Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
05d15943
D
dragonwell8_hotspot
项目概览
openanolis
/
dragonwell8_hotspot
通知
2
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_hotspot
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
“ae3cd7ab71cc8f2452134002859bb75ae71e622c”上不存在“git@gitcode.net:huhudeni/gpt-prompt.git”
提交
05d15943
编写于
4月 07, 2012
作者:
A
amurillo
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
34f34764
249ab9da
变更
55
隐藏空白更改
内联
并排
Showing
55 changed file
with
1039 addition
and
1874 deletion
+1039
-1874
agent/src/share/classes/sun/jvm/hotspot/oops/ArrayData.java
agent/src/share/classes/sun/jvm/hotspot/oops/ArrayData.java
+15
-15
agent/src/share/classes/sun/jvm/hotspot/oops/BranchData.java
agent/src/share/classes/sun/jvm/hotspot/oops/BranchData.java
+15
-15
agent/src/share/classes/sun/jvm/hotspot/oops/CounterData.java
...t/src/share/classes/sun/jvm/hotspot/oops/CounterData.java
+15
-15
agent/src/share/classes/sun/jvm/hotspot/oops/DataLayout.java
agent/src/share/classes/sun/jvm/hotspot/oops/DataLayout.java
+15
-15
agent/src/share/classes/sun/jvm/hotspot/oops/JumpData.java
agent/src/share/classes/sun/jvm/hotspot/oops/JumpData.java
+15
-15
agent/src/share/classes/sun/jvm/hotspot/oops/MultiBranchData.java
...c/share/classes/sun/jvm/hotspot/oops/MultiBranchData.java
+15
-15
agent/src/share/classes/sun/jvm/hotspot/oops/ReceiverTypeData.java
.../share/classes/sun/jvm/hotspot/oops/ReceiverTypeData.java
+15
-15
agent/src/share/classes/sun/jvm/hotspot/oops/VirtualCallData.java
...c/share/classes/sun/jvm/hotspot/oops/VirtualCallData.java
+15
-15
make/bsd/makefiles/wb.make
make/bsd/makefiles/wb.make
+1
-1
make/hotspot_version
make/hotspot_version
+1
-1
make/linux/makefiles/wb.make
make/linux/makefiles/wb.make
+1
-1
make/solaris/makefiles/wb.make
make/solaris/makefiles/wb.make
+1
-1
make/windows/create_obj_files.sh
make/windows/create_obj_files.sh
+2
-0
make/windows/makefiles/projectcreator.make
make/windows/makefiles/projectcreator.make
+1
-0
make/windows/makefiles/vm.make
make/windows/makefiles/vm.make
+7
-0
make/windows/makefiles/wb.make
make/windows/makefiles/wb.make
+1
-1
src/cpu/x86/vm/assembler_x86.cpp
src/cpu/x86/vm/assembler_x86.cpp
+4
-2
src/cpu/x86/vm/x86_64.ad
src/cpu/x86/vm/x86_64.ad
+0
-19
src/share/tools/whitebox/sun/hotspot/WhiteBox.java
src/share/tools/whitebox/sun/hotspot/WhiteBox.java
+2
-0
src/share/tools/whitebox/sun/hotspot/parser/DiagnosticCommand.java
.../tools/whitebox/sun/hotspot/parser/DiagnosticCommand.java
+43
-0
src/share/vm/classfile/classFileParser.cpp
src/share/vm/classfile/classFileParser.cpp
+7
-7
src/share/vm/classfile/classFileParser.hpp
src/share/vm/classfile/classFileParser.hpp
+4
-3
src/share/vm/classfile/symbolTable.cpp
src/share/vm/classfile/symbolTable.cpp
+65
-51
src/share/vm/classfile/symbolTable.hpp
src/share/vm/classfile/symbolTable.hpp
+24
-11
src/share/vm/classfile/vmSymbols.cpp
src/share/vm/classfile/vmSymbols.cpp
+4
-4
src/share/vm/code/nmethod.hpp
src/share/vm/code/nmethod.hpp
+1
-1
src/share/vm/gc_implementation/g1/concurrentMark.cpp
src/share/vm/gc_implementation/g1/concurrentMark.cpp
+26
-890
src/share/vm/gc_implementation/g1/concurrentMark.hpp
src/share/vm/gc_implementation/g1/concurrentMark.hpp
+2
-240
src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
+155
-68
src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
+2
-197
src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
+14
-72
src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
+9
-16
src/share/vm/gc_implementation/g1/g1OopClosures.hpp
src/share/vm/gc_implementation/g1/g1OopClosures.hpp
+5
-15
src/share/vm/gc_implementation/g1/g1_globals.hpp
src/share/vm/gc_implementation/g1/g1_globals.hpp
+0
-3
src/share/vm/gc_implementation/g1/heapRegion.hpp
src/share/vm/gc_implementation/g1/heapRegion.hpp
+3
-4
src/share/vm/memory/barrierSet.hpp
src/share/vm/memory/barrierSet.hpp
+2
-0
src/share/vm/memory/cardTableModRefBS.cpp
src/share/vm/memory/cardTableModRefBS.cpp
+5
-0
src/share/vm/memory/cardTableModRefBS.hpp
src/share/vm/memory/cardTableModRefBS.hpp
+3
-0
src/share/vm/memory/dump.cpp
src/share/vm/memory/dump.cpp
+4
-5
src/share/vm/oops/objArrayKlassKlass.cpp
src/share/vm/oops/objArrayKlassKlass.cpp
+2
-2
src/share/vm/oops/symbol.cpp
src/share/vm/oops/symbol.cpp
+15
-26
src/share/vm/oops/symbol.hpp
src/share/vm/oops/symbol.hpp
+35
-15
src/share/vm/oops/typeArrayKlass.cpp
src/share/vm/oops/typeArrayKlass.cpp
+1
-1
src/share/vm/prims/wbtestmethods/parserTests.cpp
src/share/vm/prims/wbtestmethods/parserTests.cpp
+148
-0
src/share/vm/prims/wbtestmethods/parserTests.hpp
src/share/vm/prims/wbtestmethods/parserTests.hpp
+32
-0
src/share/vm/prims/whitebox.cpp
src/share/vm/prims/whitebox.cpp
+57
-9
src/share/vm/prims/whitebox.hpp
src/share/vm/prims/whitebox.hpp
+17
-0
src/share/vm/runtime/globals.hpp
src/share/vm/runtime/globals.hpp
+1
-1
src/share/vm/services/diagnosticArgument.cpp
src/share/vm/services/diagnosticArgument.cpp
+41
-0
src/share/vm/services/diagnosticArgument.hpp
src/share/vm/services/diagnosticArgument.hpp
+9
-0
src/share/vm/services/gcNotifier.cpp
src/share/vm/services/gcNotifier.cpp
+2
-2
src/share/vm/utilities/bitMap.cpp
src/share/vm/utilities/bitMap.cpp
+1
-59
src/share/vm/utilities/bitMap.hpp
src/share/vm/utilities/bitMap.hpp
+1
-26
src/share/vm/utilities/vmError.cpp
src/share/vm/utilities/vmError.cpp
+6
-0
test/serviceability/ParserTest.java
test/serviceability/ParserTest.java
+152
-0
未找到文件。
agent/src/share/classes/sun/jvm/hotspot/oops/ArrayData.java
浏览文件 @
05d15943
/*
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*
*/
*/
...
...
agent/src/share/classes/sun/jvm/hotspot/oops/BranchData.java
浏览文件 @
05d15943
/*
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*
*/
*/
...
...
agent/src/share/classes/sun/jvm/hotspot/oops/CounterData.java
浏览文件 @
05d15943
/*
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*
*/
*/
...
...
agent/src/share/classes/sun/jvm/hotspot/oops/DataLayout.java
浏览文件 @
05d15943
/*
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*
*/
*/
...
...
agent/src/share/classes/sun/jvm/hotspot/oops/JumpData.java
浏览文件 @
05d15943
/*
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*
*/
*/
...
...
agent/src/share/classes/sun/jvm/hotspot/oops/MultiBranchData.java
浏览文件 @
05d15943
/*
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*
*/
*/
...
...
agent/src/share/classes/sun/jvm/hotspot/oops/ReceiverTypeData.java
浏览文件 @
05d15943
/*
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*
*/
*/
...
...
agent/src/share/classes/sun/jvm/hotspot/oops/VirtualCallData.java
浏览文件 @
05d15943
/*
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*
*/
*/
...
...
make/bsd/makefiles/wb.make
浏览文件 @
05d15943
...
@@ -36,7 +36,7 @@ WB_JAVA_CLASSES = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
...
@@ -36,7 +36,7 @@ WB_JAVA_CLASSES = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
$(
patsubst
%.java,%.class,
$(WB_JAVA_SRCS)
))
$(
patsubst
%.java,%.class,
$(WB_JAVA_SRCS)
))
$(WB_JAVA_CLASSDIR)/%.class
:
$(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
$(WB_JAVA_CLASSDIR)/%.class
:
$(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
$(REMOTE)
$(COMPILE.JAVAC)
-nowarn
-d
$(WB_JAVA_CLASSDIR)
$<
$(REMOTE)
$(COMPILE.JAVAC)
-
sourcepath
$(WBSRCDIR)
-
nowarn
-d
$(WB_JAVA_CLASSDIR)
$<
$(WB_JAR)
:
$(WB_JAVA_CLASSES)
$(WB_JAR)
:
$(WB_JAVA_CLASSES)
$(QUIETLY)
$(REMOTE)
$(RUN.JAR)
cf
$@
-C
$(WB_JAVA_CLASSDIR)
/ .
$(QUIETLY)
$(REMOTE)
$(RUN.JAR)
cf
$@
-C
$(WB_JAVA_CLASSDIR)
/ .
...
...
make/hotspot_version
浏览文件 @
05d15943
...
@@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2011
...
@@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2011
HS_MAJOR_VER=24
HS_MAJOR_VER=24
HS_MINOR_VER=0
HS_MINOR_VER=0
HS_BUILD_NUMBER=0
6
HS_BUILD_NUMBER=0
7
JDK_MAJOR_VER=1
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
JDK_MINOR_VER=8
...
...
make/linux/makefiles/wb.make
浏览文件 @
05d15943
...
@@ -36,7 +36,7 @@ WB_JAVA_CLASSES = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
...
@@ -36,7 +36,7 @@ WB_JAVA_CLASSES = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
$(
patsubst
%.java,%.class,
$(WB_JAVA_SRCS)
))
$(
patsubst
%.java,%.class,
$(WB_JAVA_SRCS)
))
$(WB_JAVA_CLASSDIR)/%.class
:
$(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
$(WB_JAVA_CLASSDIR)/%.class
:
$(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
$(REMOTE)
$(COMPILE.JAVAC)
-nowarn
-d
$(WB_JAVA_CLASSDIR)
$<
$(REMOTE)
$(COMPILE.JAVAC)
-
sourcepath
$(WBSRCDIR)
-
nowarn
-d
$(WB_JAVA_CLASSDIR)
$<
$(WB_JAR)
:
$(WB_JAVA_CLASSES)
$(WB_JAR)
:
$(WB_JAVA_CLASSES)
$(QUIETLY)
$(REMOTE)
$(RUN.JAR)
cf
$@
-C
$(WB_JAVA_CLASSDIR)
/ .
$(QUIETLY)
$(REMOTE)
$(RUN.JAR)
cf
$@
-C
$(WB_JAVA_CLASSDIR)
/ .
...
...
make/solaris/makefiles/wb.make
浏览文件 @
05d15943
...
@@ -36,7 +36,7 @@ WB_JAVA_CLASSES = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
...
@@ -36,7 +36,7 @@ WB_JAVA_CLASSES = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
$(
patsubst
%.java,%.class,
$(WB_JAVA_SRCS)
))
$(
patsubst
%.java,%.class,
$(WB_JAVA_SRCS)
))
$(WB_JAVA_CLASSDIR)/%.class
:
$(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
$(WB_JAVA_CLASSDIR)/%.class
:
$(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
$(REMOTE)
$(COMPILE.JAVAC)
-nowarn
-d
$(WB_JAVA_CLASSDIR)
$<
$(REMOTE)
$(COMPILE.JAVAC)
-
sourcepath
$(WBSRCDIR)
-
nowarn
-d
$(WB_JAVA_CLASSDIR)
$<
$(WB_JAR)
:
$(WB_JAVA_CLASSES)
$(WB_JAR)
:
$(WB_JAVA_CLASSES)
$(QUIETLY)
$(REMOTE)
$(RUN.JAR)
cf
$@
-C
$(WB_JAVA_CLASSDIR)
/ .
$(QUIETLY)
$(REMOTE)
$(RUN.JAR)
cf
$@
-C
$(WB_JAVA_CLASSDIR)
/ .
...
...
make/windows/create_obj_files.sh
浏览文件 @
05d15943
...
@@ -80,6 +80,8 @@ if [ -d "${ALTSRC}/share/vm/jfr" ]; then
...
@@ -80,6 +80,8 @@ if [ -d "${ALTSRC}/share/vm/jfr" ]; then
BASE_PATHS
=
"
${
BASE_PATHS
}
${
ALTSRC
}
/share/vm/jfr"
BASE_PATHS
=
"
${
BASE_PATHS
}
${
ALTSRC
}
/share/vm/jfr"
fi
fi
BASE_PATHS
=
"
${
BASE_PATHS
}
${
COMMONSRC
}
/share/vm/prims/wbtestmethods"
CORE_PATHS
=
"
${
BASE_PATHS
}
"
CORE_PATHS
=
"
${
BASE_PATHS
}
"
# shared is already in BASE_PATHS. Should add vm/memory but that one is also in BASE_PATHS.
# shared is already in BASE_PATHS. Should add vm/memory but that one is also in BASE_PATHS.
if
[
-d
"
${
ALTSRC
}
/share/vm/gc_implementation"
]
;
then
if
[
-d
"
${
ALTSRC
}
/share/vm/gc_implementation"
]
;
then
...
...
make/windows/makefiles/projectcreator.make
浏览文件 @
05d15943
...
@@ -51,6 +51,7 @@ ProjectCreatorIncludesPRIVATE=\
...
@@ -51,6 +51,7 @@ ProjectCreatorIncludesPRIVATE=\
-relativeInclude
src
\c
losed
\c
pu
\$
(
Platform_arch
)
\v
m
\
-relativeInclude
src
\c
losed
\c
pu
\$
(
Platform_arch
)
\v
m
\
-relativeInclude
src
\s
hare
\v
m
\
-relativeInclude
src
\s
hare
\v
m
\
-relativeInclude
src
\s
hare
\v
m
\p
recompiled
\
-relativeInclude
src
\s
hare
\v
m
\p
recompiled
\
-relativeInclude
src
\s
hare
\v
m
\p
rims
\w
btestmethods
\
-relativeInclude
src
\s
hare
\v
m
\p
rims
\
-relativeInclude
src
\s
hare
\v
m
\p
rims
\
-relativeInclude
src
\o
s
\w
indows
\v
m
\
-relativeInclude
src
\o
s
\w
indows
\v
m
\
-relativeInclude
src
\o
s_cpu
\w
indows_
$(Platform_arch)
\v
m
\
-relativeInclude
src
\o
s_cpu
\w
indows_
$(Platform_arch)
\v
m
\
...
...
make/windows/makefiles/vm.make
浏览文件 @
05d15943
...
@@ -172,6 +172,7 @@ VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/asm
...
@@ -172,6 +172,7 @@ VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/asm
VM_PATH
=
$(VM_PATH)
;
$(WorkSpace)
/src/share/vm/memory
VM_PATH
=
$(VM_PATH)
;
$(WorkSpace)
/src/share/vm/memory
VM_PATH
=
$(VM_PATH)
;
$(WorkSpace)
/src/share/vm/oops
VM_PATH
=
$(VM_PATH)
;
$(WorkSpace)
/src/share/vm/oops
VM_PATH
=
$(VM_PATH)
;
$(WorkSpace)
/src/share/vm/prims
VM_PATH
=
$(VM_PATH)
;
$(WorkSpace)
/src/share/vm/prims
VM_PATH
=
$(VM_PATH)
;
$(WorkSpace)
/src/share/vm/prims/wbtestmethods
VM_PATH
=
$(VM_PATH)
;
$(WorkSpace)
/src/share/vm/runtime
VM_PATH
=
$(VM_PATH)
;
$(WorkSpace)
/src/share/vm/runtime
VM_PATH
=
$(VM_PATH)
;
$(WorkSpace)
/src/share/vm/services
VM_PATH
=
$(VM_PATH)
;
$(WorkSpace)
/src/share/vm/services
VM_PATH
=
$(VM_PATH)
;
$(WorkSpace)
/src/share/vm/trace
VM_PATH
=
$(VM_PATH)
;
$(WorkSpace)
/src/share/vm/trace
...
@@ -269,6 +270,9 @@ bytecodeInterpreterWithChecks.obj: ..\generated\jvmtifiles\bytecodeInterpreterWi
...
@@ -269,6 +270,9 @@ bytecodeInterpreterWithChecks.obj: ..\generated\jvmtifiles\bytecodeInterpreterWi
{$(COMMONSRC)\share\vm\prims}.cpp.obj
::
{$(COMMONSRC)\share\vm\prims}.cpp.obj
::
$(CXX)
$(CXX_FLAGS)
$(CXX_USE_PCH)
/c
$<
$(CXX)
$(CXX_FLAGS)
$(CXX_USE_PCH)
/c
$<
{$(COMMONSRC)\share\vm\prims\wbtestmethods}.cpp.obj
::
$(CXX)
$(CXX_FLAGS)
$(CXX_USE_PCH)
/c
$<
{$(COMMONSRC)\share\vm\runtime}.cpp.obj
::
{$(COMMONSRC)\share\vm\runtime}.cpp.obj
::
$(CXX)
$(CXX_FLAGS)
$(CXX_USE_PCH)
/c
$<
$(CXX)
$(CXX_FLAGS)
$(CXX_USE_PCH)
/c
$<
...
@@ -349,6 +353,9 @@ bytecodeInterpreterWithChecks.obj: ..\generated\jvmtifiles\bytecodeInterpreterWi
...
@@ -349,6 +353,9 @@ bytecodeInterpreterWithChecks.obj: ..\generated\jvmtifiles\bytecodeInterpreterWi
{$(ALTSRC)\share\vm\prims}.cpp.obj
::
{$(ALTSRC)\share\vm\prims}.cpp.obj
::
$(CXX)
$(CXX_FLAGS)
$(CXX_USE_PCH)
/c
$<
$(CXX)
$(CXX_FLAGS)
$(CXX_USE_PCH)
/c
$<
{$(ALTSRC)\share\vm\prims\wbtestmethods}.cpp.obj
::
$(CXX)
$(CXX_FLAGS)
$(CXX_USE_PCH)
/c
$<
{$(ALTSRC)\share\vm\runtime}.cpp.obj
::
{$(ALTSRC)\share\vm\runtime}.cpp.obj
::
$(CXX)
$(CXX_FLAGS)
$(CXX_USE_PCH)
/c
$<
$(CXX)
$(CXX_FLAGS)
$(CXX_USE_PCH)
/c
$<
...
...
make/windows/makefiles/wb.make
浏览文件 @
05d15943
...
@@ -40,7 +40,7 @@ wb_java_srcs: $(WorkSpace)\src\share\tools\whitebox\sun\hotspot\*.java $(WB_CLAS
...
@@ -40,7 +40,7 @@ wb_java_srcs: $(WorkSpace)\src\share\tools\whitebox\sun\hotspot\*.java $(WB_CLAS
{$(WorkSpace)\src\share\tools\whitebox\sun\hotspot}.java.class
::
{$(WorkSpace)\src\share\tools\whitebox\sun\hotspot}.java.class
::
$(COMPILE_JAVAC)
-d
$(WB_CLASSES)
$<
$(COMPILE_JAVAC)
-
sourcepath
$(WBSRCDIR)
-
d
$(WB_CLASSES)
$<
$(WB_JAR)
:
wb_java_srcs
$(WB_JAR)
:
wb_java_srcs
$(RUN_JAR)
cf
$@
-C
$(WB_CLASSES)
.
$(RUN_JAR)
cf
$@
-C
$(WB_CLASSES)
.
...
...
src/cpu/x86/vm/assembler_x86.cpp
浏览文件 @
05d15943
...
@@ -528,10 +528,12 @@ address Assembler::locate_operand(address inst, WhichOperand which) {
...
@@ -528,10 +528,12 @@ address Assembler::locate_operand(address inst, WhichOperand which) {
if
(
which
==
end_pc_operand
)
return
ip
+
(
is_64bit
?
8
:
4
);
if
(
which
==
end_pc_operand
)
return
ip
+
(
is_64bit
?
8
:
4
);
// these asserts are somewhat nonsensical
// these asserts are somewhat nonsensical
#ifndef _LP64
#ifndef _LP64
assert
(
which
==
imm_operand
||
which
==
disp32_operand
,
""
);
assert
(
which
==
imm_operand
||
which
==
disp32_operand
,
err_msg
(
"which %d is_64_bit %d ip "
INTPTR_FORMAT
,
which
,
is_64bit
,
ip
));
#else
#else
assert
((
which
==
call32_operand
||
which
==
imm_operand
)
&&
is_64bit
||
assert
((
which
==
call32_operand
||
which
==
imm_operand
)
&&
is_64bit
||
which
==
narrow_oop_operand
&&
!
is_64bit
,
""
);
which
==
narrow_oop_operand
&&
!
is_64bit
,
err_msg
(
"which %d is_64_bit %d ip "
INTPTR_FORMAT
,
which
,
is_64bit
,
ip
));
#endif // _LP64
#endif // _LP64
return
ip
;
return
ip
;
...
...
src/cpu/x86/vm/x86_64.ad
浏览文件 @
05d15943
...
@@ -3369,15 +3369,6 @@ operand immP0()
...
@@ -3369,15 +3369,6 @@ operand immP0()
interface(CONST_INTER);
interface(CONST_INTER);
%}
%}
operand immP_poll() %{
predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
match(ConP);
// formats are generated automatically for constants and base registers
format %{ %}
interface(CONST_INTER);
%}
// Pointer Immediate
// Pointer Immediate
operand immN() %{
operand immN() %{
match(ConN);
match(ConN);
...
@@ -5726,16 +5717,6 @@ instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr)
...
@@ -5726,16 +5717,6 @@ instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr)
ins_pipe(ialu_reg);
ins_pipe(ialu_reg);
%}
%}
instruct loadConP_poll(rRegP dst, immP_poll src) %{
match(Set dst src);
format %{ "movq $dst, $src\t!ptr" %}
ins_encode %{
AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_type);
__ lea($dst$$Register, polling_page);
%}
ins_pipe(ialu_reg_fat);
%}
instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr)
instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr)
%{
%{
match(Set dst src);
match(Set dst src);
...
...
src/share/tools/whitebox/sun/hotspot/WhiteBox.java
浏览文件 @
05d15943
...
@@ -24,6 +24,7 @@
...
@@ -24,6 +24,7 @@
package
sun.hotspot
;
package
sun.hotspot
;
import
java.security.BasicPermission
;
import
java.security.BasicPermission
;
import
sun.hotspot.parser.DiagnosticCommand
;
public
class
WhiteBox
{
public
class
WhiteBox
{
...
@@ -67,4 +68,5 @@ public class WhiteBox {
...
@@ -67,4 +68,5 @@ public class WhiteBox {
public
native
boolean
g1IsHumongous
(
Object
o
);
public
native
boolean
g1IsHumongous
(
Object
o
);
public
native
long
g1NumFreeRegions
();
public
native
long
g1NumFreeRegions
();
public
native
int
g1RegionSize
();
public
native
int
g1RegionSize
();
public
native
Object
[]
parseCommandLine
(
String
commandline
,
DiagnosticCommand
[]
args
);
}
}
src/share/tools/whitebox/sun/hotspot/parser/DiagnosticCommand.java
0 → 100644
浏览文件 @
05d15943
package
sun.hotspot.parser
;
public
class
DiagnosticCommand
{
public
enum
DiagnosticArgumentType
{
JLONG
,
BOOLEAN
,
STRING
,
NANOTIME
,
STRINGARRAY
,
MEMORYSIZE
}
private
String
name
;
private
String
desc
;
private
DiagnosticArgumentType
type
;
private
boolean
mandatory
;
private
String
defaultValue
;
public
DiagnosticCommand
(
String
name
,
String
desc
,
DiagnosticArgumentType
type
,
boolean
mandatory
,
String
defaultValue
)
{
this
.
name
=
name
;
this
.
desc
=
desc
;
this
.
type
=
type
;
this
.
mandatory
=
mandatory
;
this
.
defaultValue
=
defaultValue
;
}
public
String
getName
()
{
return
name
;
}
public
String
getDesc
()
{
return
desc
;
}
public
DiagnosticArgumentType
getType
()
{
return
type
;
}
public
boolean
isMandatory
()
{
return
mandatory
;
}
public
String
getDefaultValue
()
{
return
defaultValue
;
}
}
src/share/vm/classfile/classFileParser.cpp
浏览文件 @
05d15943
/*
/*
* Copyright (c) 1997, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
2
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -81,7 +81,7 @@
...
@@ -81,7 +81,7 @@
#define JAVA_7_VERSION 51
#define JAVA_7_VERSION 51
void
ClassFileParser
::
parse_constant_pool_entries
(
constantPoolHandle
cp
,
int
length
,
TRAPS
)
{
void
ClassFileParser
::
parse_constant_pool_entries
(
Handle
class_loader
,
constantPoolHandle
cp
,
int
length
,
TRAPS
)
{
// Use a local copy of ClassFileStream. It helps the C++ compiler to optimize
// Use a local copy of ClassFileStream. It helps the C++ compiler to optimize
// this function (_current can be allocated in a register, with scalar
// this function (_current can be allocated in a register, with scalar
// replacement of aggregates). The _current pointer is copied back to
// replacement of aggregates). The _current pointer is copied back to
...
@@ -272,7 +272,7 @@ void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int len
...
@@ -272,7 +272,7 @@ void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int len
indices
[
names_count
]
=
index
;
indices
[
names_count
]
=
index
;
hashValues
[
names_count
++
]
=
hash
;
hashValues
[
names_count
++
]
=
hash
;
if
(
names_count
==
SymbolTable
::
symbol_alloc_batch_size
)
{
if
(
names_count
==
SymbolTable
::
symbol_alloc_batch_size
)
{
SymbolTable
::
new_symbols
(
cp
,
names_count
,
names
,
lengths
,
indices
,
hashValues
,
CHECK
);
SymbolTable
::
new_symbols
(
c
lass_loader
,
c
p
,
names_count
,
names
,
lengths
,
indices
,
hashValues
,
CHECK
);
names_count
=
0
;
names_count
=
0
;
}
}
}
else
{
}
else
{
...
@@ -289,7 +289,7 @@ void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int len
...
@@ -289,7 +289,7 @@ void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int len
// Allocate the remaining symbols
// Allocate the remaining symbols
if
(
names_count
>
0
)
{
if
(
names_count
>
0
)
{
SymbolTable
::
new_symbols
(
cp
,
names_count
,
names
,
lengths
,
indices
,
hashValues
,
CHECK
);
SymbolTable
::
new_symbols
(
c
lass_loader
,
c
p
,
names_count
,
names
,
lengths
,
indices
,
hashValues
,
CHECK
);
}
}
// Copy _current pointer of local copy back to stream().
// Copy _current pointer of local copy back to stream().
...
@@ -318,7 +318,7 @@ class ConstantPoolCleaner : public StackObj {
...
@@ -318,7 +318,7 @@ class ConstantPoolCleaner : public StackObj {
bool
inline
valid_cp_range
(
int
index
,
int
length
)
{
return
(
index
>
0
&&
index
<
length
);
}
bool
inline
valid_cp_range
(
int
index
,
int
length
)
{
return
(
index
>
0
&&
index
<
length
);
}
constantPoolHandle
ClassFileParser
::
parse_constant_pool
(
TRAPS
)
{
constantPoolHandle
ClassFileParser
::
parse_constant_pool
(
Handle
class_loader
,
TRAPS
)
{
ClassFileStream
*
cfs
=
stream
();
ClassFileStream
*
cfs
=
stream
();
constantPoolHandle
nullHandle
;
constantPoolHandle
nullHandle
;
...
@@ -337,7 +337,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
...
@@ -337,7 +337,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
ConstantPoolCleaner
cp_in_error
(
cp
);
// set constant pool to be cleaned up.
ConstantPoolCleaner
cp_in_error
(
cp
);
// set constant pool to be cleaned up.
// parsing constant pool entries
// parsing constant pool entries
parse_constant_pool_entries
(
cp
,
length
,
CHECK_
(
nullHandle
));
parse_constant_pool_entries
(
c
lass_loader
,
c
p
,
length
,
CHECK_
(
nullHandle
));
int
index
=
1
;
// declared outside of loops for portability
int
index
=
1
;
// declared outside of loops for portability
...
@@ -2803,7 +2803,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
...
@@ -2803,7 +2803,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
_relax_verify
=
Verifier
::
relax_verify_for
(
class_loader
());
_relax_verify
=
Verifier
::
relax_verify_for
(
class_loader
());
// Constant pool
// Constant pool
constantPoolHandle
cp
=
parse_constant_pool
(
CHECK_
(
nullHandle
));
constantPoolHandle
cp
=
parse_constant_pool
(
class_loader
,
CHECK_
(
nullHandle
));
ConstantPoolCleaner
error_handler
(
cp
);
// set constant pool to be cleaned up.
ConstantPoolCleaner
error_handler
(
cp
);
// set constant pool to be cleaned up.
int
cp_size
=
cp
->
length
();
int
cp_size
=
cp
->
length
();
...
...
src/share/vm/classfile/classFileParser.hpp
浏览文件 @
05d15943
/*
/*
* Copyright (c) 1997, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
2
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -68,9 +68,10 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
...
@@ -68,9 +68,10 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
void
set_stream
(
ClassFileStream
*
st
)
{
_stream
=
st
;
}
void
set_stream
(
ClassFileStream
*
st
)
{
_stream
=
st
;
}
// Constant pool parsing
// Constant pool parsing
void
parse_constant_pool_entries
(
constantPoolHandle
cp
,
int
length
,
TRAPS
);
void
parse_constant_pool_entries
(
Handle
class_loader
,
constantPoolHandle
cp
,
int
length
,
TRAPS
);
constantPoolHandle
parse_constant_pool
(
TRAPS
);
constantPoolHandle
parse_constant_pool
(
Handle
class_loader
,
TRAPS
);
// Interface parsing
// Interface parsing
objArrayHandle
parse_interfaces
(
constantPoolHandle
cp
,
objArrayHandle
parse_interfaces
(
constantPoolHandle
cp
,
...
...
src/share/vm/classfile/symbolTable.cpp
浏览文件 @
05d15943
/*
/*
* Copyright (c) 1997, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
2
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#include "classfile/symbolTable.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/filemap.hpp"
#include "memory/filemap.hpp"
#include "memory/gcLocker.inline.hpp"
#include "memory/gcLocker.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/oop.inline.hpp"
...
@@ -37,34 +38,35 @@
...
@@ -37,34 +38,35 @@
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
SymbolTable
*
SymbolTable
::
_the_table
=
NULL
;
SymbolTable
*
SymbolTable
::
_the_table
=
NULL
;
// Static arena for symbols that are not deallocated
Arena
*
SymbolTable
::
_arena
=
NULL
;
Symbol
*
SymbolTable
::
allocate_symbol
(
const
u1
*
name
,
int
len
,
TRAPS
)
{
Symbol
*
SymbolTable
::
allocate_symbol
(
const
u1
*
name
,
int
len
,
bool
c_heap
,
TRAPS
)
{
// Don't allow symbols to be created which cannot fit in a Symbol*.
// Don't allow symbols to be created which cannot fit in a Symbol*.
if
(
len
>
Symbol
::
max_length
())
{
if
(
len
>
Symbol
::
max_length
())
{
THROW_MSG_0
(
vmSymbols
::
java_lang_InternalError
(),
THROW_MSG_0
(
vmSymbols
::
java_lang_InternalError
(),
"name is too long to represent"
);
"name is too long to represent"
);
}
}
Symbol
*
sym
=
new
(
len
)
Symbol
(
name
,
len
);
Symbol
*
sym
;
// Allocate symbols in the C heap when dumping shared spaces in case there
// are temporary symbols we can remove.
if
(
c_heap
||
DumpSharedSpaces
)
{
// refcount starts as 1
sym
=
new
(
len
,
THREAD
)
Symbol
(
name
,
len
,
1
);
}
else
{
sym
=
new
(
len
,
arena
(),
THREAD
)
Symbol
(
name
,
len
,
-
1
);
}
assert
(
sym
!=
NULL
,
"new should call vm_exit_out_of_memory if C_HEAP is exhausted"
);
assert
(
sym
!=
NULL
,
"new should call vm_exit_out_of_memory if C_HEAP is exhausted"
);
return
sym
;
return
sym
;
}
}
bool
SymbolTable
::
allocate_symbols
(
int
names_count
,
const
u1
**
names
,
void
SymbolTable
::
initialize_symbols
(
int
arena_alloc_size
)
{
int
*
lengths
,
Symbol
**
syms
,
TRAPS
)
{
// Initialize the arena for global symbols, size passed in depends on CDS.
for
(
int
i
=
0
;
i
<
names_count
;
i
++
)
{
if
(
arena_alloc_size
==
0
)
{
if
(
lengths
[
i
]
>
Symbol
::
max_length
())
{
_arena
=
new
Arena
();
THROW_MSG_0
(
vmSymbols
::
java_lang_InternalError
(),
}
else
{
"name is too long to represent"
);
_arena
=
new
Arena
(
arena_alloc_size
);
}
}
for
(
int
i
=
0
;
i
<
names_count
;
i
++
)
{
int
len
=
lengths
[
i
];
syms
[
i
]
=
new
(
len
)
Symbol
(
names
[
i
],
len
);
assert
(
syms
[
i
]
!=
NULL
,
"new should call vm_exit_out_of_memory if "
"C_HEAP is exhausted"
);
}
}
return
true
;
}
}
// Call function for all symbols in the symbol table.
// Call function for all symbols in the symbol table.
...
@@ -83,8 +85,7 @@ int SymbolTable::symbols_removed = 0;
...
@@ -83,8 +85,7 @@ int SymbolTable::symbols_removed = 0;
int
SymbolTable
::
symbols_counted
=
0
;
int
SymbolTable
::
symbols_counted
=
0
;
// Remove unreferenced symbols from the symbol table
// Remove unreferenced symbols from the symbol table
// This is done late during GC. This doesn't use the hash table unlink because
// This is done late during GC.
// it assumes that the literals are oops.
void
SymbolTable
::
unlink
()
{
void
SymbolTable
::
unlink
()
{
int
removed
=
0
;
int
removed
=
0
;
int
total
=
0
;
int
total
=
0
;
...
@@ -156,7 +157,7 @@ Symbol* SymbolTable::lookup(const char* name, int len, TRAPS) {
...
@@ -156,7 +157,7 @@ Symbol* SymbolTable::lookup(const char* name, int len, TRAPS) {
if
(
s
!=
NULL
)
return
s
;
if
(
s
!=
NULL
)
return
s
;
// Otherwise, add to symbol to table
// Otherwise, add to symbol to table
return
the_table
()
->
basic_add
(
index
,
(
u1
*
)
name
,
len
,
hashValue
,
CHECK_NULL
);
return
the_table
()
->
basic_add
(
index
,
(
u1
*
)
name
,
len
,
hashValue
,
true
,
CHECK_NULL
);
}
}
Symbol
*
SymbolTable
::
lookup
(
const
Symbol
*
sym
,
int
begin
,
int
end
,
TRAPS
)
{
Symbol
*
SymbolTable
::
lookup
(
const
Symbol
*
sym
,
int
begin
,
int
end
,
TRAPS
)
{
...
@@ -192,7 +193,7 @@ Symbol* SymbolTable::lookup(const Symbol* sym, int begin, int end, TRAPS) {
...
@@ -192,7 +193,7 @@ Symbol* SymbolTable::lookup(const Symbol* sym, int begin, int end, TRAPS) {
// We can't include the code in No_Safepoint_Verifier because of the
// We can't include the code in No_Safepoint_Verifier because of the
// ResourceMark.
// ResourceMark.
return
the_table
()
->
basic_add
(
index
,
(
u1
*
)
buffer
,
len
,
hashValue
,
CHECK_NULL
);
return
the_table
()
->
basic_add
(
index
,
(
u1
*
)
buffer
,
len
,
hashValue
,
true
,
CHECK_NULL
);
}
}
Symbol
*
SymbolTable
::
lookup_only
(
const
char
*
name
,
int
len
,
Symbol
*
SymbolTable
::
lookup_only
(
const
char
*
name
,
int
len
,
...
@@ -256,71 +257,81 @@ Symbol* SymbolTable::lookup_only_unicode(const jchar* name, int utf16_length,
...
@@ -256,71 +257,81 @@ Symbol* SymbolTable::lookup_only_unicode(const jchar* name, int utf16_length,
}
}
}
}
void
SymbolTable
::
add
(
constantPoolHandle
cp
,
int
names_count
,
void
SymbolTable
::
add
(
Handle
class_loader
,
constantPoolHandle
cp
,
int
names_count
,
const
char
**
names
,
int
*
lengths
,
int
*
cp_indices
,
const
char
**
names
,
int
*
lengths
,
int
*
cp_indices
,
unsigned
int
*
hashValues
,
TRAPS
)
{
unsigned
int
*
hashValues
,
TRAPS
)
{
SymbolTable
*
table
=
the_table
();
SymbolTable
*
table
=
the_table
();
bool
added
=
table
->
basic_add
(
cp
,
names_count
,
names
,
lengths
,
bool
added
=
table
->
basic_add
(
c
lass_loader
,
c
p
,
names_count
,
names
,
lengths
,
cp_indices
,
hashValues
,
CHECK
);
cp_indices
,
hashValues
,
CHECK
);
if
(
!
added
)
{
if
(
!
added
)
{
// do it the hard way
// do it the hard way
for
(
int
i
=
0
;
i
<
names_count
;
i
++
)
{
for
(
int
i
=
0
;
i
<
names_count
;
i
++
)
{
int
index
=
table
->
hash_to_index
(
hashValues
[
i
]);
int
index
=
table
->
hash_to_index
(
hashValues
[
i
]);
Symbol
*
sym
=
table
->
basic_add
(
index
,
(
u1
*
)
names
[
i
],
lengths
[
i
],
bool
c_heap
=
class_loader
()
!=
NULL
;
hashValues
[
i
]
,
CHECK
);
Symbol
*
sym
=
table
->
basic_add
(
index
,
(
u1
*
)
names
[
i
],
lengths
[
i
],
hashValues
[
i
],
c_heap
,
CHECK
);
cp
->
symbol_at_put
(
cp_indices
[
i
],
sym
);
cp
->
symbol_at_put
(
cp_indices
[
i
],
sym
);
}
}
}
}
}
}
Symbol
*
SymbolTable
::
new_permanent_symbol
(
const
char
*
name
,
TRAPS
)
{
unsigned
int
hash
;
Symbol
*
result
=
SymbolTable
::
lookup_only
((
char
*
)
name
,
(
int
)
strlen
(
name
),
hash
);
if
(
result
!=
NULL
)
{
return
result
;
}
SymbolTable
*
table
=
the_table
();
int
index
=
table
->
hash_to_index
(
hash
);
return
table
->
basic_add
(
index
,
(
u1
*
)
name
,
(
int
)
strlen
(
name
),
hash
,
false
,
THREAD
);
}
Symbol
*
SymbolTable
::
basic_add
(
int
index
,
u1
*
name
,
int
len
,
Symbol
*
SymbolTable
::
basic_add
(
int
index
,
u1
*
name
,
int
len
,
unsigned
int
hashValue
,
TRAPS
)
{
unsigned
int
hashValue
,
bool
c_heap
,
TRAPS
)
{
assert
(
!
Universe
::
heap
()
->
is_in_reserved
(
name
)
||
GC_locker
::
is_active
(),
assert
(
!
Universe
::
heap
()
->
is_in_reserved
(
name
)
||
GC_locker
::
is_active
(),
"proposed name of symbol must be stable"
);
"proposed name of symbol must be stable"
);
// We assume that lookup() has been called already, that it failed,
// Grab SymbolTable_lock first.
// and symbol was not found. We create the symbol here.
Symbol
*
sym
=
allocate_symbol
(
name
,
len
,
CHECK_NULL
);
// Allocation must be done before grabbing the SymbolTable_lock lock
MutexLocker
ml
(
SymbolTable_lock
,
THREAD
);
MutexLocker
ml
(
SymbolTable_lock
,
THREAD
);
assert
(
sym
->
equals
((
char
*
)
name
,
len
),
"symbol must be properly initialized"
);
// Since look-up was done lock-free, we need to check if another
// Since look-up was done lock-free, we need to check if another
// thread beat us in the race to insert the symbol.
// thread beat us in the race to insert the symbol.
Symbol
*
test
=
lookup
(
index
,
(
char
*
)
name
,
len
,
hashValue
);
Symbol
*
test
=
lookup
(
index
,
(
char
*
)
name
,
len
,
hashValue
);
if
(
test
!=
NULL
)
{
if
(
test
!=
NULL
)
{
// A race occurred and another thread introduced the symbol, this one
// A race occurred and another thread introduced the symbol.
// will be dropped and collected.
delete
sym
;
assert
(
test
->
refcount
()
!=
0
,
"lookup should have incremented the count"
);
assert
(
test
->
refcount
()
!=
0
,
"lookup should have incremented the count"
);
return
test
;
return
test
;
}
}
// Create a new symbol.
Symbol
*
sym
=
allocate_symbol
(
name
,
len
,
c_heap
,
CHECK_NULL
);
assert
(
sym
->
equals
((
char
*
)
name
,
len
),
"symbol must be properly initialized"
);
HashtableEntry
<
Symbol
*>*
entry
=
new_entry
(
hashValue
,
sym
);
HashtableEntry
<
Symbol
*>*
entry
=
new_entry
(
hashValue
,
sym
);
sym
->
increment_refcount
();
add_entry
(
index
,
entry
);
add_entry
(
index
,
entry
);
return
sym
;
return
sym
;
}
}
bool
SymbolTable
::
basic_add
(
constantPoolHandle
cp
,
int
names_count
,
// This version of basic_add adds symbols in batch from the constant pool
// parsing.
bool
SymbolTable
::
basic_add
(
Handle
class_loader
,
constantPoolHandle
cp
,
int
names_count
,
const
char
**
names
,
int
*
lengths
,
const
char
**
names
,
int
*
lengths
,
int
*
cp_indices
,
unsigned
int
*
hashValues
,
int
*
cp_indices
,
unsigned
int
*
hashValues
,
TRAPS
)
{
TRAPS
)
{
Symbol
*
syms
[
symbol_alloc_batch_size
];
bool
allocated
=
allocate_symbols
(
names_count
,
(
const
u1
**
)
names
,
lengths
,
// Check symbol names are not too long. If any are too long, don't add any.
syms
,
CHECK_false
);
for
(
int
i
=
0
;
i
<
names_count
;
i
++
)
{
if
(
!
allocated
)
{
if
(
lengths
[
i
]
>
Symbol
::
max_length
())
{
return
false
;
THROW_MSG_0
(
vmSymbols
::
java_lang_InternalError
(),
"name is too long to represent"
);
}
}
}
//
Allocation must be done before grabbing the SymbolTable_lock lock
//
Hold SymbolTable_lock through the symbol creation
MutexLocker
ml
(
SymbolTable_lock
,
THREAD
);
MutexLocker
ml
(
SymbolTable_lock
,
THREAD
);
for
(
int
i
=
0
;
i
<
names_count
;
i
++
)
{
for
(
int
i
=
0
;
i
<
names_count
;
i
++
)
{
assert
(
syms
[
i
]
->
equals
(
names
[
i
],
lengths
[
i
]),
"symbol must be properly initialized"
);
// Since look-up was done lock-free, we need to check if another
// Since look-up was done lock-free, we need to check if another
// thread beat us in the race to insert the symbol.
// thread beat us in the race to insert the symbol.
int
index
=
hash_to_index
(
hashValues
[
i
]);
int
index
=
hash_to_index
(
hashValues
[
i
]);
...
@@ -330,16 +341,17 @@ bool SymbolTable::basic_add(constantPoolHandle cp, int names_count,
...
@@ -330,16 +341,17 @@ bool SymbolTable::basic_add(constantPoolHandle cp, int names_count,
// will be dropped and collected. Use test instead.
// will be dropped and collected. Use test instead.
cp
->
symbol_at_put
(
cp_indices
[
i
],
test
);
cp
->
symbol_at_put
(
cp_indices
[
i
],
test
);
assert
(
test
->
refcount
()
!=
0
,
"lookup should have incremented the count"
);
assert
(
test
->
refcount
()
!=
0
,
"lookup should have incremented the count"
);
delete
syms
[
i
];
}
else
{
}
else
{
Symbol
*
sym
=
syms
[
i
];
// Create a new symbol. The null class loader is never unloaded so these
// are allocated specially in a permanent arena.
bool
c_heap
=
class_loader
()
!=
NULL
;
Symbol
*
sym
=
allocate_symbol
((
const
u1
*
)
names
[
i
],
lengths
[
i
],
c_heap
,
CHECK_
(
false
));
assert
(
sym
->
equals
(
names
[
i
],
lengths
[
i
]),
"symbol must be properly initialized"
);
// why wouldn't it be???
HashtableEntry
<
Symbol
*>*
entry
=
new_entry
(
hashValues
[
i
],
sym
);
HashtableEntry
<
Symbol
*>*
entry
=
new_entry
(
hashValues
[
i
],
sym
);
sym
->
increment_refcount
();
// increment refcount in external hashtable
add_entry
(
index
,
entry
);
add_entry
(
index
,
entry
);
cp
->
symbol_at_put
(
cp_indices
[
i
],
sym
);
cp
->
symbol_at_put
(
cp_indices
[
i
],
sym
);
}
}
}
}
return
true
;
return
true
;
}
}
...
@@ -406,6 +418,8 @@ void SymbolTable::print_histogram() {
...
@@ -406,6 +418,8 @@ void SymbolTable::print_histogram() {
((
float
)
symbols_removed
/
(
float
)
symbols_counted
)
*
100
);
((
float
)
symbols_removed
/
(
float
)
symbols_counted
)
*
100
);
}
}
tty
->
print_cr
(
"Reference counts %5d"
,
Symbol
::
_total_count
);
tty
->
print_cr
(
"Reference counts %5d"
,
Symbol
::
_total_count
);
tty
->
print_cr
(
"Symbol arena size %5d used %5d"
,
arena
()
->
size_in_bytes
(),
arena
()
->
used
());
tty
->
print_cr
(
"Histogram of symbol length:"
);
tty
->
print_cr
(
"Histogram of symbol length:"
);
tty
->
print_cr
(
"%8s %5d"
,
"Total "
,
total
);
tty
->
print_cr
(
"%8s %5d"
,
"Total "
,
total
);
tty
->
print_cr
(
"%8s %5d"
,
"Maximum"
,
max_symbols
);
tty
->
print_cr
(
"%8s %5d"
,
"Maximum"
,
max_symbols
);
...
...
src/share/vm/classfile/symbolTable.hpp
浏览文件 @
05d15943
/*
/*
* Copyright (c) 1997, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
2
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -82,24 +82,24 @@ private:
...
@@ -82,24 +82,24 @@ private:
static
int
symbols_removed
;
static
int
symbols_removed
;
static
int
symbols_counted
;
static
int
symbols_counted
;
Symbol
*
allocate_symbol
(
const
u1
*
name
,
int
len
,
TRAPS
);
// Assumes no characters larger than 0x7F
Symbol
*
allocate_symbol
(
const
u1
*
name
,
int
len
,
bool
c_heap
,
TRAPS
);
// Assumes no characters larger than 0x7F
bool
allocate_symbols
(
int
names_count
,
const
u1
**
names
,
int
*
lengths
,
Symbol
**
syms
,
TRAPS
);
// Adding elements
// Adding elements
Symbol
*
basic_add
(
int
index
,
u1
*
name
,
int
len
,
Symbol
*
basic_add
(
int
index
,
u1
*
name
,
int
len
,
unsigned
int
hashValue
,
unsigned
int
hashValue
,
TRAPS
);
bool
c_heap
,
TRAPS
);
bool
basic_add
(
constantPoolHandle
cp
,
int
names_count
,
bool
basic_add
(
Handle
class_loader
,
constantPoolHandle
cp
,
int
names_count
,
const
char
**
names
,
int
*
lengths
,
int
*
cp_indices
,
const
char
**
names
,
int
*
lengths
,
int
*
cp_indices
,
unsigned
int
*
hashValues
,
TRAPS
);
unsigned
int
*
hashValues
,
TRAPS
);
static
void
new_symbols
(
constantPoolHandle
cp
,
int
names_count
,
static
void
new_symbols
(
Handle
class_loader
,
constantPoolHandle
cp
,
int
names_count
,
const
char
**
name
,
int
*
lengths
,
const
char
**
name
,
int
*
lengths
,
int
*
cp_indices
,
unsigned
int
*
hashValues
,
int
*
cp_indices
,
unsigned
int
*
hashValues
,
TRAPS
)
{
TRAPS
)
{
add
(
cp
,
names_count
,
name
,
lengths
,
cp_indices
,
hashValues
,
THREAD
);
add
(
c
lass_loader
,
c
p
,
names_count
,
name
,
lengths
,
cp_indices
,
hashValues
,
THREAD
);
}
}
// Table size
// Table size
enum
{
enum
{
symbol_table_size
=
20011
symbol_table_size
=
20011
...
@@ -114,10 +114,16 @@ private:
...
@@ -114,10 +114,16 @@ private:
:
Hashtable
<
Symbol
*>
(
symbol_table_size
,
sizeof
(
HashtableEntry
<
Symbol
*>
),
t
,
:
Hashtable
<
Symbol
*>
(
symbol_table_size
,
sizeof
(
HashtableEntry
<
Symbol
*>
),
t
,
number_of_entries
)
{}
number_of_entries
)
{}
// Arena for permanent symbols (null class loader) that are never unloaded
static
Arena
*
_arena
;
static
Arena
*
arena
()
{
return
_arena
;
}
// called for statistics
static
void
initialize_symbols
(
int
arena_alloc_size
=
0
);
public:
public:
enum
{
enum
{
symbol_alloc_batch_size
=
8
symbol_alloc_batch_size
=
8
,
// Pick initial size based on java -version size measurements
symbol_alloc_arena_size
=
360
*
K
};
};
// The symbol table
// The symbol table
...
@@ -126,6 +132,7 @@ public:
...
@@ -126,6 +132,7 @@ public:
static
void
create_table
()
{
static
void
create_table
()
{
assert
(
_the_table
==
NULL
,
"One symbol table allowed."
);
assert
(
_the_table
==
NULL
,
"One symbol table allowed."
);
_the_table
=
new
SymbolTable
();
_the_table
=
new
SymbolTable
();
initialize_symbols
(
symbol_alloc_arena_size
);
}
}
static
void
create_table
(
HashtableBucket
*
t
,
int
length
,
static
void
create_table
(
HashtableBucket
*
t
,
int
length
,
...
@@ -134,6 +141,9 @@ public:
...
@@ -134,6 +141,9 @@ public:
assert
(
length
==
symbol_table_size
*
sizeof
(
HashtableBucket
),
assert
(
length
==
symbol_table_size
*
sizeof
(
HashtableBucket
),
"bad shared symbol size."
);
"bad shared symbol size."
);
_the_table
=
new
SymbolTable
(
t
,
number_of_entries
);
_the_table
=
new
SymbolTable
(
t
,
number_of_entries
);
// if CDS give symbol table a default arena size since most symbols
// are already allocated in the shared misc section.
initialize_symbols
();
}
}
static
Symbol
*
lookup
(
const
char
*
name
,
int
len
,
TRAPS
);
static
Symbol
*
lookup
(
const
char
*
name
,
int
len
,
TRAPS
);
...
@@ -151,7 +161,7 @@ public:
...
@@ -151,7 +161,7 @@ public:
static
Symbol
*
lookup_unicode
(
const
jchar
*
name
,
int
len
,
TRAPS
);
static
Symbol
*
lookup_unicode
(
const
jchar
*
name
,
int
len
,
TRAPS
);
static
Symbol
*
lookup_only_unicode
(
const
jchar
*
name
,
int
len
,
unsigned
int
&
hash
);
static
Symbol
*
lookup_only_unicode
(
const
jchar
*
name
,
int
len
,
unsigned
int
&
hash
);
static
void
add
(
constantPoolHandle
cp
,
int
names_count
,
static
void
add
(
Handle
class_loader
,
constantPoolHandle
cp
,
int
names_count
,
const
char
**
names
,
int
*
lengths
,
int
*
cp_indices
,
const
char
**
names
,
int
*
lengths
,
int
*
cp_indices
,
unsigned
int
*
hashValues
,
TRAPS
);
unsigned
int
*
hashValues
,
TRAPS
);
...
@@ -174,6 +184,9 @@ public:
...
@@ -174,6 +184,9 @@ public:
return
lookup
(
sym
,
begin
,
end
,
THREAD
);
return
lookup
(
sym
,
begin
,
end
,
THREAD
);
}
}
// Create a symbol in the arena for symbols that are not deleted
static
Symbol
*
new_permanent_symbol
(
const
char
*
name
,
TRAPS
);
// Symbol lookup
// Symbol lookup
static
Symbol
*
lookup
(
int
index
,
const
char
*
name
,
int
len
,
TRAPS
);
static
Symbol
*
lookup
(
int
index
,
const
char
*
name
,
int
len
,
TRAPS
);
...
...
src/share/vm/classfile/vmSymbols.cpp
浏览文件 @
05d15943
/*
/*
* Copyright (c) 1997, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
2
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -79,7 +79,7 @@ void vmSymbols::initialize(TRAPS) {
...
@@ -79,7 +79,7 @@ void vmSymbols::initialize(TRAPS) {
if
(
!
UseSharedSpaces
)
{
if
(
!
UseSharedSpaces
)
{
const
char
*
string
=
&
vm_symbol_bodies
[
0
];
const
char
*
string
=
&
vm_symbol_bodies
[
0
];
for
(
int
index
=
(
int
)
FIRST_SID
;
index
<
(
int
)
SID_LIMIT
;
index
++
)
{
for
(
int
index
=
(
int
)
FIRST_SID
;
index
<
(
int
)
SID_LIMIT
;
index
++
)
{
Symbol
*
sym
=
SymbolTable
::
new_symbol
(
string
,
CHECK
);
Symbol
*
sym
=
SymbolTable
::
new_
permanent_
symbol
(
string
,
CHECK
);
_symbols
[
index
]
=
sym
;
_symbols
[
index
]
=
sym
;
string
+=
strlen
(
string
);
// skip string body
string
+=
strlen
(
string
);
// skip string body
string
+=
1
;
// skip trailing null
string
+=
1
;
// skip trailing null
...
@@ -128,7 +128,7 @@ void vmSymbols::initialize(TRAPS) {
...
@@ -128,7 +128,7 @@ void vmSymbols::initialize(TRAPS) {
// Spot-check correspondence between strings, symbols, and enums:
// Spot-check correspondence between strings, symbols, and enums:
assert
(
_symbols
[
NO_SID
]
==
NULL
,
"must be"
);
assert
(
_symbols
[
NO_SID
]
==
NULL
,
"must be"
);
const
char
*
str
=
"java/lang/Object"
;
const
char
*
str
=
"java/lang/Object"
;
TempNewSymbol
jlo
=
SymbolTable
::
new_symbol
(
str
,
CHECK
);
TempNewSymbol
jlo
=
SymbolTable
::
new_
permanent_
symbol
(
str
,
CHECK
);
assert
(
strncmp
(
str
,
(
char
*
)
jlo
->
base
(),
jlo
->
utf8_length
())
==
0
,
""
);
assert
(
strncmp
(
str
,
(
char
*
)
jlo
->
base
(),
jlo
->
utf8_length
())
==
0
,
""
);
assert
(
jlo
==
java_lang_Object
(),
""
);
assert
(
jlo
==
java_lang_Object
(),
""
);
SID
sid
=
VM_SYMBOL_ENUM_NAME
(
java_lang_Object
);
SID
sid
=
VM_SYMBOL_ENUM_NAME
(
java_lang_Object
);
...
@@ -147,7 +147,7 @@ void vmSymbols::initialize(TRAPS) {
...
@@ -147,7 +147,7 @@ void vmSymbols::initialize(TRAPS) {
// The string "format" happens (at the moment) not to be a vmSymbol,
// The string "format" happens (at the moment) not to be a vmSymbol,
// though it is a method name in java.lang.String.
// though it is a method name in java.lang.String.
str
=
"format"
;
str
=
"format"
;
TempNewSymbol
fmt
=
SymbolTable
::
new_symbol
(
str
,
CHECK
);
TempNewSymbol
fmt
=
SymbolTable
::
new_
permanent_
symbol
(
str
,
CHECK
);
sid
=
find_sid
(
fmt
);
sid
=
find_sid
(
fmt
);
assert
(
sid
==
NO_SID
,
"symbol index works (negative test)"
);
assert
(
sid
==
NO_SID
,
"symbol index works (negative test)"
);
}
}
...
...
src/share/vm/code/nmethod.hpp
浏览文件 @
05d15943
...
@@ -553,7 +553,7 @@ public:
...
@@ -553,7 +553,7 @@ public:
static
void
oops_do_marking_prologue
();
static
void
oops_do_marking_prologue
();
static
void
oops_do_marking_epilogue
();
static
void
oops_do_marking_epilogue
();
static
bool
oops_do_marking_is_active
()
{
return
_oops_do_mark_nmethods
!=
NULL
;
}
static
bool
oops_do_marking_is_active
()
{
return
_oops_do_mark_nmethods
!=
NULL
;
}
DEBUG_ONLY
(
bool
test_oops_do_mark
()
{
return
_oops_do_mark_link
!=
NULL
;
})
bool
test_oops_do_mark
()
{
return
_oops_do_mark_link
!=
NULL
;
}
// ScopeDesc for an instruction
// ScopeDesc for an instruction
ScopeDesc
*
scope_desc_at
(
address
pc
);
ScopeDesc
*
scope_desc_at
(
address
pc
);
...
...
src/share/vm/gc_implementation/g1/concurrentMark.cpp
浏览文件 @
05d15943
...
@@ -103,16 +103,6 @@ int CMBitMapRO::heapWordDiffToOffsetDiff(size_t diff) const {
...
@@ -103,16 +103,6 @@ int CMBitMapRO::heapWordDiffToOffsetDiff(size_t diff) const {
return
(
int
)
(
diff
>>
_shifter
);
return
(
int
)
(
diff
>>
_shifter
);
}
}
void
CMBitMapRO
::
mostly_disjoint_range_union
(
BitMap
*
from_bitmap
,
size_t
from_start_index
,
HeapWord
*
to_start_word
,
size_t
word_num
)
{
_bm
.
mostly_disjoint_range_union
(
from_bitmap
,
from_start_index
,
heapWordToOffset
(
to_start_word
),
word_num
);
}
#ifndef PRODUCT
#ifndef PRODUCT
bool
CMBitMapRO
::
covers
(
ReservedSpace
rs
)
const
{
bool
CMBitMapRO
::
covers
(
ReservedSpace
rs
)
const
{
// assert(_bm.map() == _virtual_space.low(), "map inconsistency");
// assert(_bm.map() == _virtual_space.low(), "map inconsistency");
...
@@ -271,140 +261,6 @@ bool CMMarkStack::par_pop_arr(oop* ptr_arr, int max, int* n) {
...
@@ -271,140 +261,6 @@ bool CMMarkStack::par_pop_arr(oop* ptr_arr, int max, int* n) {
}
}
}
}
CMRegionStack
::
CMRegionStack
()
:
_base
(
NULL
)
{}
void
CMRegionStack
::
allocate
(
size_t
size
)
{
_base
=
NEW_C_HEAP_ARRAY
(
MemRegion
,
size
);
if
(
_base
==
NULL
)
{
vm_exit_during_initialization
(
"Failed to allocate CM region mark stack"
);
}
_index
=
0
;
_capacity
=
(
jint
)
size
;
}
CMRegionStack
::~
CMRegionStack
()
{
if
(
_base
!=
NULL
)
{
FREE_C_HEAP_ARRAY
(
oop
,
_base
);
}
}
void
CMRegionStack
::
push_lock_free
(
MemRegion
mr
)
{
guarantee
(
false
,
"push_lock_free(): don't call this any more"
);
assert
(
mr
.
word_size
()
>
0
,
"Precondition"
);
while
(
true
)
{
jint
index
=
_index
;
if
(
index
>=
_capacity
)
{
_overflow
=
true
;
return
;
}
// Otherwise...
jint
next_index
=
index
+
1
;
jint
res
=
Atomic
::
cmpxchg
(
next_index
,
&
_index
,
index
);
if
(
res
==
index
)
{
_base
[
index
]
=
mr
;
return
;
}
// Otherwise, we need to try again.
}
}
// Lock-free pop of the region stack. Called during the concurrent
// marking / remark phases. Should only be called in tandem with
// other lock-free pops.
MemRegion
CMRegionStack
::
pop_lock_free
()
{
guarantee
(
false
,
"pop_lock_free(): don't call this any more"
);
while
(
true
)
{
jint
index
=
_index
;
if
(
index
==
0
)
{
return
MemRegion
();
}
// Otherwise...
jint
next_index
=
index
-
1
;
jint
res
=
Atomic
::
cmpxchg
(
next_index
,
&
_index
,
index
);
if
(
res
==
index
)
{
MemRegion
mr
=
_base
[
next_index
];
if
(
mr
.
start
()
!=
NULL
)
{
assert
(
mr
.
end
()
!=
NULL
,
"invariant"
);
assert
(
mr
.
word_size
()
>
0
,
"invariant"
);
return
mr
;
}
else
{
// that entry was invalidated... let's skip it
assert
(
mr
.
end
()
==
NULL
,
"invariant"
);
}
}
// Otherwise, we need to try again.
}
}
#if 0
// The routines that manipulate the region stack with a lock are
// not currently used. They should be retained, however, as a
// diagnostic aid.
void CMRegionStack::push_with_lock(MemRegion mr) {
assert(mr.word_size() > 0, "Precondition");
MutexLockerEx x(CMRegionStack_lock, Mutex::_no_safepoint_check_flag);
if (isFull()) {
_overflow = true;
return;
}
_base[_index] = mr;
_index += 1;
}
MemRegion CMRegionStack::pop_with_lock() {
MutexLockerEx x(CMRegionStack_lock, Mutex::_no_safepoint_check_flag);
while (true) {
if (_index == 0) {
return MemRegion();
}
_index -= 1;
MemRegion mr = _base[_index];
if (mr.start() != NULL) {
assert(mr.end() != NULL, "invariant");
assert(mr.word_size() > 0, "invariant");
return mr;
} else {
// that entry was invalidated... let's skip it
assert(mr.end() == NULL, "invariant");
}
}
}
#endif
bool
CMRegionStack
::
invalidate_entries_into_cset
()
{
guarantee
(
false
,
"invalidate_entries_into_cset(): don't call this any more"
);
bool
result
=
false
;
G1CollectedHeap
*
g1h
=
G1CollectedHeap
::
heap
();
for
(
int
i
=
0
;
i
<
_oops_do_bound
;
++
i
)
{
MemRegion
mr
=
_base
[
i
];
if
(
mr
.
start
()
!=
NULL
)
{
assert
(
mr
.
end
()
!=
NULL
,
"invariant"
);
assert
(
mr
.
word_size
()
>
0
,
"invariant"
);
HeapRegion
*
hr
=
g1h
->
heap_region_containing
(
mr
.
start
());
assert
(
hr
!=
NULL
,
"invariant"
);
if
(
hr
->
in_collection_set
())
{
// The region points into the collection set
_base
[
i
]
=
MemRegion
();
result
=
true
;
}
}
else
{
// that entry was invalidated... let's skip it
assert
(
mr
.
end
()
==
NULL
,
"invariant"
);
}
}
return
result
;
}
template
<
class
OopClosureClass
>
template
<
class
OopClosureClass
>
bool
CMMarkStack
::
drain
(
OopClosureClass
*
cl
,
CMBitMap
*
bm
,
bool
yield_after
)
{
bool
CMMarkStack
::
drain
(
OopClosureClass
*
cl
,
CMBitMap
*
bm
,
bool
yield_after
)
{
assert
(
!
_drain_in_progress
||
!
_drain_in_progress_yields
||
yield_after
assert
(
!
_drain_in_progress
||
!
_drain_in_progress_yields
||
yield_after
...
@@ -565,10 +421,8 @@ ConcurrentMark::ConcurrentMark(ReservedSpace rs,
...
@@ -565,10 +421,8 @@ ConcurrentMark::ConcurrentMark(ReservedSpace rs,
_prevMarkBitMap
(
&
_markBitMap1
),
_prevMarkBitMap
(
&
_markBitMap1
),
_nextMarkBitMap
(
&
_markBitMap2
),
_nextMarkBitMap
(
&
_markBitMap2
),
_at_least_one_mark_complete
(
false
),
_markStack
(
this
),
_markStack
(
this
),
_regionStack
(),
// _finger set in set_non_marking_state
// _finger set in set_non_marking_state
_max_task_num
(
MAX2
((
uint
)
ParallelGCThreads
,
1U
)),
_max_task_num
(
MAX2
((
uint
)
ParallelGCThreads
,
1U
)),
...
@@ -582,7 +436,6 @@ ConcurrentMark::ConcurrentMark(ReservedSpace rs,
...
@@ -582,7 +436,6 @@ ConcurrentMark::ConcurrentMark(ReservedSpace rs,
_has_aborted
(
false
),
_has_aborted
(
false
),
_restart_for_overflow
(
false
),
_restart_for_overflow
(
false
),
_concurrent_marking_in_progress
(
false
),
_concurrent_marking_in_progress
(
false
),
_should_gray_objects
(
false
),
// _verbose_level set below
// _verbose_level set below
...
@@ -611,7 +464,6 @@ ConcurrentMark::ConcurrentMark(ReservedSpace rs,
...
@@ -611,7 +464,6 @@ ConcurrentMark::ConcurrentMark(ReservedSpace rs,
}
}
_markStack
.
allocate
(
MarkStackSize
);
_markStack
.
allocate
(
MarkStackSize
);
_regionStack
.
allocate
(
G1MarkRegionStackSize
);
// Create & start a ConcurrentMark thread.
// Create & start a ConcurrentMark thread.
_cmThread
=
new
ConcurrentMarkThread
(
this
);
_cmThread
=
new
ConcurrentMarkThread
(
this
);
...
@@ -744,15 +596,7 @@ ConcurrentMark::ConcurrentMark(ReservedSpace rs,
...
@@ -744,15 +596,7 @@ ConcurrentMark::ConcurrentMark(ReservedSpace rs,
void
ConcurrentMark
::
update_g1_committed
(
bool
force
)
{
void
ConcurrentMark
::
update_g1_committed
(
bool
force
)
{
// If concurrent marking is not in progress, then we do not need to
// If concurrent marking is not in progress, then we do not need to
// update _heap_end. This has a subtle and important
// update _heap_end.
// side-effect. Imagine that two evacuation pauses happen between
// marking completion and remark. The first one can grow the
// heap (hence now the finger is below the heap end). Then, the
// second one could unnecessarily push regions on the region
// stack. This causes the invariant that the region stack is empty
// at the beginning of remark to be false. By ensuring that we do
// not observe heap expansions after marking is complete, then we do
// not have this problem.
if
(
!
concurrent_marking_in_progress
()
&&
!
force
)
return
;
if
(
!
concurrent_marking_in_progress
()
&&
!
force
)
return
;
MemRegion
committed
=
_g1h
->
g1_committed
();
MemRegion
committed
=
_g1h
->
g1_committed
();
...
@@ -1058,86 +902,6 @@ bool ForceOverflowSettings::should_force() {
...
@@ -1058,86 +902,6 @@ bool ForceOverflowSettings::should_force() {
}
}
#endif // !PRODUCT
#endif // !PRODUCT
void
ConcurrentMark
::
grayRegionIfNecessary
(
MemRegion
mr
)
{
guarantee
(
false
,
"grayRegionIfNecessary(): don't call this any more"
);
// The objects on the region have already been marked "in bulk" by
// the caller. We only need to decide whether to push the region on
// the region stack or not.
if
(
!
concurrent_marking_in_progress
()
||
!
_should_gray_objects
)
{
// We're done with marking and waiting for remark. We do not need to
// push anything else on the region stack.
return
;
}
HeapWord
*
finger
=
_finger
;
if
(
verbose_low
())
{
gclog_or_tty
->
print_cr
(
"[global] attempting to push "
"region ["
PTR_FORMAT
", "
PTR_FORMAT
"), finger is at "
PTR_FORMAT
,
mr
.
start
(),
mr
.
end
(),
finger
);
}
if
(
mr
.
start
()
<
finger
)
{
// The finger is always heap region aligned and it is not possible
// for mr to span heap regions.
assert
(
mr
.
end
()
<=
finger
,
"invariant"
);
// Separated the asserts so that we know which one fires.
assert
(
mr
.
start
()
<=
mr
.
end
(),
"region boundaries should fall within the committed space"
);
assert
(
_heap_start
<=
mr
.
start
(),
"region boundaries should fall within the committed space"
);
assert
(
mr
.
end
()
<=
_heap_end
,
"region boundaries should fall within the committed space"
);
if
(
verbose_low
())
{
gclog_or_tty
->
print_cr
(
"[global] region ["
PTR_FORMAT
", "
PTR_FORMAT
") "
"below the finger, pushing it"
,
mr
.
start
(),
mr
.
end
());
}
if
(
!
region_stack_push_lock_free
(
mr
))
{
if
(
verbose_low
())
{
gclog_or_tty
->
print_cr
(
"[global] region stack has overflown."
);
}
}
}
}
void
ConcurrentMark
::
markAndGrayObjectIfNecessary
(
oop
p
)
{
guarantee
(
false
,
"markAndGrayObjectIfNecessary(): don't call this any more"
);
// The object is not marked by the caller. We need to at least mark
// it and maybe push in on the stack.
HeapWord
*
addr
=
(
HeapWord
*
)
p
;
if
(
!
_nextMarkBitMap
->
isMarked
(
addr
))
{
// We definitely need to mark it, irrespective whether we bail out
// because we're done with marking.
if
(
_nextMarkBitMap
->
parMark
(
addr
))
{
if
(
!
concurrent_marking_in_progress
()
||
!
_should_gray_objects
)
{
// If we're done with concurrent marking and we're waiting for
// remark, then we're not pushing anything on the stack.
return
;
}
// No OrderAccess:store_load() is needed. It is implicit in the
// CAS done in parMark(addr) above
HeapWord
*
finger
=
_finger
;
if
(
addr
<
finger
)
{
if
(
!
mark_stack_push
(
oop
(
addr
)))
{
if
(
verbose_low
())
{
gclog_or_tty
->
print_cr
(
"[global] global stack overflow "
"during parMark"
);
}
}
}
}
}
}
class
CMConcurrentMarkingTask
:
public
AbstractGangTask
{
class
CMConcurrentMarkingTask
:
public
AbstractGangTask
{
private:
private:
ConcurrentMark
*
_cm
;
ConcurrentMark
*
_cm
;
...
@@ -2255,7 +2019,6 @@ void ConcurrentMark::cleanup() {
...
@@ -2255,7 +2019,6 @@ void ConcurrentMark::cleanup() {
g1p
->
set_known_garbage_bytes
(
known_garbage_bytes
);
g1p
->
set_known_garbage_bytes
(
known_garbage_bytes
);
size_t
start_used_bytes
=
g1h
->
used
();
size_t
start_used_bytes
=
g1h
->
used
();
_at_least_one_mark_complete
=
true
;
g1h
->
set_marking_complete
();
g1h
->
set_marking_complete
();
ergo_verbose4
(
ErgoConcCycles
,
ergo_verbose4
(
ErgoConcCycles
,
...
@@ -3066,89 +2829,6 @@ void ConcurrentMark::print_reachable(const char* str,
...
@@ -3066,89 +2829,6 @@ void ConcurrentMark::print_reachable(const char* str,
#endif // PRODUCT
#endif // PRODUCT
// This note is for drainAllSATBBuffers and the code in between.
// In the future we could reuse a task to do this work during an
// evacuation pause (since now tasks are not active and can be claimed
// during an evacuation pause). This was a late change to the code and
// is currently not being taken advantage of.
void
ConcurrentMark
::
deal_with_reference
(
oop
obj
)
{
if
(
verbose_high
())
{
gclog_or_tty
->
print_cr
(
"[global] we're dealing with reference "
PTR_FORMAT
,
(
void
*
)
obj
);
}
HeapWord
*
objAddr
=
(
HeapWord
*
)
obj
;
assert
(
obj
->
is_oop_or_null
(
true
/* ignore mark word */
),
"Error"
);
if
(
_g1h
->
is_in_g1_reserved
(
objAddr
))
{
assert
(
obj
!=
NULL
,
"null check is implicit"
);
if
(
!
_nextMarkBitMap
->
isMarked
(
objAddr
))
{
// Only get the containing region if the object is not marked on the
// bitmap (otherwise, it's a waste of time since we won't do
// anything with it).
HeapRegion
*
hr
=
_g1h
->
heap_region_containing_raw
(
obj
);
if
(
!
hr
->
obj_allocated_since_next_marking
(
obj
))
{
if
(
verbose_high
())
{
gclog_or_tty
->
print_cr
(
"[global] "
PTR_FORMAT
" is not considered "
"marked"
,
(
void
*
)
obj
);
}
// we need to mark it first
if
(
_nextMarkBitMap
->
parMark
(
objAddr
))
{
// No OrderAccess:store_load() is needed. It is implicit in the
// CAS done in parMark(objAddr) above
HeapWord
*
finger
=
_finger
;
if
(
objAddr
<
finger
)
{
if
(
verbose_high
())
{
gclog_or_tty
->
print_cr
(
"[global] below the global finger "
"("
PTR_FORMAT
"), pushing it"
,
finger
);
}
if
(
!
mark_stack_push
(
obj
))
{
if
(
verbose_low
())
{
gclog_or_tty
->
print_cr
(
"[global] global stack overflow during "
"deal_with_reference"
);
}
}
}
}
}
}
}
}
class
CMGlobalObjectClosure
:
public
ObjectClosure
{
private:
ConcurrentMark
*
_cm
;
public:
void
do_object
(
oop
obj
)
{
_cm
->
deal_with_reference
(
obj
);
}
CMGlobalObjectClosure
(
ConcurrentMark
*
cm
)
:
_cm
(
cm
)
{
}
};
void
ConcurrentMark
::
drainAllSATBBuffers
()
{
guarantee
(
false
,
"drainAllSATBBuffers(): don't call this any more"
);
CMGlobalObjectClosure
oc
(
this
);
SATBMarkQueueSet
&
satb_mq_set
=
JavaThread
::
satb_mark_queue_set
();
satb_mq_set
.
set_closure
(
&
oc
);
while
(
satb_mq_set
.
apply_closure_to_completed_buffer
())
{
if
(
verbose_medium
())
{
gclog_or_tty
->
print_cr
(
"[global] processed an SATB buffer"
);
}
}
// no need to check whether we should do this, as this is only
// called during an evacuation pause
satb_mq_set
.
iterate_closure_all_threads
();
satb_mq_set
.
set_closure
(
NULL
);
assert
(
satb_mq_set
.
completed_buffers_num
()
==
0
,
"invariant"
);
}
void
ConcurrentMark
::
clearRangePrevBitmap
(
MemRegion
mr
)
{
void
ConcurrentMark
::
clearRangePrevBitmap
(
MemRegion
mr
)
{
// Note we are overriding the read-only view of the prev map here, via
// Note we are overriding the read-only view of the prev map here, via
// the cast.
// the cast.
...
@@ -3257,63 +2937,6 @@ ConcurrentMark::claim_region(int task_num) {
...
@@ -3257,63 +2937,6 @@ ConcurrentMark::claim_region(int task_num) {
return
NULL
;
return
NULL
;
}
}
bool
ConcurrentMark
::
invalidate_aborted_regions_in_cset
()
{
guarantee
(
false
,
"invalidate_aborted_regions_in_cset(): "
"don't call this any more"
);
bool
result
=
false
;
for
(
int
i
=
0
;
i
<
(
int
)
_max_task_num
;
++
i
)
{
CMTask
*
the_task
=
_tasks
[
i
];
MemRegion
mr
=
the_task
->
aborted_region
();
if
(
mr
.
start
()
!=
NULL
)
{
assert
(
mr
.
end
()
!=
NULL
,
"invariant"
);
assert
(
mr
.
word_size
()
>
0
,
"invariant"
);
HeapRegion
*
hr
=
_g1h
->
heap_region_containing
(
mr
.
start
());
assert
(
hr
!=
NULL
,
"invariant"
);
if
(
hr
->
in_collection_set
())
{
// The region points into the collection set
the_task
->
set_aborted_region
(
MemRegion
());
result
=
true
;
}
}
}
return
result
;
}
bool
ConcurrentMark
::
has_aborted_regions
()
{
for
(
int
i
=
0
;
i
<
(
int
)
_max_task_num
;
++
i
)
{
CMTask
*
the_task
=
_tasks
[
i
];
MemRegion
mr
=
the_task
->
aborted_region
();
if
(
mr
.
start
()
!=
NULL
)
{
assert
(
mr
.
end
()
!=
NULL
,
"invariant"
);
assert
(
mr
.
word_size
()
>
0
,
"invariant"
);
return
true
;
}
}
return
false
;
}
void
ConcurrentMark
::
oops_do
(
OopClosure
*
cl
)
{
if
(
_markStack
.
size
()
>
0
&&
verbose_low
())
{
gclog_or_tty
->
print_cr
(
"[global] scanning the global marking stack, "
"size = %d"
,
_markStack
.
size
());
}
// we first iterate over the contents of the mark stack...
_markStack
.
oops_do
(
cl
);
for
(
int
i
=
0
;
i
<
(
int
)
_max_task_num
;
++
i
)
{
OopTaskQueue
*
queue
=
_task_queues
->
queue
((
int
)
i
);
if
(
queue
->
size
()
>
0
&&
verbose_low
())
{
gclog_or_tty
->
print_cr
(
"[global] scanning task queue of task %d, "
"size = %d"
,
i
,
queue
->
size
());
}
// ...then over the contents of the all the task queues.
queue
->
oops_do
(
cl
);
}
}
#ifndef PRODUCT
#ifndef PRODUCT
enum
VerifyNoCSetOopsPhase
{
enum
VerifyNoCSetOopsPhase
{
VerifyNoCSetOopsStack
,
VerifyNoCSetOopsStack
,
...
@@ -3445,8 +3068,6 @@ void ConcurrentMark::verify_no_cset_oops(bool verify_stacks,
...
@@ -3445,8 +3068,6 @@ void ConcurrentMark::verify_no_cset_oops(bool verify_stacks,
void
ConcurrentMark
::
clear_marking_state
(
bool
clear_overflow
)
{
void
ConcurrentMark
::
clear_marking_state
(
bool
clear_overflow
)
{
_markStack
.
setEmpty
();
_markStack
.
setEmpty
();
_markStack
.
clear_overflow
();
_markStack
.
clear_overflow
();
_regionStack
.
setEmpty
();
_regionStack
.
clear_overflow
();
if
(
clear_overflow
)
{
if
(
clear_overflow
)
{
clear_has_overflown
();
clear_has_overflown
();
}
else
{
}
else
{
...
@@ -3457,8 +3078,6 @@ void ConcurrentMark::clear_marking_state(bool clear_overflow) {
...
@@ -3457,8 +3078,6 @@ void ConcurrentMark::clear_marking_state(bool clear_overflow) {
for
(
int
i
=
0
;
i
<
(
int
)
_max_task_num
;
++
i
)
{
for
(
int
i
=
0
;
i
<
(
int
)
_max_task_num
;
++
i
)
{
OopTaskQueue
*
queue
=
_task_queues
->
queue
(
i
);
OopTaskQueue
*
queue
=
_task_queues
->
queue
(
i
);
queue
->
set_empty
();
queue
->
set_empty
();
// Clear any partial regions from the CMTasks
_tasks
[
i
]
->
clear_aborted_region
();
}
}
}
}
...
@@ -3658,327 +3277,6 @@ void ConcurrentMark::print_stats() {
...
@@ -3658,327 +3277,6 @@ void ConcurrentMark::print_stats() {
}
}
}
}
// Closures used by ConcurrentMark::complete_marking_in_collection_set().
class
CSetMarkOopClosure
:
public
OopClosure
{
friend
class
CSetMarkBitMapClosure
;
G1CollectedHeap
*
_g1h
;
CMBitMap
*
_bm
;
ConcurrentMark
*
_cm
;
oop
*
_ms
;
jint
*
_array_ind_stack
;
int
_ms_size
;
int
_ms_ind
;
int
_array_increment
;
uint
_worker_id
;
bool
push
(
oop
obj
,
int
arr_ind
=
0
)
{
if
(
_ms_ind
==
_ms_size
)
{
gclog_or_tty
->
print_cr
(
"Mark stack is full."
);
return
false
;
}
_ms
[
_ms_ind
]
=
obj
;
if
(
obj
->
is_objArray
())
{
_array_ind_stack
[
_ms_ind
]
=
arr_ind
;
}
_ms_ind
++
;
return
true
;
}
oop
pop
()
{
if
(
_ms_ind
==
0
)
{
return
NULL
;
}
else
{
_ms_ind
--
;
return
_ms
[
_ms_ind
];
}
}
template
<
class
T
>
bool
drain
()
{
while
(
_ms_ind
>
0
)
{
oop
obj
=
pop
();
assert
(
obj
!=
NULL
,
"Since index was non-zero."
);
if
(
obj
->
is_objArray
())
{
jint
arr_ind
=
_array_ind_stack
[
_ms_ind
];
objArrayOop
aobj
=
objArrayOop
(
obj
);
jint
len
=
aobj
->
length
();
jint
next_arr_ind
=
arr_ind
+
_array_increment
;
if
(
next_arr_ind
<
len
)
{
push
(
obj
,
next_arr_ind
);
}
// Now process this portion of this one.
int
lim
=
MIN2
(
next_arr_ind
,
len
);
for
(
int
j
=
arr_ind
;
j
<
lim
;
j
++
)
{
do_oop
(
aobj
->
objArrayOopDesc
::
obj_at_addr
<
T
>
(
j
));
}
}
else
{
obj
->
oop_iterate
(
this
);
}
if
(
abort
())
return
false
;
}
return
true
;
}
public:
CSetMarkOopClosure
(
ConcurrentMark
*
cm
,
int
ms_size
,
uint
worker_id
)
:
_g1h
(
G1CollectedHeap
::
heap
()),
_cm
(
cm
),
_bm
(
cm
->
nextMarkBitMap
()),
_ms_size
(
ms_size
),
_ms_ind
(
0
),
_ms
(
NEW_C_HEAP_ARRAY
(
oop
,
ms_size
)),
_array_ind_stack
(
NEW_C_HEAP_ARRAY
(
jint
,
ms_size
)),
_array_increment
(
MAX2
(
ms_size
/
8
,
16
)),
_worker_id
(
worker_id
)
{
}
~
CSetMarkOopClosure
()
{
FREE_C_HEAP_ARRAY
(
oop
,
_ms
);
FREE_C_HEAP_ARRAY
(
jint
,
_array_ind_stack
);
}
virtual
void
do_oop
(
narrowOop
*
p
)
{
do_oop_work
(
p
);
}
virtual
void
do_oop
(
oop
*
p
)
{
do_oop_work
(
p
);
}
template
<
class
T
>
void
do_oop_work
(
T
*
p
)
{
T
heap_oop
=
oopDesc
::
load_heap_oop
(
p
);
if
(
oopDesc
::
is_null
(
heap_oop
))
return
;
oop
obj
=
oopDesc
::
decode_heap_oop_not_null
(
heap_oop
);
if
(
obj
->
is_forwarded
())
{
// If the object has already been forwarded, we have to make sure
// that it's marked. So follow the forwarding pointer. Note that
// this does the right thing for self-forwarding pointers in the
// evacuation failure case.
obj
=
obj
->
forwardee
();
}
HeapRegion
*
hr
=
_g1h
->
heap_region_containing
(
obj
);
if
(
hr
!=
NULL
)
{
if
(
hr
->
in_collection_set
())
{
if
(
_g1h
->
is_obj_ill
(
obj
))
{
if
(
_bm
->
parMark
((
HeapWord
*
)
obj
))
{
if
(
!
push
(
obj
))
{
gclog_or_tty
->
print_cr
(
"Setting abort in CSetMarkOopClosure because push failed."
);
set_abort
();
}
}
}
}
else
{
// Outside the collection set; we need to gray it
_cm
->
deal_with_reference
(
obj
);
}
}
}
};
class
CSetMarkBitMapClosure
:
public
BitMapClosure
{
G1CollectedHeap
*
_g1h
;
CMBitMap
*
_bitMap
;
ConcurrentMark
*
_cm
;
CSetMarkOopClosure
_oop_cl
;
uint
_worker_id
;
public:
CSetMarkBitMapClosure
(
ConcurrentMark
*
cm
,
int
ms_size
,
int
worker_id
)
:
_g1h
(
G1CollectedHeap
::
heap
()),
_bitMap
(
cm
->
nextMarkBitMap
()),
_oop_cl
(
cm
,
ms_size
,
worker_id
),
_worker_id
(
worker_id
)
{
}
bool
do_bit
(
size_t
offset
)
{
// convert offset into a HeapWord*
HeapWord
*
addr
=
_bitMap
->
offsetToHeapWord
(
offset
);
assert
(
_bitMap
->
endWord
()
&&
addr
<
_bitMap
->
endWord
(),
"address out of range"
);
assert
(
_bitMap
->
isMarked
(
addr
),
"tautology"
);
oop
obj
=
oop
(
addr
);
if
(
!
obj
->
is_forwarded
())
{
if
(
!
_oop_cl
.
push
(
obj
))
return
false
;
if
(
UseCompressedOops
)
{
if
(
!
_oop_cl
.
drain
<
narrowOop
>
())
return
false
;
}
else
{
if
(
!
_oop_cl
.
drain
<
oop
>
())
return
false
;
}
}
// Otherwise...
return
true
;
}
};
class
CompleteMarkingInCSetHRClosure
:
public
HeapRegionClosure
{
CMBitMap
*
_bm
;
CSetMarkBitMapClosure
_bit_cl
;
uint
_worker_id
;
enum
SomePrivateConstants
{
MSSize
=
1000
};
public:
CompleteMarkingInCSetHRClosure
(
ConcurrentMark
*
cm
,
int
worker_id
)
:
_bm
(
cm
->
nextMarkBitMap
()),
_bit_cl
(
cm
,
MSSize
,
worker_id
),
_worker_id
(
worker_id
)
{
}
bool
doHeapRegion
(
HeapRegion
*
hr
)
{
if
(
hr
->
claimHeapRegion
(
HeapRegion
::
CompleteMarkCSetClaimValue
))
{
// The current worker has successfully claimed the region.
if
(
!
hr
->
evacuation_failed
())
{
MemRegion
mr
=
MemRegion
(
hr
->
bottom
(),
hr
->
next_top_at_mark_start
());
if
(
!
mr
.
is_empty
())
{
bool
done
=
false
;
while
(
!
done
)
{
done
=
_bm
->
iterate
(
&
_bit_cl
,
mr
);
}
}
}
}
return
false
;
}
};
class
G1ParCompleteMarkInCSetTask
:
public
AbstractGangTask
{
protected:
G1CollectedHeap
*
_g1h
;
ConcurrentMark
*
_cm
;
public:
G1ParCompleteMarkInCSetTask
(
G1CollectedHeap
*
g1h
,
ConcurrentMark
*
cm
)
:
AbstractGangTask
(
"Complete Mark in CSet"
),
_g1h
(
g1h
),
_cm
(
cm
)
{
}
void
work
(
uint
worker_id
)
{
CompleteMarkingInCSetHRClosure
cmplt
(
_cm
,
worker_id
);
HeapRegion
*
hr
=
_g1h
->
start_cset_region_for_worker
(
worker_id
);
_g1h
->
collection_set_iterate_from
(
hr
,
&
cmplt
);
}
};
void
ConcurrentMark
::
complete_marking_in_collection_set
()
{
guarantee
(
false
,
"complete_marking_in_collection_set(): "
"don't call this any more"
);
G1CollectedHeap
*
g1h
=
G1CollectedHeap
::
heap
();
if
(
!
g1h
->
mark_in_progress
())
{
g1h
->
g1_policy
()
->
record_mark_closure_time
(
0.0
);
return
;
}
double
start
=
os
::
elapsedTime
();
G1ParCompleteMarkInCSetTask
complete_mark_task
(
g1h
,
this
);
assert
(
g1h
->
check_cset_heap_region_claim_values
(
HeapRegion
::
InitialClaimValue
),
"sanity"
);
if
(
G1CollectedHeap
::
use_parallel_gc_threads
())
{
int
n_workers
=
g1h
->
workers
()
->
active_workers
();
g1h
->
set_par_threads
(
n_workers
);
g1h
->
workers
()
->
run_task
(
&
complete_mark_task
);
g1h
->
set_par_threads
(
0
);
}
else
{
complete_mark_task
.
work
(
0
);
}
assert
(
g1h
->
check_cset_heap_region_claim_values
(
HeapRegion
::
CompleteMarkCSetClaimValue
),
"sanity"
);
// Reset the claim values in the regions in the collection set.
g1h
->
reset_cset_heap_region_claim_values
();
assert
(
g1h
->
check_cset_heap_region_claim_values
(
HeapRegion
::
InitialClaimValue
),
"sanity"
);
double
end_time
=
os
::
elapsedTime
();
double
elapsed_time_ms
=
(
end_time
-
start
)
*
1000.0
;
g1h
->
g1_policy
()
->
record_mark_closure_time
(
elapsed_time_ms
);
}
// The next two methods deal with the following optimisation. Some
// objects are gray by being marked and located above the finger. If
// they are copied, during an evacuation pause, below the finger then
// the need to be pushed on the stack. The observation is that, if
// there are no regions in the collection set located above the
// finger, then the above cannot happen, hence we do not need to
// explicitly gray any objects when copying them to below the
// finger. The global stack will be scanned to ensure that, if it
// points to objects being copied, it will update their
// location. There is a tricky situation with the gray objects in
// region stack that are being coped, however. See the comment in
// newCSet().
void
ConcurrentMark
::
newCSet
()
{
guarantee
(
false
,
"newCSet(): don't call this any more"
);
if
(
!
concurrent_marking_in_progress
())
{
// nothing to do if marking is not in progress
return
;
}
// find what the lowest finger is among the global and local fingers
_min_finger
=
_finger
;
for
(
int
i
=
0
;
i
<
(
int
)
_max_task_num
;
++
i
)
{
CMTask
*
task
=
_tasks
[
i
];
HeapWord
*
task_finger
=
task
->
finger
();
if
(
task_finger
!=
NULL
&&
task_finger
<
_min_finger
)
{
_min_finger
=
task_finger
;
}
}
_should_gray_objects
=
false
;
// This fixes a very subtle and fustrating bug. It might be the case
// that, during en evacuation pause, heap regions that contain
// objects that are gray (by being in regions contained in the
// region stack) are included in the collection set. Since such gray
// objects will be moved, and because it's not easy to redirect
// region stack entries to point to a new location (because objects
// in one region might be scattered to multiple regions after they
// are copied), one option is to ensure that all marked objects
// copied during a pause are pushed on the stack. Notice, however,
// that this problem can only happen when the region stack is not
// empty during an evacuation pause. So, we make the fix a bit less
// conservative and ensure that regions are pushed on the stack,
// irrespective whether all collection set regions are below the
// finger, if the region stack is not empty. This is expected to be
// a rare case, so I don't think it's necessary to be smarted about it.
if
(
!
region_stack_empty
()
||
has_aborted_regions
())
{
_should_gray_objects
=
true
;
}
}
void
ConcurrentMark
::
registerCSetRegion
(
HeapRegion
*
hr
)
{
guarantee
(
false
,
"registerCSetRegion(): don't call this any more"
);
if
(
!
concurrent_marking_in_progress
())
return
;
HeapWord
*
region_end
=
hr
->
end
();
if
(
region_end
>
_min_finger
)
{
_should_gray_objects
=
true
;
}
}
// Resets the region fields of active CMTasks whose values point
// into the collection set.
void
ConcurrentMark
::
reset_active_task_region_fields_in_cset
()
{
guarantee
(
false
,
"reset_active_task_region_fields_in_cset(): "
"don't call this any more"
);
assert
(
SafepointSynchronize
::
is_at_safepoint
(),
"should be in STW"
);
assert
(
parallel_marking_threads
()
<=
_max_task_num
,
"sanity"
);
for
(
int
i
=
0
;
i
<
(
int
)
parallel_marking_threads
();
i
+=
1
)
{
CMTask
*
task
=
_tasks
[
i
];
HeapWord
*
task_finger
=
task
->
finger
();
if
(
task_finger
!=
NULL
)
{
assert
(
_g1h
->
is_in_g1_reserved
(
task_finger
),
"not in heap"
);
HeapRegion
*
finger_region
=
_g1h
->
heap_region_containing
(
task_finger
);
if
(
finger_region
->
in_collection_set
())
{
// The task's current region is in the collection set.
// This region will be evacuated in the current GC and
// the region fields in the task will be stale.
task
->
giveup_current_region
();
}
}
}
}
// abandon current marking iteration due to a Full GC
// abandon current marking iteration due to a Full GC
void
ConcurrentMark
::
abort
()
{
void
ConcurrentMark
::
abort
()
{
// Clear all marks to force marking thread to do nothing
// Clear all marks to force marking thread to do nothing
...
@@ -4112,36 +3410,21 @@ private:
...
@@ -4112,36 +3410,21 @@ private:
CMBitMap
*
_nextMarkBitMap
;
CMBitMap
*
_nextMarkBitMap
;
ConcurrentMark
*
_cm
;
ConcurrentMark
*
_cm
;
CMTask
*
_task
;
CMTask
*
_task
;
// true if we're scanning a heap region claimed by the task (so that
// we move the finger along), false if we're not, i.e. currently when
// scanning a heap region popped from the region stack (so that we
// do not move the task finger along; it'd be a mistake if we did so).
bool
_scanning_heap_region
;
public:
public:
CMBitMapClosure
(
CMTask
*
task
,
CMBitMapClosure
(
CMTask
*
task
,
ConcurrentMark
*
cm
,
CMBitMap
*
nextMarkBitMap
)
:
ConcurrentMark
*
cm
,
_task
(
task
),
_cm
(
cm
),
_nextMarkBitMap
(
nextMarkBitMap
)
{
}
CMBitMap
*
nextMarkBitMap
)
:
_task
(
task
),
_cm
(
cm
),
_nextMarkBitMap
(
nextMarkBitMap
)
{
}
void
set_scanning_heap_region
(
bool
scanning_heap_region
)
{
_scanning_heap_region
=
scanning_heap_region
;
}
bool
do_bit
(
size_t
offset
)
{
bool
do_bit
(
size_t
offset
)
{
HeapWord
*
addr
=
_nextMarkBitMap
->
offsetToHeapWord
(
offset
);
HeapWord
*
addr
=
_nextMarkBitMap
->
offsetToHeapWord
(
offset
);
assert
(
_nextMarkBitMap
->
isMarked
(
addr
),
"invariant"
);
assert
(
_nextMarkBitMap
->
isMarked
(
addr
),
"invariant"
);
assert
(
addr
<
_cm
->
finger
(),
"invariant"
);
assert
(
addr
<
_cm
->
finger
(),
"invariant"
);
if
(
_scanning_heap_region
)
{
statsOnly
(
_task
->
increase_objs_found_on_bitmap
()
);
statsOnly
(
_task
->
increase_objs_found_on_bitmap
()
);
assert
(
addr
>=
_task
->
finger
(),
"invariant"
);
assert
(
addr
>=
_task
->
finger
(),
"invariant"
);
// We move that task's local finger along.
// We move that task's local finger along.
_task
->
move_finger_to
(
addr
);
_task
->
move_finger_to
(
addr
);
}
else
{
// We move the task's region finger along.
_task
->
move_region_finger_to
(
addr
);
}
_task
->
scan_object
(
oop
(
addr
));
_task
->
scan_object
(
oop
(
addr
));
// we only partially drain the local queue and global stack
// we only partially drain the local queue and global stack
...
@@ -4249,8 +3532,6 @@ void CMTask::clear_region_fields() {
...
@@ -4249,8 +3532,6 @@ void CMTask::clear_region_fields() {
_curr_region
=
NULL
;
_curr_region
=
NULL
;
_finger
=
NULL
;
_finger
=
NULL
;
_region_limit
=
NULL
;
_region_limit
=
NULL
;
_region_finger
=
NULL
;
}
}
void
CMTask
::
set_cm_oop_closure
(
G1CMOopClosure
*
cm_oop_closure
)
{
void
CMTask
::
set_cm_oop_closure
(
G1CMOopClosure
*
cm_oop_closure
)
{
...
@@ -4271,7 +3552,6 @@ void CMTask::reset(CMBitMap* nextMarkBitMap) {
...
@@ -4271,7 +3552,6 @@ void CMTask::reset(CMBitMap* nextMarkBitMap) {
_nextMarkBitMap
=
nextMarkBitMap
;
_nextMarkBitMap
=
nextMarkBitMap
;
clear_region_fields
();
clear_region_fields
();
assert
(
_aborted_region
.
is_empty
(),
"should have been cleared"
);
_calls
=
0
;
_calls
=
0
;
_elapsed_time_ms
=
0.0
;
_elapsed_time_ms
=
0.0
;
...
@@ -4288,7 +3568,6 @@ void CMTask::reset(CMBitMap* nextMarkBitMap) {
...
@@ -4288,7 +3568,6 @@ void CMTask::reset(CMBitMap* nextMarkBitMap) {
_global_max_size
=
0
;
_global_max_size
=
0
;
_global_transfers_to
=
0
;
_global_transfers_to
=
0
;
_global_transfers_from
=
0
;
_global_transfers_from
=
0
;
_region_stack_pops
=
0
;
_regions_claimed
=
0
;
_regions_claimed
=
0
;
_objs_found_on_bitmap
=
0
;
_objs_found_on_bitmap
=
0
;
_satb_buffers_processed
=
0
;
_satb_buffers_processed
=
0
;
...
@@ -4663,110 +3942,6 @@ void CMTask::drain_satb_buffers() {
...
@@ -4663,110 +3942,6 @@ void CMTask::drain_satb_buffers() {
decrease_limits
();
decrease_limits
();
}
}
void
CMTask
::
drain_region_stack
(
BitMapClosure
*
bc
)
{
assert
(
_cm
->
region_stack_empty
(),
"region stack should be empty"
);
assert
(
_aborted_region
.
is_empty
(),
"aborted region should be empty"
);
return
;
if
(
has_aborted
())
return
;
assert
(
_region_finger
==
NULL
,
"it should be NULL when we're not scanning a region"
);
if
(
!
_cm
->
region_stack_empty
()
||
!
_aborted_region
.
is_empty
())
{
if
(
_cm
->
verbose_low
())
{
gclog_or_tty
->
print_cr
(
"[%d] draining region stack, size = %d"
,
_task_id
,
_cm
->
region_stack_size
());
}
MemRegion
mr
;
if
(
!
_aborted_region
.
is_empty
())
{
mr
=
_aborted_region
;
_aborted_region
=
MemRegion
();
if
(
_cm
->
verbose_low
())
{
gclog_or_tty
->
print_cr
(
"[%d] scanning aborted region "
"[ "
PTR_FORMAT
", "
PTR_FORMAT
" )"
,
_task_id
,
mr
.
start
(),
mr
.
end
());
}
}
else
{
mr
=
_cm
->
region_stack_pop_lock_free
();
// it returns MemRegion() if the pop fails
statsOnly
(
if
(
mr
.
start
()
!=
NULL
)
++
_region_stack_pops
);
}
while
(
mr
.
start
()
!=
NULL
)
{
if
(
_cm
->
verbose_medium
())
{
gclog_or_tty
->
print_cr
(
"[%d] we are scanning region "
"["
PTR_FORMAT
", "
PTR_FORMAT
")"
,
_task_id
,
mr
.
start
(),
mr
.
end
());
}
assert
(
mr
.
end
()
<=
_cm
->
finger
(),
"otherwise the region shouldn't be on the stack"
);
assert
(
!
mr
.
is_empty
(),
"Only non-empty regions live on the region stack"
);
if
(
_nextMarkBitMap
->
iterate
(
bc
,
mr
))
{
assert
(
!
has_aborted
(),
"cannot abort the task without aborting the bitmap iteration"
);
// We finished iterating over the region without aborting.
regular_clock_call
();
if
(
has_aborted
())
{
mr
=
MemRegion
();
}
else
{
mr
=
_cm
->
region_stack_pop_lock_free
();
// it returns MemRegion() if the pop fails
statsOnly
(
if
(
mr
.
start
()
!=
NULL
)
++
_region_stack_pops
);
}
}
else
{
assert
(
has_aborted
(),
"currently the only way to do so"
);
// The only way to abort the bitmap iteration is to return
// false from the do_bit() method. However, inside the
// do_bit() method we move the _region_finger to point to the
// object currently being looked at. So, if we bail out, we
// have definitely set _region_finger to something non-null.
assert
(
_region_finger
!=
NULL
,
"invariant"
);
// Make sure that any previously aborted region has been
// cleared.
assert
(
_aborted_region
.
is_empty
(),
"aborted region not cleared"
);
// The iteration was actually aborted. So now _region_finger
// points to the address of the object we last scanned. If we
// leave it there, when we restart this task, we will rescan
// the object. It is easy to avoid this. We move the finger by
// enough to point to the next possible object header (the
// bitmap knows by how much we need to move it as it knows its
// granularity).
MemRegion
newRegion
=
MemRegion
(
_nextMarkBitMap
->
nextWord
(
_region_finger
),
mr
.
end
());
if
(
!
newRegion
.
is_empty
())
{
if
(
_cm
->
verbose_low
())
{
gclog_or_tty
->
print_cr
(
"[%d] recording unscanned region"
"["
PTR_FORMAT
","
PTR_FORMAT
") in CMTask"
,
_task_id
,
newRegion
.
start
(),
newRegion
.
end
());
}
// Now record the part of the region we didn't scan to
// make sure this task scans it later.
_aborted_region
=
newRegion
;
}
// break from while
mr
=
MemRegion
();
}
_region_finger
=
NULL
;
}
if
(
_cm
->
verbose_low
())
{
gclog_or_tty
->
print_cr
(
"[%d] drained region stack, size = %d"
,
_task_id
,
_cm
->
region_stack_size
());
}
}
}
void
CMTask
::
print_stats
()
{
void
CMTask
::
print_stats
()
{
gclog_or_tty
->
print_cr
(
"Marking Stats, task = %d, calls = %d"
,
gclog_or_tty
->
print_cr
(
"Marking Stats, task = %d, calls = %d"
,
_task_id
,
_calls
);
_task_id
,
_calls
);
...
@@ -4795,8 +3970,7 @@ void CMTask::print_stats() {
...
@@ -4795,8 +3970,7 @@ void CMTask::print_stats() {
_global_pushes
,
_global_pops
,
_global_max_size
);
_global_pushes
,
_global_pops
,
_global_max_size
);
gclog_or_tty
->
print_cr
(
" transfers to = %d, transfers from = %d"
,
gclog_or_tty
->
print_cr
(
" transfers to = %d, transfers from = %d"
,
_global_transfers_to
,
_global_transfers_from
);
_global_transfers_to
,
_global_transfers_from
);
gclog_or_tty
->
print_cr
(
" Regions: claimed = %d, Region Stack: pops = %d"
,
gclog_or_tty
->
print_cr
(
" Regions: claimed = %d"
,
_regions_claimed
);
_regions_claimed
,
_region_stack_pops
);
gclog_or_tty
->
print_cr
(
" SATB buffers: processed = %d"
,
_satb_buffers_processed
);
gclog_or_tty
->
print_cr
(
" SATB buffers: processed = %d"
,
_satb_buffers_processed
);
gclog_or_tty
->
print_cr
(
" Steals: attempts = %d, successes = %d"
,
gclog_or_tty
->
print_cr
(
" Steals: attempts = %d, successes = %d"
,
_steal_attempts
,
_steals
);
_steal_attempts
,
_steals
);
...
@@ -4855,15 +4029,7 @@ void CMTask::print_stats() {
...
@@ -4855,15 +4029,7 @@ void CMTask::print_stats() {
popping by other tasks. Only when there is no more work, tasks
popping by other tasks. Only when there is no more work, tasks
will totally drain the global mark stack.
will totally drain the global mark stack.
(4) Global Region Stack. Entries on it correspond to areas of
(4) SATB Buffer Queue. This is where completed SATB buffers are
the bitmap that need to be scanned since they contain gray
objects. Pushes on the region stack only happen during
evacuation pauses and typically correspond to areas covered by
GC LABS. If it overflows, then the marking phase should restart
and iterate over the bitmap to identify gray objects. Tasks will
try to totally drain the region stack as soon as possible.
(5) SATB Buffer Queue. This is where completed SATB buffers are
made available. Buffers are regularly removed from this queue
made available. Buffers are regularly removed from this queue
and scanned for roots, so that the queue doesn't get too
and scanned for roots, so that the queue doesn't get too
long. During remark, all completed buffers are processed, as
long. During remark, all completed buffers are processed, as
...
@@ -4875,12 +4041,12 @@ void CMTask::print_stats() {
...
@@ -4875,12 +4041,12 @@ void CMTask::print_stats() {
(1) When the marking phase has been aborted (after a Full GC).
(1) When the marking phase has been aborted (after a Full GC).
(2) When a global overflow (
either on the global stack or the
(2) When a global overflow (
on the global stack) has been
region stack) has been triggered. Before the task aborts, it
triggered. Before the task aborts, it will actually sync up with
will actually sync up with the other tasks to ensure that all
the other tasks to ensure that all the marking data structures
the marking data structures (local queues, stacks, fingers etc.)
(local queues, stacks, fingers etc.) are re-initialised so that
are re-initialised so that when do_marking_step() completes,
when do_marking_step() completes, the marking phase can
the marking phase can
immediately restart.
immediately restart.
(3) When enough completed SATB buffers are available. The
(3) When enough completed SATB buffers are available. The
do_marking_step() method only tries to drain SATB buffers right
do_marking_step() method only tries to drain SATB buffers right
...
@@ -4923,13 +4089,6 @@ void CMTask::do_marking_step(double time_target_ms,
...
@@ -4923,13 +4089,6 @@ void CMTask::do_marking_step(double time_target_ms,
assert
(
time_target_ms
>=
1.0
,
"minimum granularity is 1ms"
);
assert
(
time_target_ms
>=
1.0
,
"minimum granularity is 1ms"
);
assert
(
concurrent
()
==
_cm
->
concurrent
(),
"they should be the same"
);
assert
(
concurrent
()
==
_cm
->
concurrent
(),
"they should be the same"
);
assert
(
concurrent
()
||
_cm
->
region_stack_empty
(),
"the region stack should have been cleared before remark"
);
assert
(
concurrent
()
||
!
_cm
->
has_aborted_regions
(),
"aborted regions should have been cleared before remark"
);
assert
(
_region_finger
==
NULL
,
"this should be non-null only when a region is being scanned"
);
G1CollectorPolicy
*
g1_policy
=
_g1h
->
g1_policy
();
G1CollectorPolicy
*
g1_policy
=
_g1h
->
g1_policy
();
assert
(
_task_queues
!=
NULL
,
"invariant"
);
assert
(
_task_queues
!=
NULL
,
"invariant"
);
assert
(
_task_queue
!=
NULL
,
"invariant"
);
assert
(
_task_queue
!=
NULL
,
"invariant"
);
...
@@ -4978,10 +4137,10 @@ void CMTask::do_marking_step(double time_target_ms,
...
@@ -4978,10 +4137,10 @@ void CMTask::do_marking_step(double time_target_ms,
set_cm_oop_closure
(
&
cm_oop_closure
);
set_cm_oop_closure
(
&
cm_oop_closure
);
if
(
_cm
->
has_overflown
())
{
if
(
_cm
->
has_overflown
())
{
// This can happen if the
region stack or the mark stack overflows
// This can happen if the
mark stack overflows during a GC pause
//
during a GC pause and this task, after a yield point,
//
and this task, after a yield point, restarts. We have to abort
//
restarts. We have to abort as we need to get into the overflow
//
as we need to get into the overflow protocol which happens
//
protocol which happens
right at the end of this task.
// right at the end of this task.
set_has_aborted
();
set_has_aborted
();
}
}
...
@@ -4994,17 +4153,6 @@ void CMTask::do_marking_step(double time_target_ms,
...
@@ -4994,17 +4153,6 @@ void CMTask::do_marking_step(double time_target_ms,
drain_local_queue
(
true
);
drain_local_queue
(
true
);
drain_global_stack
(
true
);
drain_global_stack
(
true
);
// Then totally drain the region stack. We will not look at
// it again before the next invocation of this method. Entries on
// the region stack are only added during evacuation pauses, for
// which we have to yield. When we do, we abort the task anyway so
// it will look at the region stack again when it restarts.
bitmap_closure
.
set_scanning_heap_region
(
false
);
drain_region_stack
(
&
bitmap_closure
);
// ...then partially drain the local queue and the global stack
drain_local_queue
(
true
);
drain_global_stack
(
true
);
do
{
do
{
if
(
!
has_aborted
()
&&
_curr_region
!=
NULL
)
{
if
(
!
has_aborted
()
&&
_curr_region
!=
NULL
)
{
// This means that we're already holding on to a region.
// This means that we're already holding on to a region.
...
@@ -5034,9 +4182,7 @@ void CMTask::do_marking_step(double time_target_ms,
...
@@ -5034,9 +4182,7 @@ void CMTask::do_marking_step(double time_target_ms,
// Let's iterate over the bitmap of the part of the
// Let's iterate over the bitmap of the part of the
// region that is left.
// region that is left.
bitmap_closure
.
set_scanning_heap_region
(
true
);
if
(
mr
.
is_empty
()
||
_nextMarkBitMap
->
iterate
(
&
bitmap_closure
,
mr
))
{
if
(
mr
.
is_empty
()
||
_nextMarkBitMap
->
iterate
(
&
bitmap_closure
,
mr
))
{
// We successfully completed iterating over the region. Now,
// We successfully completed iterating over the region. Now,
// let's give up the region.
// let's give up the region.
giveup_current_region
();
giveup_current_region
();
...
@@ -5061,9 +4207,9 @@ void CMTask::do_marking_step(double time_target_ms,
...
@@ -5061,9 +4207,9 @@ void CMTask::do_marking_step(double time_target_ms,
HeapWord
*
new_finger
=
_nextMarkBitMap
->
nextWord
(
_finger
);
HeapWord
*
new_finger
=
_nextMarkBitMap
->
nextWord
(
_finger
);
// Check if bitmap iteration was aborted while scanning the last object
// Check if bitmap iteration was aborted while scanning the last object
if
(
new_finger
>=
_region_limit
)
{
if
(
new_finger
>=
_region_limit
)
{
giveup_current_region
();
giveup_current_region
();
}
else
{
}
else
{
move_finger_to
(
new_finger
);
move_finger_to
(
new_finger
);
}
}
}
}
}
}
...
@@ -5119,9 +4265,7 @@ void CMTask::do_marking_step(double time_target_ms,
...
@@ -5119,9 +4265,7 @@ void CMTask::do_marking_step(double time_target_ms,
if
(
!
has_aborted
())
{
if
(
!
has_aborted
())
{
// We cannot check whether the global stack is empty, since other
// We cannot check whether the global stack is empty, since other
// tasks might be pushing objects to it concurrently. We also cannot
// tasks might be pushing objects to it concurrently.
// check if the region stack is empty because if a thread is aborting
// it can push a partially done region back.
assert
(
_cm
->
out_of_regions
(),
assert
(
_cm
->
out_of_regions
(),
"at this point we should be out of regions"
);
"at this point we should be out of regions"
);
...
@@ -5145,9 +4289,7 @@ void CMTask::do_marking_step(double time_target_ms,
...
@@ -5145,9 +4289,7 @@ void CMTask::do_marking_step(double time_target_ms,
// we could. Let's try to do some stealing...
// we could. Let's try to do some stealing...
// We cannot check whether the global stack is empty, since other
// We cannot check whether the global stack is empty, since other
// tasks might be pushing objects to it concurrently. We also cannot
// tasks might be pushing objects to it concurrently.
// check if the region stack is empty because if a thread is aborting
// it can push a partially done region back.
assert
(
_cm
->
out_of_regions
()
&&
_task_queue
->
size
()
==
0
,
assert
(
_cm
->
out_of_regions
()
&&
_task_queue
->
size
()
==
0
,
"only way to reach here"
);
"only way to reach here"
);
...
@@ -5194,9 +4336,7 @@ void CMTask::do_marking_step(double time_target_ms,
...
@@ -5194,9 +4336,7 @@ void CMTask::do_marking_step(double time_target_ms,
// termination protocol.
// termination protocol.
if
(
do_termination
&&
!
has_aborted
())
{
if
(
do_termination
&&
!
has_aborted
())
{
// We cannot check whether the global stack is empty, since other
// We cannot check whether the global stack is empty, since other
// tasks might be concurrently pushing objects on it. We also cannot
// tasks might be concurrently pushing objects on it.
// check if the region stack is empty because if a thread is aborting
// it can push a partially done region back.
// Separated the asserts so that we know which one fires.
// Separated the asserts so that we know which one fires.
assert
(
_cm
->
out_of_regions
(),
"only way to reach here"
);
assert
(
_cm
->
out_of_regions
(),
"only way to reach here"
);
assert
(
_task_queue
->
size
()
==
0
,
"only way to reach here"
);
assert
(
_task_queue
->
size
()
==
0
,
"only way to reach here"
);
...
@@ -5233,13 +4373,10 @@ void CMTask::do_marking_step(double time_target_ms,
...
@@ -5233,13 +4373,10 @@ void CMTask::do_marking_step(double time_target_ms,
// that, if a condition is false, we can immediately find out
// that, if a condition is false, we can immediately find out
// which one.
// which one.
guarantee
(
_cm
->
out_of_regions
(),
"only way to reach here"
);
guarantee
(
_cm
->
out_of_regions
(),
"only way to reach here"
);
guarantee
(
_aborted_region
.
is_empty
(),
"only way to reach here"
);
guarantee
(
_cm
->
region_stack_empty
(),
"only way to reach here"
);
guarantee
(
_cm
->
mark_stack_empty
(),
"only way to reach here"
);
guarantee
(
_cm
->
mark_stack_empty
(),
"only way to reach here"
);
guarantee
(
_task_queue
->
size
()
==
0
,
"only way to reach here"
);
guarantee
(
_task_queue
->
size
()
==
0
,
"only way to reach here"
);
guarantee
(
!
_cm
->
has_overflown
(),
"only way to reach here"
);
guarantee
(
!
_cm
->
has_overflown
(),
"only way to reach here"
);
guarantee
(
!
_cm
->
mark_stack_overflow
(),
"only way to reach here"
);
guarantee
(
!
_cm
->
mark_stack_overflow
(),
"only way to reach here"
);
guarantee
(
!
_cm
->
region_stack_overflow
(),
"only way to reach here"
);
if
(
_cm
->
verbose_low
())
{
if
(
_cm
->
verbose_low
())
{
gclog_or_tty
->
print_cr
(
"[%d] all tasks terminated"
,
_task_id
);
gclog_or_tty
->
print_cr
(
"[%d] all tasks terminated"
,
_task_id
);
...
@@ -5342,7 +4479,6 @@ CMTask::CMTask(int task_id,
...
@@ -5342,7 +4479,6 @@ CMTask::CMTask(int task_id,
_task_queue
(
task_queue
),
_task_queue
(
task_queue
),
_task_queues
(
task_queues
),
_task_queues
(
task_queues
),
_cm_oop_closure
(
NULL
),
_cm_oop_closure
(
NULL
),
_aborted_region
(
MemRegion
()),
_marked_bytes_array
(
marked_bytes
),
_marked_bytes_array
(
marked_bytes
),
_card_bm
(
card_bm
)
{
_card_bm
(
card_bm
)
{
guarantee
(
task_queue
!=
NULL
,
"invariant"
);
guarantee
(
task_queue
!=
NULL
,
"invariant"
);
...
...
src/share/vm/gc_implementation/g1/concurrentMark.hpp
浏览文件 @
05d15943
...
@@ -42,9 +42,7 @@ typedef GenericTaskQueueSet<CMTaskQueue> CMTaskQueueSet;
...
@@ -42,9 +42,7 @@ typedef GenericTaskQueueSet<CMTaskQueue> CMTaskQueueSet;
class
G1CMIsAliveClosure
:
public
BoolObjectClosure
{
class
G1CMIsAliveClosure
:
public
BoolObjectClosure
{
G1CollectedHeap
*
_g1
;
G1CollectedHeap
*
_g1
;
public:
public:
G1CMIsAliveClosure
(
G1CollectedHeap
*
g1
)
:
G1CMIsAliveClosure
(
G1CollectedHeap
*
g1
)
:
_g1
(
g1
)
{
}
_g1
(
g1
)
{}
void
do_object
(
oop
obj
)
{
void
do_object
(
oop
obj
)
{
ShouldNotCallThis
();
ShouldNotCallThis
();
...
@@ -111,11 +109,6 @@ class CMBitMapRO VALUE_OBJ_CLASS_SPEC {
...
@@ -111,11 +109,6 @@ class CMBitMapRO VALUE_OBJ_CLASS_SPEC {
return
offsetToHeapWord
(
heapWordToOffset
(
addr
)
+
1
);
return
offsetToHeapWord
(
heapWordToOffset
(
addr
)
+
1
);
}
}
void
mostly_disjoint_range_union
(
BitMap
*
from_bitmap
,
size_t
from_start_index
,
HeapWord
*
to_start_word
,
size_t
word_num
);
// debugging
// debugging
NOT_PRODUCT
(
bool
covers
(
ReservedSpace
rs
)
const
;)
NOT_PRODUCT
(
bool
covers
(
ReservedSpace
rs
)
const
;)
};
};
...
@@ -258,60 +251,6 @@ class CMMarkStack VALUE_OBJ_CLASS_SPEC {
...
@@ -258,60 +251,6 @@ class CMMarkStack VALUE_OBJ_CLASS_SPEC {
void
oops_do
(
OopClosure
*
f
);
void
oops_do
(
OopClosure
*
f
);
};
};
class
CMRegionStack
VALUE_OBJ_CLASS_SPEC
{
MemRegion
*
_base
;
jint
_capacity
;
jint
_index
;
jint
_oops_do_bound
;
bool
_overflow
;
public:
CMRegionStack
();
~
CMRegionStack
();
void
allocate
(
size_t
size
);
// This is lock-free; assumes that it will only be called in parallel
// with other "push" operations (no pops).
void
push_lock_free
(
MemRegion
mr
);
// Lock-free; assumes that it will only be called in parallel
// with other "pop" operations (no pushes).
MemRegion
pop_lock_free
();
#if 0
// The routines that manipulate the region stack with a lock are
// not currently used. They should be retained, however, as a
// diagnostic aid.
// These two are the implementations that use a lock. They can be
// called concurrently with each other but they should not be called
// concurrently with the lock-free versions (push() / pop()).
void push_with_lock(MemRegion mr);
MemRegion pop_with_lock();
#endif
bool
isEmpty
()
{
return
_index
==
0
;
}
bool
isFull
()
{
return
_index
==
_capacity
;
}
bool
overflow
()
{
return
_overflow
;
}
void
clear_overflow
()
{
_overflow
=
false
;
}
int
size
()
{
return
_index
;
}
// It iterates over the entries in the region stack and it
// invalidates (i.e. assigns MemRegion()) the ones that point to
// regions in the collection set.
bool
invalidate_entries_into_cset
();
// This gives an upper bound up to which the iteration in
// invalidate_entries_into_cset() will reach. This prevents
// newly-added entries to be unnecessarily scanned.
void
set_oops_do_bound
()
{
_oops_do_bound
=
_index
;
}
void
setEmpty
()
{
_index
=
0
;
clear_overflow
();
}
};
class
ForceOverflowSettings
VALUE_OBJ_CLASS_SPEC
{
class
ForceOverflowSettings
VALUE_OBJ_CLASS_SPEC
{
private:
private:
#ifndef PRODUCT
#ifndef PRODUCT
...
@@ -408,7 +347,6 @@ class ConcurrentMark : public CHeapObj {
...
@@ -408,7 +347,6 @@ class ConcurrentMark : public CHeapObj {
friend
class
ConcurrentMarkThread
;
friend
class
ConcurrentMarkThread
;
friend
class
CMTask
;
friend
class
CMTask
;
friend
class
CMBitMapClosure
;
friend
class
CMBitMapClosure
;
friend
class
CSetMarkOopClosure
;
friend
class
CMGlobalObjectClosure
;
friend
class
CMGlobalObjectClosure
;
friend
class
CMRemarkTask
;
friend
class
CMRemarkTask
;
friend
class
CMConcurrentMarkingTask
;
friend
class
CMConcurrentMarkingTask
;
...
@@ -443,7 +381,6 @@ protected:
...
@@ -443,7 +381,6 @@ protected:
CMBitMap
_markBitMap2
;
CMBitMap
_markBitMap2
;
CMBitMapRO
*
_prevMarkBitMap
;
// completed mark bitmap
CMBitMapRO
*
_prevMarkBitMap
;
// completed mark bitmap
CMBitMap
*
_nextMarkBitMap
;
// under-construction mark bitmap
CMBitMap
*
_nextMarkBitMap
;
// under-construction mark bitmap
bool
_at_least_one_mark_complete
;
BitMap
_region_bm
;
BitMap
_region_bm
;
BitMap
_card_bm
;
BitMap
_card_bm
;
...
@@ -457,7 +394,6 @@ protected:
...
@@ -457,7 +394,6 @@ protected:
// For gray objects
// For gray objects
CMMarkStack
_markStack
;
// Grey objects behind global finger.
CMMarkStack
_markStack
;
// Grey objects behind global finger.
CMRegionStack
_regionStack
;
// Grey regions behind global finger.
HeapWord
*
volatile
_finger
;
// the global finger, region aligned,
HeapWord
*
volatile
_finger
;
// the global finger, region aligned,
// always points to the end of the
// always points to the end of the
// last claimed region
// last claimed region
...
@@ -502,18 +438,6 @@ protected:
...
@@ -502,18 +438,6 @@ protected:
// verbose level
// verbose level
CMVerboseLevel
_verbose_level
;
CMVerboseLevel
_verbose_level
;
// These two fields are used to implement the optimisation that
// avoids pushing objects on the global/region stack if there are
// no collection set regions above the lowest finger.
// This is the lowest finger (among the global and local fingers),
// which is calculated before a new collection set is chosen.
HeapWord
*
_min_finger
;
// If this flag is true, objects/regions that are marked below the
// finger should be pushed on the stack(s). If this is flag is
// false, it is safe not to push them on the stack(s).
bool
_should_gray_objects
;
// All of these times are in ms.
// All of these times are in ms.
NumberSeq
_init_times
;
NumberSeq
_init_times
;
NumberSeq
_remark_times
;
NumberSeq
_remark_times
;
...
@@ -604,7 +528,7 @@ protected:
...
@@ -604,7 +528,7 @@ protected:
CMTaskQueueSet
*
task_queues
()
{
return
_task_queues
;
}
CMTaskQueueSet
*
task_queues
()
{
return
_task_queues
;
}
// Access / manipulation of the overflow flag which is set to
// Access / manipulation of the overflow flag which is set to
// indicate that the global stack
or region stack
has overflown
// indicate that the global stack has overflown
bool
has_overflown
()
{
return
_has_overflown
;
}
bool
has_overflown
()
{
return
_has_overflown
;
}
void
set_has_overflown
()
{
_has_overflown
=
true
;
}
void
set_has_overflown
()
{
_has_overflown
=
true
;
}
void
clear_has_overflown
()
{
_has_overflown
=
false
;
}
void
clear_has_overflown
()
{
_has_overflown
=
false
;
}
...
@@ -684,68 +608,6 @@ public:
...
@@ -684,68 +608,6 @@ public:
bool
mark_stack_overflow
()
{
return
_markStack
.
overflow
();
}
bool
mark_stack_overflow
()
{
return
_markStack
.
overflow
();
}
bool
mark_stack_empty
()
{
return
_markStack
.
isEmpty
();
}
bool
mark_stack_empty
()
{
return
_markStack
.
isEmpty
();
}
// (Lock-free) Manipulation of the region stack
bool
region_stack_push_lock_free
(
MemRegion
mr
)
{
// Currently we only call the lock-free version during evacuation
// pauses.
assert
(
SafepointSynchronize
::
is_at_safepoint
(),
"world should be stopped"
);
_regionStack
.
push_lock_free
(
mr
);
if
(
_regionStack
.
overflow
())
{
set_has_overflown
();
return
false
;
}
return
true
;
}
// Lock-free version of region-stack pop. Should only be
// called in tandem with other lock-free pops.
MemRegion
region_stack_pop_lock_free
()
{
return
_regionStack
.
pop_lock_free
();
}
#if 0
// The routines that manipulate the region stack with a lock are
// not currently used. They should be retained, however, as a
// diagnostic aid.
bool region_stack_push_with_lock(MemRegion mr) {
// Currently we only call the lock-based version during either
// concurrent marking or remark.
assert(!SafepointSynchronize::is_at_safepoint() || !concurrent(),
"if we are at a safepoint it should be the remark safepoint");
_regionStack.push_with_lock(mr);
if (_regionStack.overflow()) {
set_has_overflown();
return false;
}
return true;
}
MemRegion region_stack_pop_with_lock() {
// Currently we only call the lock-based version during either
// concurrent marking or remark.
assert(!SafepointSynchronize::is_at_safepoint() || !concurrent(),
"if we are at a safepoint it should be the remark safepoint");
return _regionStack.pop_with_lock();
}
#endif
int
region_stack_size
()
{
return
_regionStack
.
size
();
}
bool
region_stack_overflow
()
{
return
_regionStack
.
overflow
();
}
bool
region_stack_empty
()
{
return
_regionStack
.
isEmpty
();
}
// Iterate over any regions that were aborted while draining the
// region stack (any such regions are saved in the corresponding
// CMTask) and invalidate (i.e. assign to the empty MemRegion())
// any regions that point into the collection set.
bool
invalidate_aborted_regions_in_cset
();
// Returns true if there are any aborted memory regions.
bool
has_aborted_regions
();
CMRootRegions
*
root_regions
()
{
return
&
_root_regions
;
}
CMRootRegions
*
root_regions
()
{
return
&
_root_regions
;
}
bool
concurrent_marking_in_progress
()
{
bool
concurrent_marking_in_progress
()
{
...
@@ -774,10 +636,6 @@ public:
...
@@ -774,10 +636,6 @@ public:
return
_task_queues
->
steal
(
task_num
,
hash_seed
,
obj
);
return
_task_queues
->
steal
(
task_num
,
hash_seed
,
obj
);
}
}
// It grays an object by first marking it. Then, if it's behind the
// global finger, it also pushes it on the global stack.
void
deal_with_reference
(
oop
obj
);
ConcurrentMark
(
ReservedSpace
rs
,
int
max_regions
);
ConcurrentMark
(
ReservedSpace
rs
,
int
max_regions
);
~
ConcurrentMark
();
~
ConcurrentMark
();
...
@@ -810,22 +668,6 @@ public:
...
@@ -810,22 +668,6 @@ public:
inline
void
grayRoot
(
oop
obj
,
size_t
word_size
,
inline
void
grayRoot
(
oop
obj
,
size_t
word_size
,
uint
worker_id
,
HeapRegion
*
hr
=
NULL
);
uint
worker_id
,
HeapRegion
*
hr
=
NULL
);
// It's used during evacuation pauses to gray a region, if
// necessary, and it's MT-safe. It assumes that the caller has
// marked any objects on that region. If _should_gray_objects is
// true and we're still doing concurrent marking, the region is
// pushed on the region stack, if it is located below the global
// finger, otherwise we do nothing.
void
grayRegionIfNecessary
(
MemRegion
mr
);
// It's used during evacuation pauses to mark and, if necessary,
// gray a single object and it's MT-safe. It assumes the caller did
// not mark the object. If _should_gray_objects is true and we're
// still doing concurrent marking, the objects is pushed on the
// global stack, if it is located below the global finger, otherwise
// we do nothing.
void
markAndGrayObjectIfNecessary
(
oop
p
);
// It iterates over the heap and for each object it comes across it
// It iterates over the heap and for each object it comes across it
// will dump the contents of its reference fields, as well as
// will dump the contents of its reference fields, as well as
// liveness information for the object and its referents. The dump
// liveness information for the object and its referents. The dump
...
@@ -869,10 +711,6 @@ public:
...
@@ -869,10 +711,6 @@ public:
// Do concurrent phase of marking, to a tentative transitive closure.
// Do concurrent phase of marking, to a tentative transitive closure.
void
markFromRoots
();
void
markFromRoots
();
// Process all unprocessed SATB buffers. It is called at the
// beginning of an evacuation pause.
void
drainAllSATBBuffers
();
void
checkpointRootsFinal
(
bool
clear_all_soft_refs
);
void
checkpointRootsFinal
(
bool
clear_all_soft_refs
);
void
checkpointRootsFinalWork
();
void
checkpointRootsFinalWork
();
void
cleanup
();
void
cleanup
();
...
@@ -899,10 +737,6 @@ public:
...
@@ -899,10 +737,6 @@ public:
_markStack
.
note_end_of_gc
();
_markStack
.
note_end_of_gc
();
}
}
// Iterate over the oops in the mark stack and all local queues. It
// also calls invalidate_entries_into_cset() on the region stack.
void
oops_do
(
OopClosure
*
f
);
// Verify that there are no CSet oops on the stacks (taskqueues /
// Verify that there are no CSet oops on the stacks (taskqueues /
// global mark stack), enqueued SATB buffers, per-thread SATB
// global mark stack), enqueued SATB buffers, per-thread SATB
// buffers, and fingers (global / per-task). The boolean parameters
// buffers, and fingers (global / per-task). The boolean parameters
...
@@ -919,40 +753,6 @@ public:
...
@@ -919,40 +753,6 @@ public:
// unless the force parameter is true.
// unless the force parameter is true.
void
update_g1_committed
(
bool
force
=
false
);
void
update_g1_committed
(
bool
force
=
false
);
void
complete_marking_in_collection_set
();
// It indicates that a new collection set is being chosen.
void
newCSet
();
// It registers a collection set heap region with CM. This is used
// to determine whether any heap regions are located above the finger.
void
registerCSetRegion
(
HeapRegion
*
hr
);
// Resets the region fields of any active CMTask whose region fields
// are in the collection set (i.e. the region currently claimed by
// the CMTask will be evacuated and may be used, subsequently, as
// an alloc region). When this happens the region fields in the CMTask
// are stale and, hence, should be cleared causing the worker thread
// to claim a new region.
void
reset_active_task_region_fields_in_cset
();
// Registers the maximum region-end associated with a set of
// regions with CM. Again this is used to determine whether any
// heap regions are located above the finger.
void
register_collection_set_finger
(
HeapWord
*
max_finger
)
{
// max_finger is the highest heap region end of the regions currently
// contained in the collection set. If this value is larger than
// _min_finger then we need to gray objects.
// This routine is like registerCSetRegion but for an entire
// collection of regions.
if
(
max_finger
>
_min_finger
)
{
_should_gray_objects
=
true
;
}
}
// Returns "true" if at least one mark has been completed.
bool
at_least_one_mark_complete
()
{
return
_at_least_one_mark_complete
;
}
bool
isMarked
(
oop
p
)
const
{
bool
isMarked
(
oop
p
)
const
{
assert
(
p
!=
NULL
&&
p
->
is_oop
(),
"expected an oop"
);
assert
(
p
!=
NULL
&&
p
->
is_oop
(),
"expected an oop"
);
HeapWord
*
addr
=
(
HeapWord
*
)
p
;
HeapWord
*
addr
=
(
HeapWord
*
)
p
;
...
@@ -1164,23 +964,6 @@ private:
...
@@ -1164,23 +964,6 @@ private:
// limit of the region this task is scanning, NULL if we're not scanning one
// limit of the region this task is scanning, NULL if we're not scanning one
HeapWord
*
_region_limit
;
HeapWord
*
_region_limit
;
// This is used only when we scan regions popped from the region
// stack. It records what the last object on such a region we
// scanned was. It is used to ensure that, if we abort region
// iteration, we do not rescan the first part of the region. This
// should be NULL when we're not scanning a region from the region
// stack.
HeapWord
*
_region_finger
;
// If we abort while scanning a region we record the remaining
// unscanned portion and check this field when marking restarts.
// This avoids having to push on the region stack while other
// marking threads may still be popping regions.
// If we were to push the unscanned portion directly to the
// region stack then we would need to using locking versions
// of the push and pop operations.
MemRegion
_aborted_region
;
// the number of words this task has scanned
// the number of words this task has scanned
size_t
_words_scanned
;
size_t
_words_scanned
;
// When _words_scanned reaches this limit, the regular clock is
// When _words_scanned reaches this limit, the regular clock is
...
@@ -1268,8 +1051,6 @@ private:
...
@@ -1268,8 +1051,6 @@ private:
int
_global_transfers_to
;
int
_global_transfers_to
;
int
_global_transfers_from
;
int
_global_transfers_from
;
int
_region_stack_pops
;
int
_regions_claimed
;
int
_regions_claimed
;
int
_objs_found_on_bitmap
;
int
_objs_found_on_bitmap
;
...
@@ -1347,15 +1128,6 @@ public:
...
@@ -1347,15 +1128,6 @@ public:
bool
has_timed_out
()
{
return
_has_timed_out
;
}
bool
has_timed_out
()
{
return
_has_timed_out
;
}
bool
claimed
()
{
return
_claimed
;
}
bool
claimed
()
{
return
_claimed
;
}
// Support routines for the partially scanned region that may be
// recorded as a result of aborting while draining the CMRegionStack
MemRegion
aborted_region
()
{
return
_aborted_region
;
}
void
set_aborted_region
(
MemRegion
mr
)
{
_aborted_region
=
mr
;
}
// Clears any recorded partially scanned region
void
clear_aborted_region
()
{
set_aborted_region
(
MemRegion
());
}
void
set_cm_oop_closure
(
G1CMOopClosure
*
cm_oop_closure
);
void
set_cm_oop_closure
(
G1CMOopClosure
*
cm_oop_closure
);
// It grays the object by marking it and, if necessary, pushing it
// It grays the object by marking it and, if necessary, pushing it
...
@@ -1385,22 +1157,12 @@ public:
...
@@ -1385,22 +1157,12 @@ public:
// buffers are available.
// buffers are available.
void
drain_satb_buffers
();
void
drain_satb_buffers
();
// It keeps popping regions from the region stack and processing
// them until the region stack is empty.
void
drain_region_stack
(
BitMapClosure
*
closure
);
// moves the local finger to a new location
// moves the local finger to a new location
inline
void
move_finger_to
(
HeapWord
*
new_finger
)
{
inline
void
move_finger_to
(
HeapWord
*
new_finger
)
{
assert
(
new_finger
>=
_finger
&&
new_finger
<
_region_limit
,
"invariant"
);
assert
(
new_finger
>=
_finger
&&
new_finger
<
_region_limit
,
"invariant"
);
_finger
=
new_finger
;
_finger
=
new_finger
;
}
}
// moves the region finger to a new location
inline
void
move_region_finger_to
(
HeapWord
*
new_finger
)
{
assert
(
new_finger
<
_cm
->
finger
(),
"invariant"
);
_region_finger
=
new_finger
;
}
CMTask
(
int
task_num
,
ConcurrentMark
*
cm
,
CMTask
(
int
task_num
,
ConcurrentMark
*
cm
,
size_t
*
marked_bytes
,
BitMap
*
card_bm
,
size_t
*
marked_bytes
,
BitMap
*
card_bm
,
CMTaskQueue
*
task_queue
,
CMTaskQueueSet
*
task_queues
);
CMTaskQueue
*
task_queue
,
CMTaskQueueSet
*
task_queues
);
...
...
src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
浏览文件 @
05d15943
...
@@ -4355,7 +4355,8 @@ G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1,
...
@@ -4355,7 +4355,8 @@ G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1,
_during_initial_mark
(
_g1
->
g1_policy
()
->
during_initial_mark_pause
()),
_during_initial_mark
(
_g1
->
g1_policy
()
->
during_initial_mark_pause
()),
_mark_in_progress
(
_g1
->
mark_in_progress
())
{
}
_mark_in_progress
(
_g1
->
mark_in_progress
())
{
}
void
G1ParCopyHelper
::
mark_object
(
oop
obj
)
{
template
<
bool
do_gen_barrier
,
G1Barrier
barrier
,
bool
do_mark_object
>
void
G1ParCopyClosure
<
do_gen_barrier
,
barrier
,
do_mark_object
>::
mark_object
(
oop
obj
)
{
#ifdef ASSERT
#ifdef ASSERT
HeapRegion
*
hr
=
_g1
->
heap_region_containing
(
obj
);
HeapRegion
*
hr
=
_g1
->
heap_region_containing
(
obj
);
assert
(
hr
!=
NULL
,
"sanity"
);
assert
(
hr
!=
NULL
,
"sanity"
);
...
@@ -4366,7 +4367,9 @@ void G1ParCopyHelper::mark_object(oop obj) {
...
@@ -4366,7 +4367,9 @@ void G1ParCopyHelper::mark_object(oop obj) {
_cm
->
grayRoot
(
obj
,
(
size_t
)
obj
->
size
(),
_worker_id
);
_cm
->
grayRoot
(
obj
,
(
size_t
)
obj
->
size
(),
_worker_id
);
}
}
void
G1ParCopyHelper
::
mark_forwarded_object
(
oop
from_obj
,
oop
to_obj
)
{
template
<
bool
do_gen_barrier
,
G1Barrier
barrier
,
bool
do_mark_object
>
void
G1ParCopyClosure
<
do_gen_barrier
,
barrier
,
do_mark_object
>
::
mark_forwarded_object
(
oop
from_obj
,
oop
to_obj
)
{
#ifdef ASSERT
#ifdef ASSERT
assert
(
from_obj
->
is_forwarded
(),
"from obj should be forwarded"
);
assert
(
from_obj
->
is_forwarded
(),
"from obj should be forwarded"
);
assert
(
from_obj
->
forwardee
()
==
to_obj
,
"to obj should be the forwardee"
);
assert
(
from_obj
->
forwardee
()
==
to_obj
,
"to obj should be the forwardee"
);
...
@@ -4388,7 +4391,9 @@ void G1ParCopyHelper::mark_forwarded_object(oop from_obj, oop to_obj) {
...
@@ -4388,7 +4391,9 @@ void G1ParCopyHelper::mark_forwarded_object(oop from_obj, oop to_obj) {
_cm
->
grayRoot
(
to_obj
,
(
size_t
)
from_obj
->
size
(),
_worker_id
);
_cm
->
grayRoot
(
to_obj
,
(
size_t
)
from_obj
->
size
(),
_worker_id
);
}
}
oop
G1ParCopyHelper
::
copy_to_survivor_space
(
oop
old
)
{
template
<
bool
do_gen_barrier
,
G1Barrier
barrier
,
bool
do_mark_object
>
oop
G1ParCopyClosure
<
do_gen_barrier
,
barrier
,
do_mark_object
>
::
copy_to_survivor_space
(
oop
old
)
{
size_t
word_sz
=
old
->
size
();
size_t
word_sz
=
old
->
size
();
HeapRegion
*
from_region
=
_g1
->
heap_region_containing_raw
(
old
);
HeapRegion
*
from_region
=
_g1
->
heap_region_containing_raw
(
old
);
// +1 to make the -1 indexes valid...
// +1 to make the -1 indexes valid...
...
@@ -4457,8 +4462,8 @@ oop G1ParCopyHelper::copy_to_survivor_space(oop old) {
...
@@ -4457,8 +4462,8 @@ oop G1ParCopyHelper::copy_to_survivor_space(oop old) {
}
else
{
}
else
{
// No point in using the slower heap_region_containing() method,
// No point in using the slower heap_region_containing() method,
// given that we know obj is in the heap.
// given that we know obj is in the heap.
_scanner
->
set_region
(
_g1
->
heap_region_containing_raw
(
obj
));
_scanner
.
set_region
(
_g1
->
heap_region_containing_raw
(
obj
));
obj
->
oop_iterate_backwards
(
_scanner
);
obj
->
oop_iterate_backwards
(
&
_scanner
);
}
}
}
else
{
}
else
{
_par_scan_state
->
undo_allocation
(
alloc_purpose
,
obj_ptr
,
word_sz
);
_par_scan_state
->
undo_allocation
(
alloc_purpose
,
obj_ptr
,
word_sz
);
...
@@ -4675,67 +4680,74 @@ public:
...
@@ -4675,67 +4680,74 @@ public:
double
start_time_ms
=
os
::
elapsedTime
()
*
1000.0
;
double
start_time_ms
=
os
::
elapsedTime
()
*
1000.0
;
_g1h
->
g1_policy
()
->
record_gc_worker_start_time
(
worker_id
,
start_time_ms
);
_g1h
->
g1_policy
()
->
record_gc_worker_start_time
(
worker_id
,
start_time_ms
);
ResourceMark
rm
;
{
HandleMark
hm
;
ResourceMark
rm
;
HandleMark
hm
;
ReferenceProcessor
*
rp
=
_g1h
->
ref_processor_stw
();
ReferenceProcessor
*
rp
=
_g1h
->
ref_processor_stw
();
G1ParScanThreadState
pss
(
_g1h
,
worker_id
);
G1ParScanThreadState
pss
(
_g1h
,
worker_id
);
G1ParScanHeapEvacClosure
scan_evac_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanHeapEvacClosure
scan_evac_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanHeapEvacFailureClosure
evac_failure_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanHeapEvacFailureClosure
evac_failure_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanPartialArrayClosure
partial_scan_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanPartialArrayClosure
partial_scan_cl
(
_g1h
,
&
pss
,
rp
);
pss
.
set_evac_closure
(
&
scan_evac_cl
);
pss
.
set_evac_closure
(
&
scan_evac_cl
);
pss
.
set_evac_failure_closure
(
&
evac_failure_cl
);
pss
.
set_evac_failure_closure
(
&
evac_failure_cl
);
pss
.
set_partial_scan_closure
(
&
partial_scan_cl
);
pss
.
set_partial_scan_closure
(
&
partial_scan_cl
);
G1ParScanExtRootClosure
only_scan_root_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanExtRootClosure
only_scan_root_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanPermClosure
only_scan_perm_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanPermClosure
only_scan_perm_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanAndMarkExtRootClosure
scan_mark_root_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanAndMarkExtRootClosure
scan_mark_root_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanAndMarkPermClosure
scan_mark_perm_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanAndMarkPermClosure
scan_mark_perm_cl
(
_g1h
,
&
pss
,
rp
);
OopClosure
*
scan_root_cl
=
&
only_scan_root_cl
;
OopClosure
*
scan_root_cl
=
&
only_scan_root_cl
;
OopsInHeapRegionClosure
*
scan_perm_cl
=
&
only_scan_perm_cl
;
OopsInHeapRegionClosure
*
scan_perm_cl
=
&
only_scan_perm_cl
;
if
(
_g1h
->
g1_policy
()
->
during_initial_mark_pause
())
{
if
(
_g1h
->
g1_policy
()
->
during_initial_mark_pause
())
{
// We also need to mark copied objects.
// We also need to mark copied objects.
scan_root_cl
=
&
scan_mark_root_cl
;
scan_root_cl
=
&
scan_mark_root_cl
;
scan_perm_cl
=
&
scan_mark_perm_cl
;
scan_perm_cl
=
&
scan_mark_perm_cl
;
}
}
G1ParPushHeapRSClosure
push_heap_rs_cl
(
_g1h
,
&
pss
);
G1ParPushHeapRSClosure
push_heap_rs_cl
(
_g1h
,
&
pss
);
pss
.
start_strong_roots
();
pss
.
start_strong_roots
();
_g1h
->
g1_process_strong_roots
(
/* not collecting perm */
false
,
_g1h
->
g1_process_strong_roots
(
/* not collecting perm */
false
,
SharedHeap
::
SO_AllClasses
,
SharedHeap
::
SO_AllClasses
,
scan_root_cl
,
scan_root_cl
,
&
push_heap_rs_cl
,
&
push_heap_rs_cl
,
scan_perm_cl
,
scan_perm_cl
,
worker_id
);
worker_id
);
pss
.
end_strong_roots
();
pss
.
end_strong_roots
();
{
{
double
start
=
os
::
elapsedTime
();
double
start
=
os
::
elapsedTime
();
G1ParEvacuateFollowersClosure
evac
(
_g1h
,
&
pss
,
_queues
,
&
_terminator
);
G1ParEvacuateFollowersClosure
evac
(
_g1h
,
&
pss
,
_queues
,
&
_terminator
);
evac
.
do_void
();
evac
.
do_void
();
double
elapsed_ms
=
(
os
::
elapsedTime
()
-
start
)
*
1000.0
;
double
elapsed_ms
=
(
os
::
elapsedTime
()
-
start
)
*
1000.0
;
double
term_ms
=
pss
.
term_time
()
*
1000.0
;
double
term_ms
=
pss
.
term_time
()
*
1000.0
;
_g1h
->
g1_policy
()
->
record_obj_copy_time
(
worker_id
,
elapsed_ms
-
term_ms
);
_g1h
->
g1_policy
()
->
record_obj_copy_time
(
worker_id
,
elapsed_ms
-
term_ms
);
_g1h
->
g1_policy
()
->
record_termination
(
worker_id
,
term_ms
,
pss
.
term_attempts
());
_g1h
->
g1_policy
()
->
record_termination
(
worker_id
,
term_ms
,
pss
.
term_attempts
());
}
}
_g1h
->
g1_policy
()
->
record_thread_age_table
(
pss
.
age_table
());
_g1h
->
g1_policy
()
->
record_thread_age_table
(
pss
.
age_table
());
_g1h
->
update_surviving_young_words
(
pss
.
surviving_young_words
()
+
1
);
_g1h
->
update_surviving_young_words
(
pss
.
surviving_young_words
()
+
1
);
// Clean up any par-expanded rem sets.
// Clean up any par-expanded rem sets.
HeapRegionRemSet
::
par_cleanup
();
HeapRegionRemSet
::
par_cleanup
();
if
(
ParallelGCVerbose
)
{
if
(
ParallelGCVerbose
)
{
MutexLocker
x
(
stats_lock
());
MutexLocker
x
(
stats_lock
());
pss
.
print_termination_stats
(
worker_id
);
pss
.
print_termination_stats
(
worker_id
);
}
assert
(
pss
.
refs
()
->
is_empty
(),
"should be empty"
);
// Close the inner scope so that the ResourceMark and HandleMark
// destructors are executed here and are included as part of the
// "GC Worker Time".
}
}
assert
(
pss
.
refs
()
->
is_empty
(),
"should be empty"
);
double
end_time_ms
=
os
::
elapsedTime
()
*
1000.0
;
double
end_time_ms
=
os
::
elapsedTime
()
*
1000.0
;
_g1h
->
g1_policy
()
->
record_gc_worker_end_time
(
worker_id
,
end_time_ms
);
_g1h
->
g1_policy
()
->
record_gc_worker_end_time
(
worker_id
,
end_time_ms
);
}
}
...
@@ -4743,6 +4755,67 @@ public:
...
@@ -4743,6 +4755,67 @@ public:
// *** Common G1 Evacuation Stuff
// *** Common G1 Evacuation Stuff
// Closures that support the filtering of CodeBlobs scanned during
// external root scanning.
// Closure applied to reference fields in code blobs (specifically nmethods)
// to determine whether an nmethod contains references that point into
// the collection set. Used as a predicate when walking code roots so
// that only nmethods that point into the collection set are added to the
// 'marked' list.
class
G1FilteredCodeBlobToOopClosure
:
public
CodeBlobToOopClosure
{
class
G1PointsIntoCSOopClosure
:
public
OopClosure
{
G1CollectedHeap
*
_g1
;
bool
_points_into_cs
;
public:
G1PointsIntoCSOopClosure
(
G1CollectedHeap
*
g1
)
:
_g1
(
g1
),
_points_into_cs
(
false
)
{
}
bool
points_into_cs
()
const
{
return
_points_into_cs
;
}
template
<
class
T
>
void
do_oop_nv
(
T
*
p
)
{
if
(
!
_points_into_cs
)
{
T
heap_oop
=
oopDesc
::
load_heap_oop
(
p
);
if
(
!
oopDesc
::
is_null
(
heap_oop
)
&&
_g1
->
in_cset_fast_test
(
oopDesc
::
decode_heap_oop_not_null
(
heap_oop
)))
{
_points_into_cs
=
true
;
}
}
}
virtual
void
do_oop
(
oop
*
p
)
{
do_oop_nv
(
p
);
}
virtual
void
do_oop
(
narrowOop
*
p
)
{
do_oop_nv
(
p
);
}
};
G1CollectedHeap
*
_g1
;
public:
G1FilteredCodeBlobToOopClosure
(
G1CollectedHeap
*
g1
,
OopClosure
*
cl
)
:
CodeBlobToOopClosure
(
cl
,
true
),
_g1
(
g1
)
{
}
virtual
void
do_code_blob
(
CodeBlob
*
cb
)
{
nmethod
*
nm
=
cb
->
as_nmethod_or_null
();
if
(
nm
!=
NULL
&&
!
(
nm
->
test_oops_do_mark
()))
{
G1PointsIntoCSOopClosure
predicate_cl
(
_g1
);
nm
->
oops_do
(
&
predicate_cl
);
if
(
predicate_cl
.
points_into_cs
())
{
// At least one of the reference fields or the oop relocations
// in the nmethod points into the collection set. We have to
// 'mark' this nmethod.
// Note: Revisit the following if CodeBlobToOopClosure::do_code_blob()
// or MarkingCodeBlobClosure::do_code_blob() change.
if
(
!
nm
->
test_set_oops_do_mark
())
{
do_newly_marked_nmethod
(
nm
);
}
}
}
}
};
// This method is run in a GC worker.
// This method is run in a GC worker.
void
void
...
@@ -4764,7 +4837,7 @@ g1_process_strong_roots(bool collecting_perm_gen,
...
@@ -4764,7 +4837,7 @@ g1_process_strong_roots(bool collecting_perm_gen,
// Walk the code cache w/o buffering, because StarTask cannot handle
// Walk the code cache w/o buffering, because StarTask cannot handle
// unaligned oop locations.
// unaligned oop locations.
CodeBlobToOopClosure
eager_scan_code_roots
(
scan_non_heap_roots
,
/*do_marking=*/
true
);
G1FilteredCodeBlobToOopClosure
eager_scan_code_roots
(
this
,
scan_non_heap_roots
);
process_strong_roots
(
false
,
// no scoping; this is parallel code
process_strong_roots
(
false
,
// no scoping; this is parallel code
collecting_perm_gen
,
so
,
collecting_perm_gen
,
so
,
...
@@ -5378,25 +5451,39 @@ void G1CollectedHeap::evacuate_collection_set() {
...
@@ -5378,25 +5451,39 @@ void G1CollectedHeap::evacuate_collection_set() {
rem_set
()
->
prepare_for_younger_refs_iterate
(
true
);
rem_set
()
->
prepare_for_younger_refs_iterate
(
true
);
assert
(
dirty_card_queue_set
().
completed_buffers_num
()
==
0
,
"Should be empty"
);
assert
(
dirty_card_queue_set
().
completed_buffers_num
()
==
0
,
"Should be empty"
);
double
start_par
=
os
::
elapsedTime
();
double
start_par_time_sec
=
os
::
elapsedTime
();
double
end_par_time_sec
;
if
(
G1CollectedHeap
::
use_parallel_gc_threads
())
{
{
// The individual threads will set their evac-failure closures.
StrongRootsScope
srs
(
this
);
if
(
ParallelGCVerbose
)
G1ParScanThreadState
::
print_termination_stats_hdr
();
// These tasks use ShareHeap::_process_strong_tasks
assert
(
UseDynamicNumberOfGCThreads
||
workers
()
->
active_workers
()
==
workers
()
->
total_workers
(),
"If not dynamic should be using all the workers"
);
workers
()
->
run_task
(
&
g1_par_task
);
}
else
{
StrongRootsScope
srs
(
this
);
StrongRootsScope
srs
(
this
);
g1_par_task
.
set_for_termination
(
n_workers
);
g1_par_task
.
work
(
0
);
if
(
G1CollectedHeap
::
use_parallel_gc_threads
())
{
// The individual threads will set their evac-failure closures.
if
(
ParallelGCVerbose
)
G1ParScanThreadState
::
print_termination_stats_hdr
();
// These tasks use ShareHeap::_process_strong_tasks
assert
(
UseDynamicNumberOfGCThreads
||
workers
()
->
active_workers
()
==
workers
()
->
total_workers
(),
"If not dynamic should be using all the workers"
);
workers
()
->
run_task
(
&
g1_par_task
);
}
else
{
g1_par_task
.
set_for_termination
(
n_workers
);
g1_par_task
.
work
(
0
);
}
end_par_time_sec
=
os
::
elapsedTime
();
// Closing the inner scope will execute the destructor
// for the StrongRootsScope object. We record the current
// elapsed time before closing the scope so that time
// taken for the SRS destructor is NOT included in the
// reported parallel time.
}
}
double
par_time
=
(
os
::
elapsedTime
()
-
start_par
)
*
1000.0
;
double
par_time_ms
=
(
end_par_time_sec
-
start_par_time_sec
)
*
1000.0
;
g1_policy
()
->
record_par_time
(
par_time
);
g1_policy
()
->
record_par_time
(
par_time_ms
);
double
code_root_fixup_time_ms
=
(
os
::
elapsedTime
()
-
end_par_time_sec
)
*
1000.0
;
g1_policy
()
->
record_code_root_fixup_time
(
code_root_fixup_time_ms
);
set_par_threads
(
0
);
set_par_threads
(
0
);
...
...
src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
浏览文件 @
05d15943
...
@@ -199,7 +199,8 @@ class G1CollectedHeap : public SharedHeap {
...
@@ -199,7 +199,8 @@ class G1CollectedHeap : public SharedHeap {
friend
class
OldGCAllocRegion
;
friend
class
OldGCAllocRegion
;
// Closures used in implementation.
// Closures used in implementation.
friend
class
G1ParCopyHelper
;
template
<
bool
do_gen_barrier
,
G1Barrier
barrier
,
bool
do_mark_object
>
friend
class
G1ParCopyClosure
;
friend
class
G1IsAliveClosure
;
friend
class
G1IsAliveClosure
;
friend
class
G1EvacuateFollowersClosure
;
friend
class
G1EvacuateFollowersClosure
;
friend
class
G1ParScanThreadState
;
friend
class
G1ParScanThreadState
;
...
@@ -1676,202 +1677,6 @@ protected:
...
@@ -1676,202 +1677,6 @@ protected:
size_t
_max_heap_capacity
;
size_t
_max_heap_capacity
;
};
};
#define use_local_bitmaps 1
#define verify_local_bitmaps 0
#define oop_buffer_length 256
#ifndef PRODUCT
class
GCLabBitMap
;
class
GCLabBitMapClosure
:
public
BitMapClosure
{
private:
ConcurrentMark
*
_cm
;
GCLabBitMap
*
_bitmap
;
public:
GCLabBitMapClosure
(
ConcurrentMark
*
cm
,
GCLabBitMap
*
bitmap
)
{
_cm
=
cm
;
_bitmap
=
bitmap
;
}
virtual
bool
do_bit
(
size_t
offset
);
};
#endif // !PRODUCT
class
GCLabBitMap
:
public
BitMap
{
private:
ConcurrentMark
*
_cm
;
int
_shifter
;
size_t
_bitmap_word_covers_words
;
// beginning of the heap
HeapWord
*
_heap_start
;
// this is the actual start of the GCLab
HeapWord
*
_real_start_word
;
// this is the actual end of the GCLab
HeapWord
*
_real_end_word
;
// this is the first word, possibly located before the actual start
// of the GCLab, that corresponds to the first bit of the bitmap
HeapWord
*
_start_word
;
// size of a GCLab in words
size_t
_gclab_word_size
;
static
int
shifter
()
{
return
MinObjAlignment
-
1
;
}
// how many heap words does a single bitmap word corresponds to?
static
size_t
bitmap_word_covers_words
()
{
return
BitsPerWord
<<
shifter
();
}
size_t
gclab_word_size
()
const
{
return
_gclab_word_size
;
}
// Calculates actual GCLab size in words
size_t
gclab_real_word_size
()
const
{
return
bitmap_size_in_bits
(
pointer_delta
(
_real_end_word
,
_start_word
))
/
BitsPerWord
;
}
static
size_t
bitmap_size_in_bits
(
size_t
gclab_word_size
)
{
size_t
bits_in_bitmap
=
gclab_word_size
>>
shifter
();
// We are going to ensure that the beginning of a word in this
// bitmap also corresponds to the beginning of a word in the
// global marking bitmap. To handle the case where a GCLab
// starts from the middle of the bitmap, we need to add enough
// space (i.e. up to a bitmap word) to ensure that we have
// enough bits in the bitmap.
return
bits_in_bitmap
+
BitsPerWord
-
1
;
}
public:
GCLabBitMap
(
HeapWord
*
heap_start
,
size_t
gclab_word_size
)
:
BitMap
(
bitmap_size_in_bits
(
gclab_word_size
)),
_cm
(
G1CollectedHeap
::
heap
()
->
concurrent_mark
()),
_shifter
(
shifter
()),
_bitmap_word_covers_words
(
bitmap_word_covers_words
()),
_heap_start
(
heap_start
),
_gclab_word_size
(
gclab_word_size
),
_real_start_word
(
NULL
),
_real_end_word
(
NULL
),
_start_word
(
NULL
)
{
guarantee
(
false
,
"GCLabBitMap::GCLabBitmap(): don't call this any more"
);
}
inline
unsigned
heapWordToOffset
(
HeapWord
*
addr
)
{
unsigned
offset
=
(
unsigned
)
pointer_delta
(
addr
,
_start_word
)
>>
_shifter
;
assert
(
offset
<
size
(),
"offset should be within bounds"
);
return
offset
;
}
inline
HeapWord
*
offsetToHeapWord
(
size_t
offset
)
{
HeapWord
*
addr
=
_start_word
+
(
offset
<<
_shifter
);
assert
(
_real_start_word
<=
addr
&&
addr
<
_real_end_word
,
"invariant"
);
return
addr
;
}
bool
fields_well_formed
()
{
bool
ret1
=
(
_real_start_word
==
NULL
)
&&
(
_real_end_word
==
NULL
)
&&
(
_start_word
==
NULL
);
if
(
ret1
)
return
true
;
bool
ret2
=
_real_start_word
>=
_start_word
&&
_start_word
<
_real_end_word
&&
(
_real_start_word
+
_gclab_word_size
)
==
_real_end_word
&&
(
_start_word
+
_gclab_word_size
+
_bitmap_word_covers_words
)
>
_real_end_word
;
return
ret2
;
}
inline
bool
mark
(
HeapWord
*
addr
)
{
guarantee
(
use_local_bitmaps
,
"invariant"
);
assert
(
fields_well_formed
(),
"invariant"
);
if
(
addr
>=
_real_start_word
&&
addr
<
_real_end_word
)
{
assert
(
!
isMarked
(
addr
),
"should not have already been marked"
);
// first mark it on the bitmap
at_put
(
heapWordToOffset
(
addr
),
true
);
return
true
;
}
else
{
return
false
;
}
}
inline
bool
isMarked
(
HeapWord
*
addr
)
{
guarantee
(
use_local_bitmaps
,
"invariant"
);
assert
(
fields_well_formed
(),
"invariant"
);
return
at
(
heapWordToOffset
(
addr
));
}
void
set_buffer
(
HeapWord
*
start
)
{
guarantee
(
false
,
"set_buffer(): don't call this any more"
);
guarantee
(
use_local_bitmaps
,
"invariant"
);
clear
();
assert
(
start
!=
NULL
,
"invariant"
);
_real_start_word
=
start
;
_real_end_word
=
start
+
_gclab_word_size
;
size_t
diff
=
pointer_delta
(
start
,
_heap_start
)
%
_bitmap_word_covers_words
;
_start_word
=
start
-
diff
;
assert
(
fields_well_formed
(),
"invariant"
);
}
#ifndef PRODUCT
void
verify
()
{
// verify that the marks have been propagated
GCLabBitMapClosure
cl
(
_cm
,
this
);
iterate
(
&
cl
);
}
#endif // PRODUCT
void
retire
()
{
guarantee
(
false
,
"retire(): don't call this any more"
);
guarantee
(
use_local_bitmaps
,
"invariant"
);
assert
(
fields_well_formed
(),
"invariant"
);
if
(
_start_word
!=
NULL
)
{
CMBitMap
*
mark_bitmap
=
_cm
->
nextMarkBitMap
();
// this means that the bitmap was set up for the GCLab
assert
(
_real_start_word
!=
NULL
&&
_real_end_word
!=
NULL
,
"invariant"
);
mark_bitmap
->
mostly_disjoint_range_union
(
this
,
0
,
// always start from the start of the bitmap
_start_word
,
gclab_real_word_size
());
_cm
->
grayRegionIfNecessary
(
MemRegion
(
_real_start_word
,
_real_end_word
));
#ifndef PRODUCT
if
(
use_local_bitmaps
&&
verify_local_bitmaps
)
verify
();
#endif // PRODUCT
}
else
{
assert
(
_real_start_word
==
NULL
&&
_real_end_word
==
NULL
,
"invariant"
);
}
}
size_t
bitmap_size_in_words
()
const
{
return
(
bitmap_size_in_bits
(
gclab_word_size
())
+
BitsPerWord
-
1
)
/
BitsPerWord
;
}
};
class
G1ParGCAllocBuffer
:
public
ParGCAllocBuffer
{
class
G1ParGCAllocBuffer
:
public
ParGCAllocBuffer
{
private:
private:
bool
_retired
;
bool
_retired
;
...
...
src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
浏览文件 @
05d15943
...
@@ -140,7 +140,6 @@ G1CollectorPolicy::G1CollectorPolicy() :
...
@@ -140,7 +140,6 @@ G1CollectorPolicy::G1CollectorPolicy() :
_summary
(
new
Summary
()),
_summary
(
new
Summary
()),
_cur_clear_ct_time_ms
(
0.0
),
_cur_clear_ct_time_ms
(
0.0
),
_mark_closure_time_ms
(
0.0
),
_root_region_scan_wait_time_ms
(
0.0
),
_root_region_scan_wait_time_ms
(
0.0
),
_cur_ref_proc_time_ms
(
0.0
),
_cur_ref_proc_time_ms
(
0.0
),
...
@@ -944,9 +943,6 @@ void G1CollectorPolicy::record_collection_pause_start(double start_time_sec,
...
@@ -944,9 +943,6 @@ void G1CollectorPolicy::record_collection_pause_start(double start_time_sec,
_cur_aux_times_set
[
i
]
=
false
;
_cur_aux_times_set
[
i
]
=
false
;
}
}
// This is initialized to zero here and is set during
// the evacuation pause if marking is in progress.
_cur_satb_drain_time_ms
=
0.0
;
// This is initialized to zero here and is set during the evacuation
// This is initialized to zero here and is set during the evacuation
// pause if we actually waited for the root region scanning to finish.
// pause if we actually waited for the root region scanning to finish.
_root_region_scan_wait_time_ms
=
0.0
;
_root_region_scan_wait_time_ms
=
0.0
;
...
@@ -1246,11 +1242,6 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
...
@@ -1246,11 +1242,6 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
double
other_time_ms
=
elapsed_ms
;
double
other_time_ms
=
elapsed_ms
;
// Subtract the SATB drain time. It's initialized to zero at the
// start of the pause and is updated during the pause if marking
// is in progress.
other_time_ms
-=
_cur_satb_drain_time_ms
;
// Subtract the root region scanning wait time. It's initialized to
// Subtract the root region scanning wait time. It's initialized to
// zero at the start of the pause.
// zero at the start of the pause.
other_time_ms
-=
_root_region_scan_wait_time_ms
;
other_time_ms
-=
_root_region_scan_wait_time_ms
;
...
@@ -1261,15 +1252,13 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
...
@@ -1261,15 +1252,13 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
other_time_ms
-=
known_time
;
other_time_ms
-=
known_time
;
}
}
// Now subtract the time taken to fix up roots in generated code
other_time_ms
-=
_cur_collection_code_root_fixup_time_ms
;
// Subtract the time taken to clean the card table from the
// Subtract the time taken to clean the card table from the
// current value of "other time"
// current value of "other time"
other_time_ms
-=
_cur_clear_ct_time_ms
;
other_time_ms
-=
_cur_clear_ct_time_ms
;
// Subtract the time spent completing marking in the collection
// set. Note if marking is not in progress during the pause
// the value of _mark_closure_time_ms will be zero.
other_time_ms
-=
_mark_closure_time_ms
;
// TraceGen0Time and TraceGen1Time summary info updating.
// TraceGen0Time and TraceGen1Time summary info updating.
_all_pause_times_ms
->
add
(
elapsed_ms
);
_all_pause_times_ms
->
add
(
elapsed_ms
);
...
@@ -1280,16 +1269,8 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
...
@@ -1280,16 +1269,8 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
MainBodySummary
*
body_summary
=
_summary
->
main_body_summary
();
MainBodySummary
*
body_summary
=
_summary
->
main_body_summary
();
assert
(
body_summary
!=
NULL
,
"should not be null!"
);
assert
(
body_summary
!=
NULL
,
"should not be null!"
);
// This will be non-zero iff marking is currently in progress (i.e.
// _g1->mark_in_progress() == true) and the currrent pause was not
// an initial mark pause. Since the body_summary items are NumberSeqs,
// however, they have to be consistent and updated in lock-step with
// each other. Therefore we unconditionally record the SATB drain
// time - even if it's zero.
body_summary
->
record_satb_drain_time_ms
(
_cur_satb_drain_time_ms
);
body_summary
->
record_root_region_scan_wait_time_ms
(
body_summary
->
record_root_region_scan_wait_time_ms
(
_root_region_scan_wait_time_ms
);
_root_region_scan_wait_time_ms
);
body_summary
->
record_ext_root_scan_time_ms
(
ext_root_scan_time
);
body_summary
->
record_ext_root_scan_time_ms
(
ext_root_scan_time
);
body_summary
->
record_satb_filtering_time_ms
(
satb_filtering_time
);
body_summary
->
record_satb_filtering_time_ms
(
satb_filtering_time
);
body_summary
->
record_update_rs_time_ms
(
update_rs_time
);
body_summary
->
record_update_rs_time_ms
(
update_rs_time
);
...
@@ -1305,7 +1286,6 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
...
@@ -1305,7 +1286,6 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
body_summary
->
record_parallel_other_time_ms
(
parallel_other_time
);
body_summary
->
record_parallel_other_time_ms
(
parallel_other_time
);
}
}
body_summary
->
record_mark_closure_time_ms
(
_mark_closure_time_ms
);
body_summary
->
record_clear_ct_time_ms
(
_cur_clear_ct_time_ms
);
body_summary
->
record_clear_ct_time_ms
(
_cur_clear_ct_time_ms
);
// We exempt parallel collection from this check because Alloc Buffer
// We exempt parallel collection from this check because Alloc Buffer
...
@@ -1401,10 +1381,10 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
...
@@ -1401,10 +1381,10 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
print_par_stats
(
2
,
"Object Copy"
,
_par_last_obj_copy_times_ms
);
print_par_stats
(
2
,
"Object Copy"
,
_par_last_obj_copy_times_ms
);
print_par_stats
(
2
,
"Termination"
,
_par_last_termination_times_ms
);
print_par_stats
(
2
,
"Termination"
,
_par_last_termination_times_ms
);
print_par_sizes
(
3
,
"Termination Attempts"
,
_par_last_termination_attempts
);
print_par_sizes
(
3
,
"Termination Attempts"
,
_par_last_termination_attempts
);
print_par_stats
(
2
,
"GC Worker End"
,
_par_last_gc_worker_end_times_ms
);
for
(
int
i
=
0
;
i
<
_parallel_gc_threads
;
i
++
)
{
for
(
int
i
=
0
;
i
<
_parallel_gc_threads
;
i
++
)
{
_par_last_gc_worker_times_ms
[
i
]
=
_par_last_gc_worker_end_times_ms
[
i
]
-
_par_last_gc_worker_start_times_ms
[
i
];
_par_last_gc_worker_times_ms
[
i
]
=
_par_last_gc_worker_end_times_ms
[
i
]
-
_par_last_gc_worker_start_times_ms
[
i
];
double
worker_known_time
=
_par_last_ext_root_scan_times_ms
[
i
]
+
double
worker_known_time
=
_par_last_ext_root_scan_times_ms
[
i
]
+
_par_last_satb_filtering_times_ms
[
i
]
+
_par_last_satb_filtering_times_ms
[
i
]
+
...
@@ -1413,10 +1393,13 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
...
@@ -1413,10 +1393,13 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
_par_last_obj_copy_times_ms
[
i
]
+
_par_last_obj_copy_times_ms
[
i
]
+
_par_last_termination_times_ms
[
i
];
_par_last_termination_times_ms
[
i
];
_par_last_gc_worker_other_times_ms
[
i
]
=
_cur_collection_par_time_ms
-
worker_known_time
;
_par_last_gc_worker_other_times_ms
[
i
]
=
_par_last_gc_worker_times_ms
[
i
]
-
worker_known_time
;
}
}
print_par_stats
(
2
,
"GC Worker"
,
_par_last_gc_worker_times_ms
);
print_par_stats
(
2
,
"GC Worker Other"
,
_par_last_gc_worker_other_times_ms
);
print_par_stats
(
2
,
"GC Worker Other"
,
_par_last_gc_worker_other_times_ms
);
print_par_stats
(
2
,
"GC Worker Total"
,
_par_last_gc_worker_times_ms
);
print_par_stats
(
2
,
"GC Worker End"
,
_par_last_gc_worker_end_times_ms
);
}
else
{
}
else
{
print_stats
(
1
,
"Ext Root Scanning"
,
ext_root_scan_time
);
print_stats
(
1
,
"Ext Root Scanning"
,
ext_root_scan_time
);
if
(
print_marking_info
)
{
if
(
print_marking_info
)
{
...
@@ -1427,9 +1410,7 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
...
@@ -1427,9 +1410,7 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
print_stats
(
1
,
"Scan RS"
,
scan_rs_time
);
print_stats
(
1
,
"Scan RS"
,
scan_rs_time
);
print_stats
(
1
,
"Object Copying"
,
obj_copy_time
);
print_stats
(
1
,
"Object Copying"
,
obj_copy_time
);
}
}
if
(
print_marking_info
)
{
print_stats
(
1
,
"Code Root Fixup"
,
_cur_collection_code_root_fixup_time_ms
);
print_stats
(
1
,
"Complete CSet Marking"
,
_mark_closure_time_ms
);
}
print_stats
(
1
,
"Clear CT"
,
_cur_clear_ct_time_ms
);
print_stats
(
1
,
"Clear CT"
,
_cur_clear_ct_time_ms
);
#ifndef PRODUCT
#ifndef PRODUCT
print_stats
(
1
,
"Cur Clear CC"
,
_cur_clear_cc_time_ms
);
print_stats
(
1
,
"Cur Clear CC"
,
_cur_clear_cc_time_ms
);
...
@@ -1577,8 +1558,7 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
...
@@ -1577,8 +1558,7 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
}
}
double
all_other_time_ms
=
pause_time_ms
-
double
all_other_time_ms
=
pause_time_ms
-
(
update_rs_time
+
scan_rs_time
+
obj_copy_time
+
(
update_rs_time
+
scan_rs_time
+
obj_copy_time
+
termination_time
);
_mark_closure_time_ms
+
termination_time
);
double
young_other_time_ms
=
0.0
;
double
young_other_time_ms
=
0.0
;
if
(
young_cset_region_length
()
>
0
)
{
if
(
young_cset_region_length
()
>
0
)
{
...
@@ -1705,41 +1685,6 @@ void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time,
...
@@ -1705,41 +1685,6 @@ void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time,
dcqs
.
notify_if_necessary
();
dcqs
.
notify_if_necessary
();
}
}
double
G1CollectorPolicy
::
predict_young_collection_elapsed_time_ms
(
size_t
adjustment
)
{
guarantee
(
adjustment
==
0
||
adjustment
==
1
,
"invariant"
);
G1CollectedHeap
*
g1h
=
G1CollectedHeap
::
heap
();
size_t
young_num
=
g1h
->
young_list
()
->
length
();
if
(
young_num
==
0
)
return
0.0
;
young_num
+=
adjustment
;
size_t
pending_cards
=
predict_pending_cards
();
size_t
rs_lengths
=
g1h
->
young_list
()
->
sampled_rs_lengths
()
+
predict_rs_length_diff
();
size_t
card_num
;
if
(
gcs_are_young
())
{
card_num
=
predict_young_card_num
(
rs_lengths
);
}
else
{
card_num
=
predict_non_young_card_num
(
rs_lengths
);
}
size_t
young_byte_size
=
young_num
*
HeapRegion
::
GrainBytes
;
double
accum_yg_surv_rate
=
_short_lived_surv_rate_group
->
accum_surv_rate
(
adjustment
);
size_t
bytes_to_copy
=
(
size_t
)
(
accum_yg_surv_rate
*
(
double
)
HeapRegion
::
GrainBytes
);
return
predict_rs_update_time_ms
(
pending_cards
)
+
predict_rs_scan_time_ms
(
card_num
)
+
predict_object_copy_time_ms
(
bytes_to_copy
)
+
predict_young_other_time_ms
(
young_num
)
+
predict_constant_other_time_ms
();
}
double
double
G1CollectorPolicy
::
predict_base_elapsed_time_ms
(
size_t
pending_cards
)
{
G1CollectorPolicy
::
predict_base_elapsed_time_ms
(
size_t
pending_cards
)
{
size_t
rs_length
=
predict_rs_length_diff
();
size_t
rs_length
=
predict_rs_length_diff
();
...
@@ -1973,7 +1918,6 @@ void G1CollectorPolicy::print_summary(PauseSummary* summary) const {
...
@@ -1973,7 +1918,6 @@ void G1CollectorPolicy::print_summary(PauseSummary* summary) const {
print_summary
(
1
,
"Object Copy"
,
body_summary
->
get_obj_copy_seq
());
print_summary
(
1
,
"Object Copy"
,
body_summary
->
get_obj_copy_seq
());
}
}
}
}
print_summary
(
1
,
"Mark Closure"
,
body_summary
->
get_mark_closure_seq
());
print_summary
(
1
,
"Clear CT"
,
body_summary
->
get_clear_ct_seq
());
print_summary
(
1
,
"Clear CT"
,
body_summary
->
get_clear_ct_seq
());
print_summary
(
1
,
"Other"
,
summary
->
get_other_seq
());
print_summary
(
1
,
"Other"
,
summary
->
get_other_seq
());
{
{
...
@@ -1982,17 +1926,15 @@ void G1CollectorPolicy::print_summary(PauseSummary* summary) const {
...
@@ -1982,17 +1926,15 @@ void G1CollectorPolicy::print_summary(PauseSummary* summary) const {
if
(
parallel
)
{
if
(
parallel
)
{
// parallel
// parallel
NumberSeq
*
other_parts
[]
=
{
NumberSeq
*
other_parts
[]
=
{
body_summary
->
get_satb_drain_seq
(),
body_summary
->
get_root_region_scan_wait_seq
(),
body_summary
->
get_root_region_scan_wait_seq
(),
body_summary
->
get_parallel_seq
(),
body_summary
->
get_parallel_seq
(),
body_summary
->
get_clear_ct_seq
()
body_summary
->
get_clear_ct_seq
()
};
};
calc_other_times_ms
=
NumberSeq
(
summary
->
get_total_seq
(),
calc_other_times_ms
=
NumberSeq
(
summary
->
get_total_seq
(),
4
,
other_parts
);
3
,
other_parts
);
}
else
{
}
else
{
// serial
// serial
NumberSeq
*
other_parts
[]
=
{
NumberSeq
*
other_parts
[]
=
{
body_summary
->
get_satb_drain_seq
(),
body_summary
->
get_root_region_scan_wait_seq
(),
body_summary
->
get_root_region_scan_wait_seq
(),
body_summary
->
get_update_rs_seq
(),
body_summary
->
get_update_rs_seq
(),
body_summary
->
get_ext_root_scan_seq
(),
body_summary
->
get_ext_root_scan_seq
(),
...
@@ -2001,7 +1943,7 @@ void G1CollectorPolicy::print_summary(PauseSummary* summary) const {
...
@@ -2001,7 +1943,7 @@ void G1CollectorPolicy::print_summary(PauseSummary* summary) const {
body_summary
->
get_obj_copy_seq
()
body_summary
->
get_obj_copy_seq
()
};
};
calc_other_times_ms
=
NumberSeq
(
summary
->
get_total_seq
(),
calc_other_times_ms
=
NumberSeq
(
summary
->
get_total_seq
(),
7
,
other_parts
);
6
,
other_parts
);
}
}
check_other_times
(
1
,
summary
->
get_other_seq
(),
&
calc_other_times_ms
);
check_other_times
(
1
,
summary
->
get_other_seq
(),
&
calc_other_times_ms
);
}
}
...
...
src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
浏览文件 @
05d15943
...
@@ -64,7 +64,6 @@ public:
...
@@ -64,7 +64,6 @@ public:
};
};
class
MainBodySummary
:
public
CHeapObj
{
class
MainBodySummary
:
public
CHeapObj
{
define_num_seq
(
satb_drain
)
// optional
define_num_seq
(
root_region_scan_wait
)
define_num_seq
(
root_region_scan_wait
)
define_num_seq
(
parallel
)
// parallel only
define_num_seq
(
parallel
)
// parallel only
define_num_seq
(
ext_root_scan
)
define_num_seq
(
ext_root_scan
)
...
@@ -74,7 +73,6 @@ class MainBodySummary: public CHeapObj {
...
@@ -74,7 +73,6 @@ class MainBodySummary: public CHeapObj {
define_num_seq
(
obj_copy
)
define_num_seq
(
obj_copy
)
define_num_seq
(
termination
)
// parallel only
define_num_seq
(
termination
)
// parallel only
define_num_seq
(
parallel_other
)
// parallel only
define_num_seq
(
parallel_other
)
// parallel only
define_num_seq
(
mark_closure
)
define_num_seq
(
clear_ct
)
define_num_seq
(
clear_ct
)
};
};
...
@@ -179,7 +177,9 @@ private:
...
@@ -179,7 +177,9 @@ private:
size_t
_cur_collection_pause_used_at_start_bytes
;
size_t
_cur_collection_pause_used_at_start_bytes
;
size_t
_cur_collection_pause_used_regions_at_start
;
size_t
_cur_collection_pause_used_regions_at_start
;
double
_cur_collection_par_time_ms
;
double
_cur_collection_par_time_ms
;
double
_cur_satb_drain_time_ms
;
double
_cur_collection_code_root_fixup_time_ms
;
double
_cur_clear_ct_time_ms
;
double
_cur_clear_ct_time_ms
;
double
_cur_ref_proc_time_ms
;
double
_cur_ref_proc_time_ms
;
double
_cur_ref_enq_time_ms
;
double
_cur_ref_enq_time_ms
;
...
@@ -226,8 +226,8 @@ private:
...
@@ -226,8 +226,8 @@ private:
double
*
_par_last_gc_worker_times_ms
;
double
*
_par_last_gc_worker_times_ms
;
// Each workers 'other' time i.e. the elapsed time of the parallel
// Each workers 'other' time i.e. the elapsed time of the parallel
//
phase of the pause
minus the sum of the individual sub-phase
//
code executed by a worker
minus the sum of the individual sub-phase
// times for
a given
worker thread.
// times for
that
worker thread.
double
*
_par_last_gc_worker_other_times_ms
;
double
*
_par_last_gc_worker_other_times_ms
;
// indicates whether we are in young or mixed GC mode
// indicates whether we are in young or mixed GC mode
...
@@ -488,7 +488,6 @@ public:
...
@@ -488,7 +488,6 @@ public:
get_new_prediction
(
_non_young_other_cost_per_region_ms_seq
);
get_new_prediction
(
_non_young_other_cost_per_region_ms_seq
);
}
}
double
predict_young_collection_elapsed_time_ms
(
size_t
adjustment
);
double
predict_base_elapsed_time_ms
(
size_t
pending_cards
);
double
predict_base_elapsed_time_ms
(
size_t
pending_cards
);
double
predict_base_elapsed_time_ms
(
size_t
pending_cards
,
double
predict_base_elapsed_time_ms
(
size_t
pending_cards
,
size_t
scanned_cards
);
size_t
scanned_cards
);
...
@@ -709,7 +708,6 @@ private:
...
@@ -709,7 +708,6 @@ private:
double
_cur_mark_stop_world_time_ms
;
double
_cur_mark_stop_world_time_ms
;
double
_mark_remark_start_sec
;
double
_mark_remark_start_sec
;
double
_mark_cleanup_start_sec
;
double
_mark_cleanup_start_sec
;
double
_mark_closure_time_ms
;
double
_root_region_scan_wait_time_ms
;
double
_root_region_scan_wait_time_ms
;
// Update the young list target length either by setting it to the
// Update the young list target length either by setting it to the
...
@@ -809,10 +807,6 @@ public:
...
@@ -809,10 +807,6 @@ public:
void
record_concurrent_mark_init_end
(
double
void
record_concurrent_mark_init_end
(
double
mark_init_elapsed_time_ms
);
mark_init_elapsed_time_ms
);
void
record_mark_closure_time
(
double
mark_closure_time_ms
)
{
_mark_closure_time_ms
=
mark_closure_time_ms
;
}
void
record_root_region_scan_wait_time
(
double
time_ms
)
{
void
record_root_region_scan_wait_time
(
double
time_ms
)
{
_root_region_scan_wait_time_ms
=
time_ms
;
_root_region_scan_wait_time_ms
=
time_ms
;
}
}
...
@@ -846,11 +840,6 @@ public:
...
@@ -846,11 +840,6 @@ public:
_par_last_satb_filtering_times_ms
[
worker_i
]
=
ms
;
_par_last_satb_filtering_times_ms
[
worker_i
]
=
ms
;
}
}
void
record_satb_drain_time
(
double
ms
)
{
assert
(
_g1
->
mark_in_progress
(),
"shouldn't be here otherwise"
);
_cur_satb_drain_time_ms
=
ms
;
}
void
record_update_rs_time
(
int
thread
,
double
ms
)
{
void
record_update_rs_time
(
int
thread
,
double
ms
)
{
_par_last_update_rs_times_ms
[
thread
]
=
ms
;
_par_last_update_rs_times_ms
[
thread
]
=
ms
;
}
}
...
@@ -897,6 +886,10 @@ public:
...
@@ -897,6 +886,10 @@ public:
_cur_collection_par_time_ms
=
ms
;
_cur_collection_par_time_ms
=
ms
;
}
}
void
record_code_root_fixup_time
(
double
ms
)
{
_cur_collection_code_root_fixup_time_ms
=
ms
;
}
void
record_aux_start_time
(
int
i
)
{
void
record_aux_start_time
(
int
i
)
{
guarantee
(
i
<
_aux_num
,
"should be within range"
);
guarantee
(
i
<
_aux_num
,
"should be within range"
);
_cur_aux_start_times_ms
[
i
]
=
os
::
elapsedTime
()
*
1000.0
;
_cur_aux_start_times_ms
[
i
]
=
os
::
elapsedTime
()
*
1000.0
;
...
...
src/share/vm/gc_implementation/g1/g1OopClosures.hpp
浏览文件 @
05d15943
...
@@ -118,9 +118,11 @@ public:
...
@@ -118,9 +118,11 @@ public:
virtual
void
do_oop
(
narrowOop
*
p
)
{
do_oop_nv
(
p
);
}
virtual
void
do_oop
(
narrowOop
*
p
)
{
do_oop_nv
(
p
);
}
};
};
template
<
bool
do_gen_barrier
,
G1Barrier
barrier
,
bool
do_mark_object
>
class
G1ParCopyClosure
:
public
G1ParClosureSuper
{
G1ParScanClosure
_scanner
;
template
<
class
T
>
void
do_oop_work
(
T
*
p
);
class
G1ParCopyHelper
:
public
G1ParClosureSuper
{
G1ParScanClosure
*
_scanner
;
protected:
protected:
// Mark the object if it's not already marked. This is used to mark
// Mark the object if it's not already marked. This is used to mark
// objects pointed to by roots that are guaranteed not to move
// objects pointed to by roots that are guaranteed not to move
...
@@ -134,23 +136,11 @@ protected:
...
@@ -134,23 +136,11 @@ protected:
oop
copy_to_survivor_space
(
oop
obj
);
oop
copy_to_survivor_space
(
oop
obj
);
public:
G1ParCopyHelper
(
G1CollectedHeap
*
g1
,
G1ParScanThreadState
*
par_scan_state
,
G1ParScanClosure
*
scanner
)
:
G1ParClosureSuper
(
g1
,
par_scan_state
),
_scanner
(
scanner
)
{
}
};
template
<
bool
do_gen_barrier
,
G1Barrier
barrier
,
bool
do_mark_object
>
class
G1ParCopyClosure
:
public
G1ParCopyHelper
{
G1ParScanClosure
_scanner
;
template
<
class
T
>
void
do_oop_work
(
T
*
p
);
public:
public:
G1ParCopyClosure
(
G1CollectedHeap
*
g1
,
G1ParScanThreadState
*
par_scan_state
,
G1ParCopyClosure
(
G1CollectedHeap
*
g1
,
G1ParScanThreadState
*
par_scan_state
,
ReferenceProcessor
*
rp
)
:
ReferenceProcessor
*
rp
)
:
_scanner
(
g1
,
par_scan_state
,
rp
),
_scanner
(
g1
,
par_scan_state
,
rp
),
G1ParC
opyHelper
(
g1
,
par_scan_state
,
&
_scanner
)
{
G1ParC
losureSuper
(
g1
,
par_scan_state
)
{
assert
(
_ref_processor
==
NULL
,
"sanity"
);
assert
(
_ref_processor
==
NULL
,
"sanity"
);
}
}
...
...
src/share/vm/gc_implementation/g1/g1_globals.hpp
浏览文件 @
05d15943
...
@@ -69,9 +69,6 @@
...
@@ -69,9 +69,6 @@
diagnostic(bool, G1TraceConcRefinement, false, \
diagnostic(bool, G1TraceConcRefinement, false, \
"Trace G1 concurrent refinement") \
"Trace G1 concurrent refinement") \
\
\
product(intx, G1MarkRegionStackSize, 1024 * 1024, \
"Size of the region stack for concurrent marking.") \
\
product(double, G1ConcMarkStepDurationMillis, 10.0, \
product(double, G1ConcMarkStepDurationMillis, 10.0, \
"Target duration of individual concurrent marking steps " \
"Target duration of individual concurrent marking steps " \
"in milliseconds.") \
"in milliseconds.") \
...
...
src/share/vm/gc_implementation/g1/heapRegion.hpp
浏览文件 @
05d15943
...
@@ -373,10 +373,9 @@ class HeapRegion: public G1OffsetTableContigSpace {
...
@@ -373,10 +373,9 @@ class HeapRegion: public G1OffsetTableContigSpace {
ScrubRemSetClaimValue
=
3
,
ScrubRemSetClaimValue
=
3
,
ParVerifyClaimValue
=
4
,
ParVerifyClaimValue
=
4
,
RebuildRSClaimValue
=
5
,
RebuildRSClaimValue
=
5
,
CompleteMarkCSetClaimValue
=
6
,
ParEvacFailureClaimValue
=
6
,
ParEvacFailureClaimValue
=
7
,
AggregateCountClaimValue
=
7
,
AggregateCountClaimValue
=
8
,
VerifyCountClaimValue
=
8
VerifyCountClaimValue
=
9
};
};
inline
HeapWord
*
par_allocate_no_bot_updates
(
size_t
word_size
)
{
inline
HeapWord
*
par_allocate_no_bot_updates
(
size_t
word_size
)
{
...
...
src/share/vm/memory/barrierSet.hpp
浏览文件 @
05d15943
...
@@ -181,6 +181,8 @@ public:
...
@@ -181,6 +181,8 @@ public:
// within the heap, this function tells whether they are met.
// within the heap, this function tells whether they are met.
virtual
bool
is_aligned
(
HeapWord
*
addr
)
=
0
;
virtual
bool
is_aligned
(
HeapWord
*
addr
)
=
0
;
// Print a description of the memory for the barrier set
virtual
void
print_on
(
outputStream
*
st
)
const
=
0
;
};
};
#endif // SHARE_VM_MEMORY_BARRIERSET_HPP
#endif // SHARE_VM_MEMORY_BARRIERSET_HPP
src/share/vm/memory/cardTableModRefBS.cpp
浏览文件 @
05d15943
...
@@ -711,6 +711,11 @@ void CardTableModRefBS::verify_dirty_region(MemRegion mr) {
...
@@ -711,6 +711,11 @@ void CardTableModRefBS::verify_dirty_region(MemRegion mr) {
}
}
#endif
#endif
void
CardTableModRefBS
::
print_on
(
outputStream
*
st
)
const
{
st
->
print_cr
(
"Card table byte_map: ["
INTPTR_FORMAT
","
INTPTR_FORMAT
"] byte_map_base: "
INTPTR_FORMAT
,
_byte_map
,
_byte_map
+
_byte_map_size
,
byte_map_base
);
}
bool
CardTableModRefBSForCTRS
::
card_will_be_scanned
(
jbyte
cv
)
{
bool
CardTableModRefBSForCTRS
::
card_will_be_scanned
(
jbyte
cv
)
{
return
return
CardTableModRefBS
::
card_will_be_scanned
(
cv
)
||
CardTableModRefBS
::
card_will_be_scanned
(
cv
)
||
...
...
src/share/vm/memory/cardTableModRefBS.hpp
浏览文件 @
05d15943
...
@@ -472,6 +472,9 @@ public:
...
@@ -472,6 +472,9 @@ public:
return
_byte_map
+
card_index
;
return
_byte_map
+
card_index
;
}
}
// Print a description of the memory for the barrier set
virtual
void
print_on
(
outputStream
*
st
)
const
;
void
verify
();
void
verify
();
void
verify_guard
();
void
verify_guard
();
...
...
src/share/vm/memory/dump.cpp
浏览文件 @
05d15943
/*
/*
* Copyright (c) 2003, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
2
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -1488,12 +1488,11 @@ void GenCollectedHeap::preload_and_dump(TRAPS) {
...
@@ -1488,12 +1488,11 @@ void GenCollectedHeap::preload_and_dump(TRAPS) {
// sun.io.Converters
// sun.io.Converters
static
const
char
obj_array_sig
[]
=
"[[Ljava/lang/Object;"
;
static
const
char
obj_array_sig
[]
=
"[[Ljava/lang/Object;"
;
SymbolTable
::
lookup
(
obj_array_sig
,
(
int
)
strlen
(
obj_array_sig
)
,
THREAD
);
(
void
)
SymbolTable
::
new_permanent_symbol
(
obj_array_sig
,
THREAD
);
// java.util.HashMap
// java.util.HashMap
static
const
char
map_entry_array_sig
[]
=
"[Ljava/util/Map$Entry;"
;
static
const
char
map_entry_array_sig
[]
=
"[Ljava/util/Map$Entry;"
;
SymbolTable
::
lookup
(
map_entry_array_sig
,
(
int
)
strlen
(
map_entry_array_sig
),
(
void
)
SymbolTable
::
new_permanent_symbol
(
map_entry_array_sig
,
THREAD
);
THREAD
);
tty
->
print
(
"Loading classes to share ... "
);
tty
->
print
(
"Loading classes to share ... "
);
while
((
fgets
(
class_name
,
sizeof
class_name
,
file
))
!=
NULL
)
{
while
((
fgets
(
class_name
,
sizeof
class_name
,
file
))
!=
NULL
)
{
...
@@ -1512,7 +1511,7 @@ void GenCollectedHeap::preload_and_dump(TRAPS) {
...
@@ -1512,7 +1511,7 @@ void GenCollectedHeap::preload_and_dump(TRAPS) {
computed_jsum
=
jsum
(
computed_jsum
,
class_name
,
(
const
int
)
name_len
-
1
);
computed_jsum
=
jsum
(
computed_jsum
,
class_name
,
(
const
int
)
name_len
-
1
);
// Got a class name - load it.
// Got a class name - load it.
TempNewSymbol
class_name_symbol
=
SymbolTable
::
new
_symbol
(
class_name
,
THREAD
);
Symbol
*
class_name_symbol
=
SymbolTable
::
new_permanent
_symbol
(
class_name
,
THREAD
);
guarantee
(
!
HAS_PENDING_EXCEPTION
,
"Exception creating a symbol."
);
guarantee
(
!
HAS_PENDING_EXCEPTION
,
"Exception creating a symbol."
);
klassOop
klass
=
SystemDictionary
::
resolve_or_null
(
class_name_symbol
,
klassOop
klass
=
SystemDictionary
::
resolve_or_null
(
class_name_symbol
,
THREAD
);
THREAD
);
...
...
src/share/vm/oops/objArrayKlassKlass.cpp
浏览文件 @
05d15943
/*
/*
* Copyright (c) 1997, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
2
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -137,7 +137,7 @@ klassOop objArrayKlassKlass::allocate_objArray_klass_impl(objArrayKlassKlassHand
...
@@ -137,7 +137,7 @@ klassOop objArrayKlassKlass::allocate_objArray_klass_impl(objArrayKlassKlassHand
new_str
[
idx
++
]
=
';'
;
new_str
[
idx
++
]
=
';'
;
}
}
new_str
[
idx
++
]
=
'\0'
;
new_str
[
idx
++
]
=
'\0'
;
name
=
SymbolTable
::
new_symbol
(
new_str
,
CHECK_0
);
name
=
SymbolTable
::
new_
permanent_
symbol
(
new_str
,
CHECK_0
);
if
(
element_klass
->
oop_is_instance
())
{
if
(
element_klass
->
oop_is_instance
())
{
instanceKlass
*
ik
=
instanceKlass
::
cast
(
element_klass
());
instanceKlass
*
ik
=
instanceKlass
::
cast
(
element_klass
());
ik
->
set_array_name
(
name
);
ik
->
set_array_name
(
name
);
...
...
src/share/vm/oops/symbol.cpp
浏览文件 @
05d15943
/*
/*
* Copyright (c) 1997, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
2
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -29,15 +29,25 @@
...
@@ -29,15 +29,25 @@
#include "runtime/os.hpp"
#include "runtime/os.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/allocation.inline.hpp"
Symbol
::
Symbol
(
const
u1
*
name
,
int
length
)
:
_refcount
(
0
),
_length
(
length
)
{
Symbol
::
Symbol
(
const
u1
*
name
,
int
length
,
int
refcount
)
:
_refcount
(
refcount
),
_length
(
length
)
{
_identity_hash
=
os
::
random
();
_identity_hash
=
os
::
random
();
for
(
int
i
=
0
;
i
<
_length
;
i
++
)
{
for
(
int
i
=
0
;
i
<
_length
;
i
++
)
{
byte_at_put
(
i
,
name
[
i
]);
byte_at_put
(
i
,
name
[
i
]);
}
}
}
}
void
*
Symbol
::
operator
new
(
size_t
size
,
int
len
)
{
void
*
Symbol
::
operator
new
(
size_t
sz
,
int
len
,
TRAPS
)
{
return
(
void
*
)
AllocateHeap
(
object_size
(
len
)
*
HeapWordSize
,
"symbol"
);
int
alloc_size
=
object_size
(
len
)
*
HeapWordSize
;
address
res
=
(
address
)
AllocateHeap
(
alloc_size
,
"symbol"
);
DEBUG_ONLY
(
set_allocation_type
(
res
,
ResourceObj
::
C_HEAP
);)
return
res
;
}
void
*
Symbol
::
operator
new
(
size_t
sz
,
int
len
,
Arena
*
arena
,
TRAPS
)
{
int
alloc_size
=
object_size
(
len
)
*
HeapWordSize
;
address
res
=
(
address
)
arena
->
Amalloc
(
alloc_size
);
DEBUG_ONLY
(
set_allocation_type
(
res
,
ResourceObj
::
ARENA
);)
return
res
;
}
}
// ------------------------------------------------------------------
// ------------------------------------------------------------------
...
@@ -206,26 +216,5 @@ void Symbol::print_value_on(outputStream* st) const {
...
@@ -206,26 +216,5 @@ void Symbol::print_value_on(outputStream* st) const {
}
}
}
}
void
Symbol
::
increment_refcount
()
{
// SymbolTable prints this in its statistics
// Only increment the refcount if positive. If negative either
// overflow has occurred or it is a permanent symbol in a read only
// shared archive.
if
(
_refcount
>=
0
)
{
Atomic
::
inc
(
&
_refcount
);
NOT_PRODUCT
(
Atomic
::
inc
(
&
_total_count
);)
}
}
void
Symbol
::
decrement_refcount
()
{
if
(
_refcount
>=
0
)
{
Atomic
::
dec
(
&
_refcount
);
#ifdef ASSERT
if
(
_refcount
<
0
)
{
print
();
assert
(
false
,
"reference count underflow for symbol"
);
}
#endif
}
}
NOT_PRODUCT
(
int
Symbol
::
_total_count
=
0
;)
NOT_PRODUCT
(
int
Symbol
::
_total_count
=
0
;)
src/share/vm/oops/symbol.hpp
浏览文件 @
05d15943
/*
/*
* Copyright (c) 1997, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
2
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#include "utilities/utf8.hpp"
#include "utilities/utf8.hpp"
#include "memory/allocation.hpp"
#include "memory/allocation.hpp"
#include "runtime/atomic.hpp"
// A Symbol is a canonicalized string.
// A Symbol is a canonicalized string.
// All Symbols reside in global SymbolTable and are reference counted.
// All Symbols reside in global SymbolTable and are reference counted.
...
@@ -95,7 +96,7 @@
...
@@ -95,7 +96,7 @@
// TempNewSymbol (passed in as a parameter) so the reference count on its symbol
// TempNewSymbol (passed in as a parameter) so the reference count on its symbol
// will be decremented when it goes out of scope.
// will be decremented when it goes out of scope.
class
Symbol
:
public
CHeap
Obj
{
class
Symbol
:
public
Resource
Obj
{
friend
class
VMStructs
;
friend
class
VMStructs
;
friend
class
SymbolTable
;
friend
class
SymbolTable
;
friend
class
MoveSymbols
;
friend
class
MoveSymbols
;
...
@@ -111,7 +112,7 @@ class Symbol : public CHeapObj {
...
@@ -111,7 +112,7 @@ class Symbol : public CHeapObj {
};
};
static
int
object_size
(
int
length
)
{
static
int
object_size
(
int
length
)
{
size_t
size
=
heap_word_size
(
sizeof
(
Symbol
)
+
length
);
size_t
size
=
heap_word_size
(
sizeof
(
Symbol
)
+
(
length
>
0
?
length
-
1
:
0
)
);
return
align_object_size
(
size
);
return
align_object_size
(
size
);
}
}
...
@@ -120,28 +121,25 @@ class Symbol : public CHeapObj {
...
@@ -120,28 +121,25 @@ class Symbol : public CHeapObj {
_body
[
index
]
=
value
;
_body
[
index
]
=
value
;
}
}
Symbol
(
const
u1
*
name
,
int
length
);
Symbol
(
const
u1
*
name
,
int
length
,
int
refcount
);
void
*
operator
new
(
size_t
size
,
int
len
);
void
*
operator
new
(
size_t
size
,
int
len
,
TRAPS
);
void
*
operator
new
(
size_t
size
,
int
len
,
Arena
*
arena
,
TRAPS
);
public:
public:
// Low-level access (used with care, since not GC-safe)
// Low-level access (used with care, since not GC-safe)
const
jbyte
*
base
()
const
{
return
&
_body
[
0
];
}
const
jbyte
*
base
()
const
{
return
&
_body
[
0
];
}
int
object_size
()
{
return
object_size
(
utf8_length
());
}
int
object_size
()
{
return
object_size
(
utf8_length
());
}
// Returns the largest size symbol we can safely hold.
// Returns the largest size symbol we can safely hold.
static
int
max_length
()
{
static
int
max_length
()
{
return
max_symbol_length
;
}
return
max_symbol_length
;
}
int
identity_hash
()
{
int
identity_hash
()
{
return
_identity_hash
;
}
return
_identity_hash
;
}
// Reference counting. See comments above this class for when to use.
// Reference counting. See comments above this class for when to use.
int
refcount
()
const
{
return
_refcount
;
}
int
refcount
()
const
{
return
_refcount
;
}
void
increment_refcount
();
inline
void
increment_refcount
();
void
decrement_refcount
();
inline
void
decrement_refcount
();
int
byte_at
(
int
index
)
const
{
int
byte_at
(
int
index
)
const
{
assert
(
index
>=
0
&&
index
<
_length
,
"symbol index overflow"
);
assert
(
index
>=
0
&&
index
<
_length
,
"symbol index overflow"
);
...
@@ -220,4 +218,26 @@ int Symbol::fast_compare(Symbol* other) const {
...
@@ -220,4 +218,26 @@ int Symbol::fast_compare(Symbol* other) const {
return
(((
uintptr_t
)
this
<
(
uintptr_t
)
other
)
?
-
1
return
(((
uintptr_t
)
this
<
(
uintptr_t
)
other
)
?
-
1
:
((
uintptr_t
)
this
==
(
uintptr_t
)
other
)
?
0
:
1
);
:
((
uintptr_t
)
this
==
(
uintptr_t
)
other
)
?
0
:
1
);
}
}
inline
void
Symbol
::
increment_refcount
()
{
// Only increment the refcount if positive. If negative either
// overflow has occurred or it is a permanent symbol in a read only
// shared archive.
if
(
_refcount
>=
0
)
{
Atomic
::
inc
(
&
_refcount
);
NOT_PRODUCT
(
Atomic
::
inc
(
&
_total_count
);)
}
}
inline
void
Symbol
::
decrement_refcount
()
{
if
(
_refcount
>=
0
)
{
Atomic
::
dec
(
&
_refcount
);
#ifdef ASSERT
if
(
_refcount
<
0
)
{
print
();
assert
(
false
,
"reference count underflow for symbol"
);
}
#endif
}
}
#endif // SHARE_VM_OOPS_SYMBOL_HPP
#endif // SHARE_VM_OOPS_SYMBOL_HPP
src/share/vm/oops/typeArrayKlass.cpp
浏览文件 @
05d15943
...
@@ -55,7 +55,7 @@ klassOop typeArrayKlass::create_klass(BasicType type, int scale,
...
@@ -55,7 +55,7 @@ klassOop typeArrayKlass::create_klass(BasicType type, int scale,
Symbol
*
sym
=
NULL
;
Symbol
*
sym
=
NULL
;
if
(
name_str
!=
NULL
)
{
if
(
name_str
!=
NULL
)
{
sym
=
SymbolTable
::
new_symbol
(
name_str
,
CHECK_NULL
);
sym
=
SymbolTable
::
new_
permanent_
symbol
(
name_str
,
CHECK_NULL
);
}
}
KlassHandle
klassklass
(
THREAD
,
Universe
::
typeArrayKlassKlassObj
());
KlassHandle
klassklass
(
THREAD
,
Universe
::
typeArrayKlassKlassObj
());
...
...
src/share/vm/prims/wbtestmethods/parserTests.cpp
0 → 100644
浏览文件 @
05d15943
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "classfile/symbolTable.hpp"
#include "prims/jni.h"
#include "prims/whitebox.hpp"
#include "prims/wbtestmethods/parserTests.hpp"
#include "runtime/interfaceSupport.hpp"
#include "memory/oopFactory.hpp"
#include "services/diagnosticArgument.hpp"
#include "services/diagnosticFramework.hpp"
//There's no way of beforeahnd knowing an upper size
//Of the length of a string representation of
//the value of an argument.
#define VALUE_MAXLEN 256
// DiagnosticFramework test utility methods
/*
* The DiagnosticArgumentType class contains an enum that says which type
* this argument represents. (JLONG, BOOLEAN etc).
* This method Returns a char* representation of that enum value.
*/
static
const
char
*
lookup_diagnosticArgumentEnum
(
const
char
*
field_name
,
oop
object
)
{
Thread
*
THREAD
=
Thread
::
current
();
const
char
*
enum_sig
=
"Lsun/hotspot/parser/DiagnosticCommand$DiagnosticArgumentType;"
;
TempNewSymbol
enumSigSymbol
=
SymbolTable
::
lookup
(
enum_sig
,
(
int
)
strlen
(
enum_sig
),
THREAD
);
int
offset
=
WhiteBox
::
offset_for_field
(
field_name
,
object
,
enumSigSymbol
);
oop
enumOop
=
object
->
obj_field
(
offset
);
const
char
*
ret
=
WhiteBox
::
lookup_jstring
(
"name"
,
enumOop
);
return
ret
;
}
/*
* Takes an oop to a DiagnosticArgumentType-instance and
* reads the fields from it. Fills an native DCmdParser with
* this info.
*/
static
void
fill_in_parser
(
DCmdParser
*
parser
,
oop
argument
)
{
const
char
*
name
=
WhiteBox
::
lookup_jstring
(
"name"
,
argument
);
const
char
*
desc
=
WhiteBox
::
lookup_jstring
(
"desc"
,
argument
);
const
char
*
default_value
=
WhiteBox
::
lookup_jstring
(
"defaultValue"
,
argument
);
bool
mandatory
=
WhiteBox
::
lookup_bool
(
"mandatory"
,
argument
);
const
char
*
type
=
lookup_diagnosticArgumentEnum
(
"type"
,
argument
);
if
(
strcmp
(
type
,
"STRING"
)
==
0
)
{
DCmdArgument
<
char
*>*
argument
=
new
DCmdArgument
<
char
*>
(
name
,
desc
,
"STRING"
,
mandatory
,
default_value
);
parser
->
add_dcmd_option
(
argument
);
}
else
if
(
strcmp
(
type
,
"NANOTIME"
)
==
0
)
{
DCmdArgument
<
NanoTimeArgument
>*
argument
=
new
DCmdArgument
<
NanoTimeArgument
>
(
name
,
desc
,
"NANOTIME"
,
mandatory
,
default_value
);
parser
->
add_dcmd_option
(
argument
);
}
else
if
(
strcmp
(
type
,
"JLONG"
)
==
0
)
{
DCmdArgument
<
jlong
>*
argument
=
new
DCmdArgument
<
jlong
>
(
name
,
desc
,
"JLONG"
,
mandatory
,
default_value
);
parser
->
add_dcmd_option
(
argument
);
}
else
if
(
strcmp
(
type
,
"BOOLEAN"
)
==
0
)
{
DCmdArgument
<
bool
>*
argument
=
new
DCmdArgument
<
bool
>
(
name
,
desc
,
"BOOLEAN"
,
mandatory
,
default_value
);
parser
->
add_dcmd_option
(
argument
);
}
else
if
(
strcmp
(
type
,
"MEMORYSIZE"
)
==
0
)
{
DCmdArgument
<
MemorySizeArgument
>*
argument
=
new
DCmdArgument
<
MemorySizeArgument
>
(
name
,
desc
,
"MEMORY SIZE"
,
mandatory
,
default_value
);
parser
->
add_dcmd_option
(
argument
);
}
else
if
(
strcmp
(
type
,
"STRINGARRAY"
)
==
0
)
{
DCmdArgument
<
StringArrayArgument
*>*
argument
=
new
DCmdArgument
<
StringArrayArgument
*>
(
name
,
desc
,
"STRING SET"
,
mandatory
);
parser
->
add_dcmd_option
(
argument
);
}
}
/*
* Will Fill in a java object array with alternating names of parsed command line options and
* the value that has been parsed for it:
* { name, value, name, value ... }
* This can then be checked from java.
*/
WB_ENTRY
(
jobjectArray
,
WB_ParseCommandLine
(
JNIEnv
*
env
,
jobject
o
,
jstring
j_cmdline
,
jobjectArray
arguments
))
ResourceMark
rm
;
DCmdParser
parser
;
const
char
*
c_cmdline
=
java_lang_String
::
as_utf8_string
(
JNIHandles
::
resolve
(
j_cmdline
));
objArrayOop
argumentArray
=
objArrayOop
(
JNIHandles
::
resolve_non_null
(
arguments
));
int
length
=
argumentArray
->
length
();
for
(
int
i
=
0
;
i
<
length
;
i
++
)
{
oop
argument_oop
=
argumentArray
->
obj_at
(
i
);
fill_in_parser
(
&
parser
,
argument_oop
);
}
CmdLine
cmdline
(
c_cmdline
,
strlen
(
c_cmdline
),
true
);
parser
.
parse
(
&
cmdline
,
','
,
CHECK_NULL
);
klassOop
k
=
SystemDictionary
::
Object_klass
();
objArrayOop
returnvalue_array
=
oopFactory
::
new_objArray
(
k
,
parser
.
num_arguments
()
*
2
,
CHECK_NULL
);
GrowableArray
<
const
char
*>*
parsedArgNames
=
parser
.
argument_name_array
();
for
(
int
i
=
0
;
i
<
parser
.
num_arguments
();
i
++
)
{
oop
parsedName
=
java_lang_String
::
create_oop_from_str
(
parsedArgNames
->
at
(
i
),
CHECK_NULL
);
returnvalue_array
->
obj_at_put
(
i
*
2
,
parsedName
);
GenDCmdArgument
*
arg
=
parser
.
lookup_dcmd_option
(
parsedArgNames
->
at
(
i
),
strlen
(
parsedArgNames
->
at
(
i
)));
char
buf
[
VALUE_MAXLEN
];
arg
->
value_as_str
(
buf
,
sizeof
(
buf
));
oop
parsedValue
=
java_lang_String
::
create_oop_from_str
(
buf
,
CHECK_NULL
);
returnvalue_array
->
obj_at_put
(
i
*
2
+
1
,
parsedValue
);
}
return
(
jobjectArray
)
JNIHandles
::
make_local
(
returnvalue_array
);
WB_END
src/share/vm/prims/wbtestmethods/parserTests.hpp
0 → 100644
浏览文件 @
05d15943
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef SHARE_VM_PRIMS_WBTESTMETHODS_PARSERTESTS_H
#define SHARE_VM_PRIMS_WBTESTMETHODS_PARSERTESTS_H
#include "prims/jni.h"
#include "prims/whitebox.hpp"
WB_METHOD_DECLARE
WB_ParseCommandLine
(
JNIEnv
*
env
,
jobject
o
,
jstring
args
,
jobjectArray
arguments
);
#endif //SHARE_VM_PRIMS_WBTESTMETHODS_PARSERTESTS_H
src/share/vm/prims/whitebox.cpp
浏览文件 @
05d15943
...
@@ -24,11 +24,14 @@
...
@@ -24,11 +24,14 @@
#include "precompiled.hpp"
#include "precompiled.hpp"
#include "jni.h"
#include "memory/universe.hpp"
#include "memory/universe.hpp"
#include "oops/oop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "classfile/symbolTable.hpp"
#include "prims/whitebox.hpp"
#include "prims/whitebox.hpp"
#include "prims/wbtestmethods/parserTests.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/os.hpp"
#include "runtime/os.hpp"
#include "utilities/debug.hpp"
#include "utilities/debug.hpp"
...
@@ -41,13 +44,6 @@
...
@@ -41,13 +44,6 @@
bool
WhiteBox
::
_used
=
false
;
bool
WhiteBox
::
_used
=
false
;
// Entry macro to transition from JNI to VM state.
#define WB_ENTRY(result_type, header) JNI_ENTRY(result_type, header)
#define WB_END JNI_END
// Definitions of functions exposed via Whitebox API
WB_ENTRY
(
jlong
,
WB_GetObjectAddress
(
JNIEnv
*
env
,
jobject
o
,
jobject
obj
))
WB_ENTRY
(
jlong
,
WB_GetObjectAddress
(
JNIEnv
*
env
,
jobject
o
,
jobject
obj
))
return
(
jlong
)(
void
*
)
JNIHandles
::
resolve
(
obj
);
return
(
jlong
)(
void
*
)
JNIHandles
::
resolve
(
obj
);
WB_END
WB_END
...
@@ -81,11 +77,63 @@ WB_ENTRY(jint, WB_G1RegionSize(JNIEnv* env, jobject o))
...
@@ -81,11 +77,63 @@ WB_ENTRY(jint, WB_G1RegionSize(JNIEnv* env, jobject o))
WB_END
WB_END
#endif // !SERIALGC
#endif // !SERIALGC
//Some convenience methods to deal with objects from java
int
WhiteBox
::
offset_for_field
(
const
char
*
field_name
,
oop
object
,
Symbol
*
signature_symbol
)
{
assert
(
field_name
!=
NULL
&&
strlen
(
field_name
)
>
0
,
"Field name not valid"
);
Thread
*
THREAD
=
Thread
::
current
();
//Get the class of our object
klassOop
arg_klass
=
object
->
klass
();
//Turn it into an instance-klass
instanceKlass
*
ik
=
instanceKlass
::
cast
(
arg_klass
);
//Create symbols to look for in the class
TempNewSymbol
name_symbol
=
SymbolTable
::
lookup
(
field_name
,
(
int
)
strlen
(
field_name
),
THREAD
);
//To be filled in with an offset of the field we're looking for
fieldDescriptor
fd
;
klassOop
res
=
ik
->
find_field
(
name_symbol
,
signature_symbol
,
&
fd
);
if
(
res
==
NULL
)
{
tty
->
print_cr
(
"Invalid layout of %s at %s"
,
ik
->
external_name
(),
name_symbol
->
as_C_string
());
fatal
(
"Invalid layout of preloaded class"
);
}
//fetch the field at the offset we've found
int
dest_offset
=
fd
.
offset
();
return
dest_offset
;
}
const
char
*
WhiteBox
::
lookup_jstring
(
const
char
*
field_name
,
oop
object
)
{
int
offset
=
offset_for_field
(
field_name
,
object
,
vmSymbols
::
string_signature
());
oop
string
=
object
->
obj_field
(
offset
);
const
char
*
ret
=
java_lang_String
::
as_utf8_string
(
string
);
return
ret
;
}
bool
WhiteBox
::
lookup_bool
(
const
char
*
field_name
,
oop
object
)
{
int
offset
=
offset_for_field
(
field_name
,
object
,
vmSymbols
::
bool_signature
());
bool
ret
=
(
object
->
bool_field
(
offset
)
==
JNI_TRUE
);
return
ret
;
}
#define CC (char*)
#define CC (char*)
static
JNINativeMethod
methods
[]
=
{
static
JNINativeMethod
methods
[]
=
{
{
CC
"getObjectAddress"
,
CC
"(Ljava/lang/Object;)J"
,
(
void
*
)
&
WB_GetObjectAddress
},
{
CC
"getObjectAddress"
,
CC
"(Ljava/lang/Object;)J"
,
(
void
*
)
&
WB_GetObjectAddress
},
{
CC
"getHeapOopSize"
,
CC
"()I"
,
(
void
*
)
&
WB_GetHeapOopSize
},
{
CC
"getHeapOopSize"
,
CC
"()I"
,
(
void
*
)
&
WB_GetHeapOopSize
},
{
CC
"parseCommandLine"
,
CC
"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;"
,
(
void
*
)
&
WB_ParseCommandLine
},
#ifndef SERIALGC
#ifndef SERIALGC
{
CC
"g1InConcurrentMark"
,
CC
"()Z"
,
(
void
*
)
&
WB_G1InConcurrentMark
},
{
CC
"g1InConcurrentMark"
,
CC
"()Z"
,
(
void
*
)
&
WB_G1InConcurrentMark
},
{
CC
"g1IsHumongous"
,
CC
"(Ljava/lang/Object;)Z"
,
(
void
*
)
&
WB_G1IsHumongous
},
{
CC
"g1IsHumongous"
,
CC
"(Ljava/lang/Object;)Z"
,
(
void
*
)
&
WB_G1IsHumongous
},
...
...
src/share/vm/prims/whitebox.hpp
浏览文件 @
05d15943
...
@@ -25,12 +25,29 @@
...
@@ -25,12 +25,29 @@
#ifndef SHARE_VM_PRIMS_WHITEBOX_HPP
#ifndef SHARE_VM_PRIMS_WHITEBOX_HPP
#define SHARE_VM_PRIMS_WHITEBOX_HPP
#define SHARE_VM_PRIMS_WHITEBOX_HPP
#include "prims/jni.h"
#include "memory/allocation.hpp"
#include "oops/oopsHierarchy.hpp"
// Entry macro to transition from JNI to VM state.
#define WB_ENTRY(result_type, header) JNI_ENTRY(result_type, header)
#define WB_END JNI_END
#define WB_METHOD_DECLARE extern "C" jobjectArray JNICALL
class
WhiteBox
:
public
AllStatic
{
class
WhiteBox
:
public
AllStatic
{
private:
private:
static
bool
_used
;
static
bool
_used
;
public:
public:
static
bool
used
()
{
return
_used
;
}
static
bool
used
()
{
return
_used
;
}
static
void
set_used
()
{
_used
=
true
;
}
static
void
set_used
()
{
_used
=
true
;
}
static
int
offset_for_field
(
const
char
*
field_name
,
oop
object
,
Symbol
*
signature_symbol
);
static
const
char
*
lookup_jstring
(
const
char
*
field_name
,
oop
object
);
static
bool
lookup_bool
(
const
char
*
field_name
,
oop
object
);
};
};
#endif // SHARE_VM_PRIMS_WHITEBOX_HPP
#endif // SHARE_VM_PRIMS_WHITEBOX_HPP
src/share/vm/runtime/globals.hpp
浏览文件 @
05d15943
...
@@ -3807,7 +3807,7 @@ class CommandLineFlags {
...
@@ -3807,7 +3807,7 @@ class CommandLineFlags {
product(uintx, SharedReadOnlySize, 10*M, \
product(uintx, SharedReadOnlySize, 10*M, \
"Size of read-only space in permanent generation (in bytes)") \
"Size of read-only space in permanent generation (in bytes)") \
\
\
product(uintx, SharedMiscDataSize,
NOT_LP64(4*M) LP64_ONLY(5
*M), \
product(uintx, SharedMiscDataSize,
NOT_LP64(4*M) LP64_ONLY(5*M) NOT_PRODUCT(+1
*M), \
"Size of the shared data area adjacent to the heap (in bytes)") \
"Size of the shared data area adjacent to the heap (in bytes)") \
\
\
product(uintx, SharedMiscCodeSize, 4*M, \
product(uintx, SharedMiscCodeSize, 4*M, \
...
...
src/share/vm/services/diagnosticArgument.cpp
浏览文件 @
05d15943
...
@@ -43,6 +43,47 @@ void GenDCmdArgument::read_value(const char* str, size_t len, TRAPS) {
...
@@ -43,6 +43,47 @@ void GenDCmdArgument::read_value(const char* str, size_t len, TRAPS) {
set_is_set
(
true
);
set_is_set
(
true
);
}
}
void
GenDCmdArgument
::
to_string
(
jlong
l
,
char
*
buf
,
size_t
len
)
{
jio_snprintf
(
buf
,
len
,
INT64_FORMAT
,
l
);
}
void
GenDCmdArgument
::
to_string
(
bool
b
,
char
*
buf
,
size_t
len
)
{
jio_snprintf
(
buf
,
len
,
b
?
"true"
:
"false"
);
}
void
GenDCmdArgument
::
to_string
(
NanoTimeArgument
n
,
char
*
buf
,
size_t
len
)
{
jio_snprintf
(
buf
,
len
,
INT64_FORMAT
,
n
.
_nanotime
);
}
void
GenDCmdArgument
::
to_string
(
MemorySizeArgument
m
,
char
*
buf
,
size_t
len
)
{
jio_snprintf
(
buf
,
len
,
INT64_FORMAT
,
m
.
_size
);
}
void
GenDCmdArgument
::
to_string
(
char
*
c
,
char
*
buf
,
size_t
len
)
{
jio_snprintf
(
buf
,
len
,
"%s"
,
c
);
}
void
GenDCmdArgument
::
to_string
(
StringArrayArgument
*
f
,
char
*
buf
,
size_t
len
)
{
int
length
=
f
->
array
()
->
length
();
size_t
written
=
0
;
buf
[
0
]
=
0
;
for
(
int
i
=
0
;
i
<
length
;
i
++
)
{
char
*
next_str
=
f
->
array
()
->
at
(
i
);
size_t
next_size
=
strlen
(
next_str
);
//Check if there's room left to write next element
if
(
written
+
next_size
>
len
)
{
return
;
}
//Actually write element
strcat
(
buf
,
next_str
);
written
+=
next_size
;
//Check if there's room left for the comma
if
(
i
<
length
-
1
&&
len
-
written
>
0
)
{
strcat
(
buf
,
","
);
}
}
}
template
<
>
void
DCmdArgument
<
jlong
>::
parse_value
(
const
char
*
str
,
template
<
>
void
DCmdArgument
<
jlong
>::
parse_value
(
const
char
*
str
,
size_t
len
,
TRAPS
)
{
size_t
len
,
TRAPS
)
{
if
(
str
==
NULL
||
sscanf
(
str
,
INT64_FORMAT
,
&
_value
)
!=
1
)
{
if
(
str
==
NULL
||
sscanf
(
str
,
INT64_FORMAT
,
&
_value
)
!=
1
)
{
...
...
src/share/vm/services/diagnosticArgument.hpp
浏览文件 @
05d15943
...
@@ -110,12 +110,20 @@ public:
...
@@ -110,12 +110,20 @@ public:
virtual
void
init_value
(
TRAPS
)
=
0
;
virtual
void
init_value
(
TRAPS
)
=
0
;
virtual
void
reset
(
TRAPS
)
=
0
;
virtual
void
reset
(
TRAPS
)
=
0
;
virtual
void
cleanup
()
=
0
;
virtual
void
cleanup
()
=
0
;
virtual
void
value_as_str
(
char
*
buf
,
size_t
len
)
=
0
;
void
set_next
(
GenDCmdArgument
*
arg
)
{
void
set_next
(
GenDCmdArgument
*
arg
)
{
_next
=
arg
;
_next
=
arg
;
}
}
GenDCmdArgument
*
next
()
{
GenDCmdArgument
*
next
()
{
return
_next
;
return
_next
;
}
}
void
to_string
(
jlong
l
,
char
*
buf
,
size_t
len
);
void
to_string
(
bool
b
,
char
*
buf
,
size_t
len
);
void
to_string
(
char
*
c
,
char
*
buf
,
size_t
len
);
void
to_string
(
NanoTimeArgument
n
,
char
*
buf
,
size_t
len
);
void
to_string
(
MemorySizeArgument
f
,
char
*
buf
,
size_t
len
);
void
to_string
(
StringArrayArgument
*
s
,
char
*
buf
,
size_t
len
);
};
};
template
<
class
ArgType
>
class
DCmdArgument
:
public
GenDCmdArgument
{
template
<
class
ArgType
>
class
DCmdArgument
:
public
GenDCmdArgument
{
...
@@ -143,6 +151,7 @@ public:
...
@@ -143,6 +151,7 @@ public:
void
parse_value
(
const
char
*
str
,
size_t
len
,
TRAPS
);
void
parse_value
(
const
char
*
str
,
size_t
len
,
TRAPS
);
void
init_value
(
TRAPS
);
void
init_value
(
TRAPS
);
void
destroy_value
();
void
destroy_value
();
void
value_as_str
(
char
*
buf
,
size_t
len
)
{
return
to_string
(
_value
,
buf
,
len
);}
};
};
#endif
/* SHARE_VM_SERVICES_DIAGNOSTICARGUMENT_HPP */
#endif
/* SHARE_VM_SERVICES_DIAGNOSTICARGUMENT_HPP */
src/share/vm/services/gcNotifier.cpp
浏览文件 @
05d15943
...
@@ -163,8 +163,8 @@ static Handle createGcInfo(GCMemoryManager *gcManager, GCStatInfo *gcStatInfo,TR
...
@@ -163,8 +163,8 @@ static Handle createGcInfo(GCMemoryManager *gcManager, GCStatInfo *gcStatInfo,TR
constructor_args
.
push_oop
(
gcInfo_instance
);
constructor_args
.
push_oop
(
gcInfo_instance
);
constructor_args
.
push_oop
(
getGcInfoBuilder
(
gcManager
,
THREAD
));
constructor_args
.
push_oop
(
getGcInfoBuilder
(
gcManager
,
THREAD
));
constructor_args
.
push_long
(
gcStatInfo
->
gc_index
());
constructor_args
.
push_long
(
gcStatInfo
->
gc_index
());
constructor_args
.
push_long
(
gcStatInfo
->
start_time
(
));
constructor_args
.
push_long
(
Management
::
ticks_to_ms
(
gcStatInfo
->
start_time
()
));
constructor_args
.
push_long
(
gcStatInfo
->
end_time
(
));
constructor_args
.
push_long
(
Management
::
ticks_to_ms
(
gcStatInfo
->
end_time
()
));
constructor_args
.
push_oop
(
usage_before_gc_ah
);
constructor_args
.
push_oop
(
usage_before_gc_ah
);
constructor_args
.
push_oop
(
usage_after_gc_ah
);
constructor_args
.
push_oop
(
usage_after_gc_ah
);
constructor_args
.
push_oop
(
extra_array
);
constructor_args
.
push_oop
(
extra_array
);
...
...
src/share/vm/utilities/bitMap.cpp
浏览文件 @
05d15943
/*
/*
* Copyright (c) 1997, 201
0
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
2
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -179,64 +179,6 @@ void BitMap::clear_large_range(idx_t beg, idx_t end) {
...
@@ -179,64 +179,6 @@ void BitMap::clear_large_range(idx_t beg, idx_t end) {
clear_range_within_word
(
bit_index
(
end_full_word
),
end
);
clear_range_within_word
(
bit_index
(
end_full_word
),
end
);
}
}
void
BitMap
::
mostly_disjoint_range_union
(
BitMap
*
from_bitmap
,
idx_t
from_start_index
,
idx_t
to_start_index
,
size_t
word_num
)
{
// Ensure that the parameters are correct.
// These shouldn't be that expensive to check, hence I left them as
// guarantees.
guarantee
(
from_bitmap
->
bit_in_word
(
from_start_index
)
==
0
,
"it should be aligned on a word boundary"
);
guarantee
(
bit_in_word
(
to_start_index
)
==
0
,
"it should be aligned on a word boundary"
);
guarantee
(
word_num
>=
2
,
"word_num should be at least 2"
);
intptr_t
*
from
=
(
intptr_t
*
)
from_bitmap
->
word_addr
(
from_start_index
);
intptr_t
*
to
=
(
intptr_t
*
)
word_addr
(
to_start_index
);
if
(
*
from
!=
0
)
{
// if it's 0, then there's no point in doing the CAS
while
(
true
)
{
intptr_t
old_value
=
*
to
;
intptr_t
new_value
=
old_value
|
*
from
;
intptr_t
res
=
Atomic
::
cmpxchg_ptr
(
new_value
,
to
,
old_value
);
if
(
res
==
old_value
)
break
;
}
}
++
from
;
++
to
;
for
(
size_t
i
=
0
;
i
<
word_num
-
2
;
++
i
)
{
if
(
*
from
!=
0
)
{
// if it's 0, then there's no point in doing the CAS
assert
(
*
to
==
0
,
"nobody else should be writing here"
);
intptr_t
new_value
=
*
from
;
*
to
=
new_value
;
}
++
from
;
++
to
;
}
if
(
*
from
!=
0
)
{
// if it's 0, then there's no point in doing the CAS
while
(
true
)
{
intptr_t
old_value
=
*
to
;
intptr_t
new_value
=
old_value
|
*
from
;
intptr_t
res
=
Atomic
::
cmpxchg_ptr
(
new_value
,
to
,
old_value
);
if
(
res
==
old_value
)
break
;
}
}
// the -1 is because we didn't advance them after the final CAS
assert
(
from
==
(
intptr_t
*
)
from_bitmap
->
word_addr
(
from_start_index
)
+
word_num
-
1
,
"invariant"
);
assert
(
to
==
(
intptr_t
*
)
word_addr
(
to_start_index
)
+
word_num
-
1
,
"invariant"
);
}
void
BitMap
::
at_put
(
idx_t
offset
,
bool
value
)
{
void
BitMap
::
at_put
(
idx_t
offset
,
bool
value
)
{
if
(
value
)
{
if
(
value
)
{
set_bit
(
offset
);
set_bit
(
offset
);
...
...
src/share/vm/utilities/bitMap.hpp
浏览文件 @
05d15943
/*
/*
* Copyright (c) 1997, 201
1
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
2
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -192,31 +192,6 @@ class BitMap VALUE_OBJ_CLASS_SPEC {
...
@@ -192,31 +192,6 @@ class BitMap VALUE_OBJ_CLASS_SPEC {
void
par_set_range
(
idx_t
beg
,
idx_t
end
,
RangeSizeHint
hint
);
void
par_set_range
(
idx_t
beg
,
idx_t
end
,
RangeSizeHint
hint
);
void
par_clear_range
(
idx_t
beg
,
idx_t
end
,
RangeSizeHint
hint
);
void
par_clear_range
(
idx_t
beg
,
idx_t
end
,
RangeSizeHint
hint
);
// It performs the union operation between subsets of equal length
// of two bitmaps (the target bitmap of the method and the
// from_bitmap) and stores the result to the target bitmap. The
// from_start_index represents the first bit index of the subrange
// of the from_bitmap. The to_start_index is the equivalent of the
// target bitmap. Both indexes should be word-aligned, i.e. they
// should correspond to the first bit on a bitmap word (it's up to
// the caller to ensure this; the method does check it). The length
// of the subset is specified with word_num and it is in number of
// bitmap words. The caller should ensure that this is at least 2
// (smaller ranges are not support to save extra checks). Again,
// this is checked in the method.
//
// Atomicity concerns: it is assumed that any contention on the
// target bitmap with other threads will happen on the first and
// last words; the ones in between will be "owned" exclusively by
// the calling thread and, in fact, they will already be 0. So, the
// method performs a CAS on the first word, copies the next
// word_num-2 words, and finally performs a CAS on the last word.
void
mostly_disjoint_range_union
(
BitMap
*
from_bitmap
,
idx_t
from_start_index
,
idx_t
to_start_index
,
size_t
word_num
);
// Clearing
// Clearing
void
clear_large
();
void
clear_large
();
inline
void
clear
();
inline
void
clear
();
...
...
src/share/vm/utilities/vmError.cpp
浏览文件 @
05d15943
...
@@ -685,6 +685,12 @@ void VMError::report(outputStream* st) {
...
@@ -685,6 +685,12 @@ void VMError::report(outputStream* st) {
// extended (i.e., more detailed) version.
// extended (i.e., more detailed) version.
Universe
::
print_on
(
st
,
true
/* extended */
);
Universe
::
print_on
(
st
,
true
/* extended */
);
st
->
cr
();
st
->
cr
();
Universe
::
heap
()
->
barrier_set
()
->
print_on
(
st
);
st
->
cr
();
st
->
print_cr
(
"Polling page: "
INTPTR_FORMAT
,
os
::
get_polling_page
());
st
->
cr
();
}
}
STEP
(
195
,
"(printing code cache information)"
)
STEP
(
195
,
"(printing code cache information)"
)
...
...
test/serviceability/ParserTest.java
0 → 100644
浏览文件 @
05d15943
/*
* @test ParserTest
* @summary verify that whitebox functions can be linked and executed
* @run compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI ParserTest.java
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ParserTest
*/
import
java.math.BigInteger
;
import
sun.hotspot.parser.DiagnosticCommand
;
import
sun.hotspot.parser.DiagnosticCommand.DiagnosticArgumentType
;
import
sun.hotspot.WhiteBox
;
public
class
ParserTest
{
WhiteBox
wb
;
public
ParserTest
()
throws
Exception
{
wb
=
WhiteBox
.
getWhiteBox
();
testNanoTime
();
testJLong
();
testBool
();
testMemorySize
();
}
public
static
void
main
(
String
...
args
)
throws
Exception
{
new
ParserTest
();
}
public
void
testNanoTime
()
throws
Exception
{
String
name
=
"name"
;
DiagnosticCommand
arg
=
new
DiagnosticCommand
(
name
,
"desc"
,
DiagnosticArgumentType
.
NANOTIME
,
false
,
"0"
);
DiagnosticCommand
[]
args
=
{
arg
};
BigInteger
bi
=
new
BigInteger
(
"7"
);
//These should work
parse
(
name
,
bi
.
toString
(),
name
+
"=7ns"
,
args
);
bi
=
bi
.
multiply
(
BigInteger
.
valueOf
(
1000
));
parse
(
name
,
bi
.
toString
(),
name
+
"=7us"
,
args
);
bi
=
bi
.
multiply
(
BigInteger
.
valueOf
(
1000
));
parse
(
name
,
bi
.
toString
(),
name
+
"=7ms"
,
args
);
bi
=
bi
.
multiply
(
BigInteger
.
valueOf
(
1000
));
parse
(
name
,
bi
.
toString
(),
name
+
"=7s"
,
args
);
bi
=
bi
.
multiply
(
BigInteger
.
valueOf
(
60
));
parse
(
name
,
bi
.
toString
()
,
name
+
"=7m"
,
args
);
bi
=
bi
.
multiply
(
BigInteger
.
valueOf
(
60
));
parse
(
name
,
bi
.
toString
()
,
name
+
"=7h"
,
args
);
bi
=
bi
.
multiply
(
BigInteger
.
valueOf
(
24
));
parse
(
name
,
bi
.
toString
()
,
name
+
"=7d"
,
args
);
parse
(
name
,
"0"
,
name
+
"=0"
,
args
);
shouldFail
(
name
+
"=7xs"
,
args
);
shouldFail
(
name
+
"=7mms"
,
args
);
shouldFail
(
name
+
"=7f"
,
args
);
//Currently, only value 0 is allowed without unit
shouldFail
(
name
+
"=7"
,
args
);
}
public
void
testJLong
()
throws
Exception
{
String
name
=
"name"
;
DiagnosticCommand
arg
=
new
DiagnosticCommand
(
name
,
"desc"
,
DiagnosticArgumentType
.
JLONG
,
false
,
"0"
);
DiagnosticCommand
[]
args
=
{
arg
};
wb
.
parseCommandLine
(
name
+
"=10"
,
args
);
parse
(
name
,
"10"
,
name
+
"=10"
,
args
);
parse
(
name
,
"-5"
,
name
+
"=-5"
,
args
);
//shouldFail(name + "=12m", args); <-- should fail, doesn't
}
public
void
testBool
()
throws
Exception
{
String
name
=
"name"
;
DiagnosticCommand
arg
=
new
DiagnosticCommand
(
name
,
"desc"
,
DiagnosticArgumentType
.
BOOLEAN
,
false
,
"false"
);
DiagnosticCommand
[]
args
=
{
arg
};
parse
(
name
,
"true"
,
name
+
"=true"
,
args
);
parse
(
name
,
"false"
,
name
+
"=false"
,
args
);
parse
(
name
,
"true"
,
name
,
args
);
//Empty commandline to parse, tests default value
//of the parameter "name"
parse
(
name
,
"false"
,
""
,
args
);
}
public
void
testMemorySize
()
throws
Exception
{
String
name
=
"name"
;
String
defaultValue
=
"1024"
;
DiagnosticCommand
arg
=
new
DiagnosticCommand
(
name
,
"desc"
,
DiagnosticArgumentType
.
MEMORYSIZE
,
false
,
defaultValue
);
DiagnosticCommand
[]
args
=
{
arg
};
BigInteger
bi
=
new
BigInteger
(
"7"
);
parse
(
name
,
bi
.
toString
(),
name
+
"=7b"
,
args
);
bi
=
bi
.
multiply
(
BigInteger
.
valueOf
(
1024
));
parse
(
name
,
bi
.
toString
(),
name
+
"=7k"
,
args
);
bi
=
bi
.
multiply
(
BigInteger
.
valueOf
(
1024
));
parse
(
name
,
bi
.
toString
(),
name
+
"=7m"
,
args
);
bi
=
bi
.
multiply
(
BigInteger
.
valueOf
(
1024
));
parse
(
name
,
bi
.
toString
(),
name
+
"=7g"
,
args
);
parse
(
name
,
defaultValue
,
""
,
args
);
//shouldFail(name + "=7gg", args); <---- should fail, doesn't
//shouldFail(name + "=7t", args); <----- should fail, doesn't
}
public
void
parse
(
String
searchName
,
String
expectedValue
,
String
cmdLine
,
DiagnosticCommand
[]
argumentTypes
)
throws
Exception
{
//parseCommandLine will return an object array that looks like
//{<name of parsed object>, <of parsed object> ... }
Object
[]
res
=
wb
.
parseCommandLine
(
cmdLine
,
argumentTypes
);
for
(
int
i
=
0
;
i
<
res
.
length
-
1
;
i
+=
2
)
{
String
parsedName
=
(
String
)
res
[
i
];
if
(
searchName
.
equals
(
parsedName
))
{
String
parsedValue
=
(
String
)
res
[
i
+
1
];
if
(
expectedValue
.
equals
(
parsedValue
))
{
return
;
}
else
{
throw
new
Exception
(
"Parsing of cmdline '"
+
cmdLine
+
"' failed!\n"
+
searchName
+
" parsed as "
+
parsedValue
+
"! Expected: "
+
expectedValue
);
}
}
}
throw
new
Exception
(
searchName
+
" not found as a parsed Argument!"
);
}
private
void
shouldFail
(
String
argument
,
DiagnosticCommand
[]
argumentTypes
)
throws
Exception
{
try
{
wb
.
parseCommandLine
(
argument
,
argumentTypes
);
throw
new
Exception
(
"Parser accepted argument: "
+
argument
);
}
catch
(
IllegalArgumentException
e
)
{
//expected
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录