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看板
提交
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.
* 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.
* 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.
* 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.
* 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.
* 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.
* 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.
* 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.
* 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)/%, \
$(
patsubst
%.java,%.class,
$(WB_JAVA_SRCS)
))
$(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)
$(QUIETLY)
$(REMOTE)
$(RUN.JAR)
cf
$@
-C
$(WB_JAVA_CLASSDIR)
/ .
...
...
make/hotspot_version
浏览文件 @
05d15943
...
...
@@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2011
HS_MAJOR_VER=24
HS_MINOR_VER=0
HS_BUILD_NUMBER=0
6
HS_BUILD_NUMBER=0
7
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
...
...
make/linux/makefiles/wb.make
浏览文件 @
05d15943
...
...
@@ -36,7 +36,7 @@ WB_JAVA_CLASSES = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
$(
patsubst
%.java,%.class,
$(WB_JAVA_SRCS)
))
$(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)
$(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)/%, \
$(
patsubst
%.java,%.class,
$(WB_JAVA_SRCS)
))
$(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)
$(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
BASE_PATHS
=
"
${
BASE_PATHS
}
${
ALTSRC
}
/share/vm/jfr"
fi
BASE_PATHS
=
"
${
BASE_PATHS
}
${
COMMONSRC
}
/share/vm/prims/wbtestmethods"
CORE_PATHS
=
"
${
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
...
...
make/windows/makefiles/projectcreator.make
浏览文件 @
05d15943
...
...
@@ -51,6 +51,7 @@ ProjectCreatorIncludesPRIVATE=\
-relativeInclude
src
\c
losed
\c
pu
\$
(
Platform_arch
)
\v
m
\
-relativeInclude
src
\s
hare
\v
m
\
-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
\o
s
\w
indows
\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
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/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/services
VM_PATH
=
$(VM_PATH)
;
$(WorkSpace)
/src/share/vm/trace
...
...
@@ -269,6 +270,9 @@ bytecodeInterpreterWithChecks.obj: ..\generated\jvmtifiles\bytecodeInterpreterWi
{$(COMMONSRC)\share\vm\prims}.cpp.obj
::
$(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
::
$(CXX)
$(CXX_FLAGS)
$(CXX_USE_PCH)
/c
$<
...
...
@@ -349,6 +353,9 @@ bytecodeInterpreterWithChecks.obj: ..\generated\jvmtifiles\bytecodeInterpreterWi
{$(ALTSRC)\share\vm\prims}.cpp.obj
::
$(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
::
$(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
{$(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
$(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) {
if
(
which
==
end_pc_operand
)
return
ip
+
(
is_64bit
?
8
:
4
);
// these asserts are somewhat nonsensical
#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
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
return
ip
;
...
...
src/cpu/x86/vm/x86_64.ad
浏览文件 @
05d15943
...
...
@@ -3369,15 +3369,6 @@ operand immP0()
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
operand immN() %{
match(ConN);
...
...
@@ -5726,16 +5717,6 @@ instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr)
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)
%{
match(Set dst src);
...
...
src/share/tools/whitebox/sun/hotspot/WhiteBox.java
浏览文件 @
05d15943
...
...
@@ -24,6 +24,7 @@
package
sun.hotspot
;
import
java.security.BasicPermission
;
import
sun.hotspot.parser.DiagnosticCommand
;
public
class
WhiteBox
{
...
...
@@ -67,4 +68,5 @@ public class WhiteBox {
public
native
boolean
g1IsHumongous
(
Object
o
);
public
native
long
g1NumFreeRegions
();
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.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -81,7 +81,7 @@
#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
// this function (_current can be allocated in a register, with scalar
// replacement of aggregates). The _current pointer is copied back to
...
...
@@ -272,7 +272,7 @@ void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int len
indices
[
names_count
]
=
index
;
hashValues
[
names_count
++
]
=
hash
;
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
;
}
}
else
{
...
...
@@ -289,7 +289,7 @@ void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int len
// Allocate the remaining symbols
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().
...
...
@@ -318,7 +318,7 @@ class ConstantPoolCleaner : public StackObj {
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
();
constantPoolHandle
nullHandle
;
...
...
@@ -337,7 +337,7 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
ConstantPoolCleaner
cp_in_error
(
cp
);
// set constant pool to be cleaned up.
// 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
...
...
@@ -2803,7 +2803,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
_relax_verify
=
Verifier
::
relax_verify_for
(
class_loader
());
// 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.
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.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -68,9 +68,10 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
void
set_stream
(
ClassFileStream
*
st
)
{
_stream
=
st
;
}
// 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
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.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -27,6 +27,7 @@
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/filemap.hpp"
#include "memory/gcLocker.inline.hpp"
#include "oops/oop.inline.hpp"
...
...
@@ -37,34 +38,35 @@
// --------------------------------------------------------------------------
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*.
if
(
len
>
Symbol
::
max_length
())
{
THROW_MSG_0
(
vmSymbols
::
java_lang_InternalError
(),
"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"
);
return
sym
;
}
bool
SymbolTable
::
allocate_symbols
(
int
names_count
,
const
u1
**
names
,
int
*
lengths
,
Symbol
**
syms
,
TRAPS
)
{
for
(
int
i
=
0
;
i
<
names_count
;
i
++
)
{
if
(
lengths
[
i
]
>
Symbol
::
max_length
())
{
THROW_MSG_0
(
vmSymbols
::
java_lang_InternalError
(),
"name is too long to represent"
);
}
}
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"
);
void
SymbolTable
::
initialize_symbols
(
int
arena_alloc_size
)
{
// Initialize the arena for global symbols, size passed in depends on CDS.
if
(
arena_alloc_size
==
0
)
{
_arena
=
new
Arena
();
}
else
{
_arena
=
new
Arena
(
arena_alloc_size
);
}
return
true
;
}
// Call function for all symbols in the symbol table.
...
...
@@ -83,8 +85,7 @@ int SymbolTable::symbols_removed = 0;
int
SymbolTable
::
symbols_counted
=
0
;
// Remove unreferenced symbols from the symbol table
// This is done late during GC. This doesn't use the hash table unlink because
// it assumes that the literals are oops.
// This is done late during GC.
void
SymbolTable
::
unlink
()
{
int
removed
=
0
;
int
total
=
0
;
...
...
@@ -156,7 +157,7 @@ Symbol* SymbolTable::lookup(const char* name, int len, TRAPS) {
if
(
s
!=
NULL
)
return
s
;
// 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
)
{
...
...
@@ -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
// 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
,
...
...
@@ -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
,
unsigned
int
*
hashValues
,
TRAPS
)
{
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
);
if
(
!
added
)
{
// do it the hard way
for
(
int
i
=
0
;
i
<
names_count
;
i
++
)
{
int
index
=
table
->
hash_to_index
(
hashValues
[
i
]);
Symbol
*
sym
=
table
->
basic_add
(
index
,
(
u1
*
)
names
[
i
],
lengths
[
i
],
hashValues
[
i
]
,
CHECK
);
bool
c_heap
=
class_loader
()
!=
NULL
;
Symbol
*
sym
=
table
->
basic_add
(
index
,
(
u1
*
)
names
[
i
],
lengths
[
i
],
hashValues
[
i
],
c_heap
,
CHECK
);
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
,
unsigned
int
hashValue
,
TRAPS
)
{
unsigned
int
hashValue
,
bool
c_heap
,
TRAPS
)
{
assert
(
!
Universe
::
heap
()
->
is_in_reserved
(
name
)
||
GC_locker
::
is_active
(),
"proposed name of symbol must be stable"
);
// We assume that lookup() has been called already, that it failed,
// 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
// Grab SymbolTable_lock first.
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
// thread beat us in the race to insert the symbol.
Symbol
*
test
=
lookup
(
index
,
(
char
*
)
name
,
len
,
hashValue
);
if
(
test
!=
NULL
)
{
// A race occurred and another thread introduced the symbol, this one
// will be dropped and collected.
delete
sym
;
// A race occurred and another thread introduced the symbol.
assert
(
test
->
refcount
()
!=
0
,
"lookup should have incremented the count"
);
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
);
sym
->
increment_refcount
();
add_entry
(
index
,
entry
);
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
,
int
*
cp_indices
,
unsigned
int
*
hashValues
,
TRAPS
)
{
Symbol
*
syms
[
symbol_alloc_batch_size
];
bool
allocated
=
allocate_symbols
(
names_count
,
(
const
u1
**
)
names
,
lengths
,
syms
,
CHECK_false
);
if
(
!
allocated
)
{
return
false
;
// Check symbol names are not too long. If any are too long, don't add any.
for
(
int
i
=
0
;
i
<
names_count
;
i
++
)
{
if
(
lengths
[
i
]
>
Symbol
::
max_length
())
{
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
);
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
// thread beat us in the race to insert the symbol.
int
index
=
hash_to_index
(
hashValues
[
i
]);
...
...
@@ -330,16 +341,17 @@ bool SymbolTable::basic_add(constantPoolHandle cp, int names_count,
// will be dropped and collected. Use test instead.
cp
->
symbol_at_put
(
cp_indices
[
i
],
test
);
assert
(
test
->
refcount
()
!=
0
,
"lookup should have incremented the count"
);
delete
syms
[
i
];
}
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
);
sym
->
increment_refcount
();
// increment refcount in external hashtable
add_entry
(
index
,
entry
);
cp
->
symbol_at_put
(
cp_indices
[
i
],
sym
);
}
}
return
true
;
}
...
...
@@ -406,6 +418,8 @@ void SymbolTable::print_histogram() {
((
float
)
symbols_removed
/
(
float
)
symbols_counted
)
*
100
);
}
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
(
"%8s %5d"
,
"Total "
,
total
);
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.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -82,24 +82,24 @@ private:
static
int
symbols_removed
;
static
int
symbols_counted
;
Symbol
*
allocate_symbol
(
const
u1
*
name
,
int
len
,
TRAPS
);
// Assumes no characters larger than 0x7F
bool
allocate_symbols
(
int
names_count
,
const
u1
**
names
,
int
*
lengths
,
Symbol
**
syms
,
TRAPS
);
Symbol
*
allocate_symbol
(
const
u1
*
name
,
int
len
,
bool
c_heap
,
TRAPS
);
// Assumes no characters larger than 0x7F
// Adding elements
Symbol
*
basic_add
(
int
index
,
u1
*
name
,
int
len
,
unsigned
int
hashValue
,
TRAPS
);
bool
basic_add
(
constantPoolHandle
cp
,
int
names_count
,
Symbol
*
basic_add
(
int
index
,
u1
*
name
,
int
len
,
unsigned
int
hashValue
,
bool
c_heap
,
TRAPS
);
bool
basic_add
(
Handle
class_loader
,
constantPoolHandle
cp
,
int
names_count
,
const
char
**
names
,
int
*
lengths
,
int
*
cp_indices
,
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
,
int
*
cp_indices
,
unsigned
int
*
hashValues
,
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
enum
{
symbol_table_size
=
20011
...
...
@@ -114,10 +114,16 @@ private:
:
Hashtable
<
Symbol
*>
(
symbol_table_size
,
sizeof
(
HashtableEntry
<
Symbol
*>
),
t
,
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:
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
...
...
@@ -126,6 +132,7 @@ public:
static
void
create_table
()
{
assert
(
_the_table
==
NULL
,
"One symbol table allowed."
);
_the_table
=
new
SymbolTable
();
initialize_symbols
(
symbol_alloc_arena_size
);
}
static
void
create_table
(
HashtableBucket
*
t
,
int
length
,
...
...
@@ -134,6 +141,9 @@ public:
assert
(
length
==
symbol_table_size
*
sizeof
(
HashtableBucket
),
"bad shared symbol size."
);
_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
);
...
...
@@ -151,7 +161,7 @@ public:
static
Symbol
*
lookup_unicode
(
const
jchar
*
name
,
int
len
,
TRAPS
);
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
,
unsigned
int
*
hashValues
,
TRAPS
);
...
...
@@ -174,6 +184,9 @@ public:
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
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.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -79,7 +79,7 @@ void vmSymbols::initialize(TRAPS) {
if
(
!
UseSharedSpaces
)
{
const
char
*
string
=
&
vm_symbol_bodies
[
0
];
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
;
string
+=
strlen
(
string
);
// skip string body
string
+=
1
;
// skip trailing null
...
...
@@ -128,7 +128,7 @@ void vmSymbols::initialize(TRAPS) {
// Spot-check correspondence between strings, symbols, and enums:
assert
(
_symbols
[
NO_SID
]
==
NULL
,
"must be"
);
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
(
jlo
==
java_lang_Object
(),
""
);
SID
sid
=
VM_SYMBOL_ENUM_NAME
(
java_lang_Object
);
...
...
@@ -147,7 +147,7 @@ void vmSymbols::initialize(TRAPS) {
// The string "format" happens (at the moment) not to be a vmSymbol,
// though it is a method name in java.lang.String.
str
=
"format"
;
TempNewSymbol
fmt
=
SymbolTable
::
new_symbol
(
str
,
CHECK
);
TempNewSymbol
fmt
=
SymbolTable
::
new_
permanent_
symbol
(
str
,
CHECK
);
sid
=
find_sid
(
fmt
);
assert
(
sid
==
NO_SID
,
"symbol index works (negative test)"
);
}
...
...
src/share/vm/code/nmethod.hpp
浏览文件 @
05d15943
...
...
@@ -553,7 +553,7 @@ public:
static
void
oops_do_marking_prologue
();
static
void
oops_do_marking_epilogue
();
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
*
scope_desc_at
(
address
pc
);
...
...
src/share/vm/gc_implementation/g1/concurrentMark.cpp
浏览文件 @
05d15943
此差异已折叠。
点击以展开。
src/share/vm/gc_implementation/g1/concurrentMark.hpp
浏览文件 @
05d15943
...
...
@@ -42,9 +42,7 @@ typedef GenericTaskQueueSet<CMTaskQueue> CMTaskQueueSet;
class
G1CMIsAliveClosure
:
public
BoolObjectClosure
{
G1CollectedHeap
*
_g1
;
public:
G1CMIsAliveClosure
(
G1CollectedHeap
*
g1
)
:
_g1
(
g1
)
{}
G1CMIsAliveClosure
(
G1CollectedHeap
*
g1
)
:
_g1
(
g1
)
{
}
void
do_object
(
oop
obj
)
{
ShouldNotCallThis
();
...
...
@@ -111,11 +109,6 @@ class CMBitMapRO VALUE_OBJ_CLASS_SPEC {
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
NOT_PRODUCT
(
bool
covers
(
ReservedSpace
rs
)
const
;)
};
...
...
@@ -258,60 +251,6 @@ class CMMarkStack VALUE_OBJ_CLASS_SPEC {
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
{
private:
#ifndef PRODUCT
...
...
@@ -408,7 +347,6 @@ class ConcurrentMark : public CHeapObj {
friend
class
ConcurrentMarkThread
;
friend
class
CMTask
;
friend
class
CMBitMapClosure
;
friend
class
CSetMarkOopClosure
;
friend
class
CMGlobalObjectClosure
;
friend
class
CMRemarkTask
;
friend
class
CMConcurrentMarkingTask
;
...
...
@@ -443,7 +381,6 @@ protected:
CMBitMap
_markBitMap2
;
CMBitMapRO
*
_prevMarkBitMap
;
// completed mark bitmap
CMBitMap
*
_nextMarkBitMap
;
// under-construction mark bitmap
bool
_at_least_one_mark_complete
;
BitMap
_region_bm
;
BitMap
_card_bm
;
...
...
@@ -457,7 +394,6 @@ protected:
// For gray objects
CMMarkStack
_markStack
;
// Grey objects behind global finger.
CMRegionStack
_regionStack
;
// Grey regions behind global finger.
HeapWord
*
volatile
_finger
;
// the global finger, region aligned,
// always points to the end of the
// last claimed region
...
...
@@ -502,18 +438,6 @@ protected:
// 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.
NumberSeq
_init_times
;
NumberSeq
_remark_times
;
...
...
@@ -604,7 +528,7 @@ protected:
CMTaskQueueSet
*
task_queues
()
{
return
_task_queues
;
}
// 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
;
}
void
set_has_overflown
()
{
_has_overflown
=
true
;
}
void
clear_has_overflown
()
{
_has_overflown
=
false
;
}
...
...
@@ -684,68 +608,6 @@ public:
bool
mark_stack_overflow
()
{
return
_markStack
.
overflow
();
}
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
;
}
bool
concurrent_marking_in_progress
()
{
...
...
@@ -774,10 +636,6 @@ public:
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
();
...
...
@@ -810,22 +668,6 @@ public:
inline
void
grayRoot
(
oop
obj
,
size_t
word_size
,
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
// will dump the contents of its reference fields, as well as
// liveness information for the object and its referents. The dump
...
...
@@ -869,10 +711,6 @@ public:
// Do concurrent phase of marking, to a tentative transitive closure.
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
checkpointRootsFinalWork
();
void
cleanup
();
...
...
@@ -899,10 +737,6 @@ public:
_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 /
// global mark stack), enqueued SATB buffers, per-thread SATB
// buffers, and fingers (global / per-task). The boolean parameters
...
...
@@ -919,40 +753,6 @@ public:
// unless the force parameter is true.
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
{
assert
(
p
!=
NULL
&&
p
->
is_oop
(),
"expected an oop"
);
HeapWord
*
addr
=
(
HeapWord
*
)
p
;
...
...
@@ -1164,23 +964,6 @@ private:
// limit of the region this task is scanning, NULL if we're not scanning one
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
size_t
_words_scanned
;
// When _words_scanned reaches this limit, the regular clock is
...
...
@@ -1268,8 +1051,6 @@ private:
int
_global_transfers_to
;
int
_global_transfers_from
;
int
_region_stack_pops
;
int
_regions_claimed
;
int
_objs_found_on_bitmap
;
...
...
@@ -1347,15 +1128,6 @@ public:
bool
has_timed_out
()
{
return
_has_timed_out
;
}
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
);
// It grays the object by marking it and, if necessary, pushing it
...
...
@@ -1385,22 +1157,12 @@ public:
// buffers are available.
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
inline
void
move_finger_to
(
HeapWord
*
new_finger
)
{
assert
(
new_finger
>=
_finger
&&
new_finger
<
_region_limit
,
"invariant"
);
_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
,
size_t
*
marked_bytes
,
BitMap
*
card_bm
,
CMTaskQueue
*
task_queue
,
CMTaskQueueSet
*
task_queues
);
...
...
src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
浏览文件 @
05d15943
...
...
@@ -4355,7 +4355,8 @@ G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1,
_during_initial_mark
(
_g1
->
g1_policy
()
->
during_initial_mark_pause
()),
_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
HeapRegion
*
hr
=
_g1
->
heap_region_containing
(
obj
);
assert
(
hr
!=
NULL
,
"sanity"
);
...
...
@@ -4366,7 +4367,9 @@ void G1ParCopyHelper::mark_object(oop obj) {
_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
assert
(
from_obj
->
is_forwarded
(),
"from obj should be forwarded"
);
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) {
_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
();
HeapRegion
*
from_region
=
_g1
->
heap_region_containing_raw
(
old
);
// +1 to make the -1 indexes valid...
...
...
@@ -4457,8 +4462,8 @@ oop G1ParCopyHelper::copy_to_survivor_space(oop old) {
}
else
{
// No point in using the slower heap_region_containing() method,
// given that we know obj is in the heap.
_scanner
->
set_region
(
_g1
->
heap_region_containing_raw
(
obj
));
obj
->
oop_iterate_backwards
(
_scanner
);
_scanner
.
set_region
(
_g1
->
heap_region_containing_raw
(
obj
));
obj
->
oop_iterate_backwards
(
&
_scanner
);
}
}
else
{
_par_scan_state
->
undo_allocation
(
alloc_purpose
,
obj_ptr
,
word_sz
);
...
...
@@ -4675,67 +4680,74 @@ public:
double
start_time_ms
=
os
::
elapsedTime
()
*
1000.0
;
_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
);
G1ParScanHeapEvacClosure
scan_evac_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanHeapEvacFailureClosure
evac_failure_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanPartialArrayClosure
partial_scan_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanThreadState
pss
(
_g1h
,
worker_id
);
G1ParScanHeapEvacClosure
scan_evac_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanHeapEvacFailureClosure
evac_failure_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanPartialArrayClosure
partial_scan_cl
(
_g1h
,
&
pss
,
rp
);
pss
.
set_evac_closure
(
&
scan_evac_cl
);
pss
.
set_evac_failure_closure
(
&
evac_failure_cl
);
pss
.
set_partial_scan_closure
(
&
partial_scan_cl
);
pss
.
set_evac_closure
(
&
scan_evac_cl
);
pss
.
set_evac_failure_closure
(
&
evac_failure_cl
);
pss
.
set_partial_scan_closure
(
&
partial_scan_cl
);
G1ParScanExtRootClosure
only_scan_root_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanPermClosure
only_scan_perm_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanExtRootClosure
only_scan_root_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanPermClosure
only_scan_perm_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanAndMarkExtRootClosure
scan_mark_root_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanAndMarkPermClosure
scan_mark_perm_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanAndMarkExtRootClosure
scan_mark_root_cl
(
_g1h
,
&
pss
,
rp
);
G1ParScanAndMarkPermClosure
scan_mark_perm_cl
(
_g1h
,
&
pss
,
rp
);
OopClosure
*
scan_root_cl
=
&
only_scan_root_cl
;
OopsInHeapRegionClosure
*
scan_perm_cl
=
&
only_scan_perm_cl
;
OopClosure
*
scan_root_cl
=
&
only_scan_root_cl
;
OopsInHeapRegionClosure
*
scan_perm_cl
=
&
only_scan_perm_cl
;
if
(
_g1h
->
g1_policy
()
->
during_initial_mark_pause
())
{
// We also need to mark copied objects.
scan_root_cl
=
&
scan_mark_root_cl
;
scan_perm_cl
=
&
scan_mark_perm_cl
;
}
if
(
_g1h
->
g1_policy
()
->
during_initial_mark_pause
())
{
// We also need to mark copied objects.
scan_root_cl
=
&
scan_mark_root_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
();
_g1h
->
g1_process_strong_roots
(
/* not collecting perm */
false
,
SharedHeap
::
SO_AllClasses
,
scan_root_cl
,
&
push_heap_rs_cl
,
scan_perm_cl
,
worker_id
);
pss
.
end_strong_roots
();
pss
.
start_strong_roots
();
_g1h
->
g1_process_strong_roots
(
/* not collecting perm */
false
,
SharedHeap
::
SO_AllClasses
,
scan_root_cl
,
&
push_heap_rs_cl
,
scan_perm_cl
,
worker_id
);
pss
.
end_strong_roots
();
{
double
start
=
os
::
elapsedTime
();
G1ParEvacuateFollowersClosure
evac
(
_g1h
,
&
pss
,
_queues
,
&
_terminator
);
evac
.
do_void
();
double
elapsed_ms
=
(
os
::
elapsedTime
()
-
start
)
*
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_termination
(
worker_id
,
term_ms
,
pss
.
term_attempts
());
}
_g1h
->
g1_policy
()
->
record_thread_age_table
(
pss
.
age_table
());
_g1h
->
update_surviving_young_words
(
pss
.
surviving_young_words
()
+
1
);
{
double
start
=
os
::
elapsedTime
();
G1ParEvacuateFollowersClosure
evac
(
_g1h
,
&
pss
,
_queues
,
&
_terminator
);
evac
.
do_void
();
double
elapsed_ms
=
(
os
::
elapsedTime
()
-
start
)
*
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_termination
(
worker_id
,
term_ms
,
pss
.
term_attempts
());
}
_g1h
->
g1_policy
()
->
record_thread_age_table
(
pss
.
age_table
());
_g1h
->
update_surviving_young_words
(
pss
.
surviving_young_words
()
+
1
);
// Clean up any par-expanded rem sets.
HeapRegionRemSet
::
par_cleanup
();
// Clean up any par-expanded rem sets.
HeapRegionRemSet
::
par_cleanup
();
if
(
ParallelGCVerbose
)
{
MutexLocker
x
(
stats_lock
());
pss
.
print_termination_stats
(
worker_id
);
if
(
ParallelGCVerbose
)
{
MutexLocker
x
(
stats_lock
());
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
;
_g1h
->
g1_policy
()
->
record_gc_worker_end_time
(
worker_id
,
end_time_ms
);
}
...
...
@@ -4743,6 +4755,67 @@ public:
// *** 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.
void
...
...
@@ -4764,7 +4837,7 @@ g1_process_strong_roots(bool collecting_perm_gen,
// Walk the code cache w/o buffering, because StarTask cannot handle
// 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
collecting_perm_gen
,
so
,
...
...
@@ -5378,25 +5451,39 @@ void G1CollectedHeap::evacuate_collection_set() {
rem_set
()
->
prepare_for_younger_refs_iterate
(
true
);
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
);
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
;
g1_policy
()
->
record_par_time
(
par_time
);
double
par_time_ms
=
(
end_par_time_sec
-
start_par_time_sec
)
*
1000.0
;
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
);
...
...
src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
浏览文件 @
05d15943
...
...
@@ -199,7 +199,8 @@ class G1CollectedHeap : public SharedHeap {
friend
class
OldGCAllocRegion
;
// 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
G1EvacuateFollowersClosure
;
friend
class
G1ParScanThreadState
;
...
...
@@ -1676,202 +1677,6 @@ protected:
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
{
private:
bool
_retired
;
...
...
src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
浏览文件 @
05d15943
...
...
@@ -140,7 +140,6 @@ G1CollectorPolicy::G1CollectorPolicy() :
_summary
(
new
Summary
()),
_cur_clear_ct_time_ms
(
0.0
),
_mark_closure_time_ms
(
0.0
),
_root_region_scan_wait_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,
_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
// pause if we actually waited for the root region scanning to finish.
_root_region_scan_wait_time_ms
=
0.0
;
...
...
@@ -1246,11 +1242,6 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
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
// zero at the start of the pause.
other_time_ms
-=
_root_region_scan_wait_time_ms
;
...
...
@@ -1261,15 +1252,13 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
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
// current value of "other time"
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.
_all_pause_times_ms
->
add
(
elapsed_ms
);
...
...
@@ -1280,16 +1269,8 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
MainBodySummary
*
body_summary
=
_summary
->
main_body_summary
();
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
(
_root_region_scan_wait_time_ms
);
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_update_rs_time_ms
(
update_rs_time
);
...
...
@@ -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_mark_closure_time_ms
(
_mark_closure_time_ms
);
body_summary
->
record_clear_ct_time_ms
(
_cur_clear_ct_time_ms
);
// 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) {
print_par_stats
(
2
,
"Object Copy"
,
_par_last_obj_copy_times_ms
);
print_par_stats
(
2
,
"Termination"
,
_par_last_termination_times_ms
);
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
++
)
{
_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
]
+
_par_last_satb_filtering_times_ms
[
i
]
+
...
...
@@ -1413,10 +1393,13 @@ void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
_par_last_obj_copy_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 Total"
,
_par_last_gc_worker_times_ms
);
print_par_stats
(
2
,
"GC Worker End"
,
_par_last_gc_worker_end_times_ms
);
}
else
{
print_stats
(
1
,
"Ext Root Scanning"
,
ext_root_scan_time
);
if
(
print_marking_info
)
{
...
...
@@ -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
,
"Object Copying"
,
obj_copy_time
);
}
if
(
print_marking_info
)
{
print_stats
(
1
,
"Complete CSet Marking"
,
_mark_closure_time_ms
);
}
print_stats
(
1
,
"Code Root Fixup"
,
_cur_collection_code_root_fixup_time_ms
);
print_stats
(
1
,
"Clear CT"
,
_cur_clear_ct_time_ms
);
#ifndef PRODUCT
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) {
}
double
all_other_time_ms
=
pause_time_ms
-
(
update_rs_time
+
scan_rs_time
+
obj_copy_time
+
_mark_closure_time_ms
+
termination_time
);
(
update_rs_time
+
scan_rs_time
+
obj_copy_time
+
termination_time
);
double
young_other_time_ms
=
0.0
;
if
(
young_cset_region_length
()
>
0
)
{
...
...
@@ -1705,41 +1685,6 @@ void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time,
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
G1CollectorPolicy
::
predict_base_elapsed_time_ms
(
size_t
pending_cards
)
{
size_t
rs_length
=
predict_rs_length_diff
();
...
...
@@ -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
,
"Mark Closure"
,
body_summary
->
get_mark_closure_seq
());
print_summary
(
1
,
"Clear CT"
,
body_summary
->
get_clear_ct_seq
());
print_summary
(
1
,
"Other"
,
summary
->
get_other_seq
());
{
...
...
@@ -1982,17 +1926,15 @@ void G1CollectorPolicy::print_summary(PauseSummary* summary) const {
if
(
parallel
)
{
// parallel
NumberSeq
*
other_parts
[]
=
{
body_summary
->
get_satb_drain_seq
(),
body_summary
->
get_root_region_scan_wait_seq
(),
body_summary
->
get_parallel_seq
(),
body_summary
->
get_clear_ct_seq
()
};
calc_other_times_ms
=
NumberSeq
(
summary
->
get_total_seq
(),
4
,
other_parts
);
3
,
other_parts
);
}
else
{
// serial
NumberSeq
*
other_parts
[]
=
{
body_summary
->
get_satb_drain_seq
(),
body_summary
->
get_root_region_scan_wait_seq
(),
body_summary
->
get_update_rs_seq
(),
body_summary
->
get_ext_root_scan_seq
(),
...
...
@@ -2001,7 +1943,7 @@ void G1CollectorPolicy::print_summary(PauseSummary* summary) const {
body_summary
->
get_obj_copy_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
);
}
...
...
src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
浏览文件 @
05d15943
...
...
@@ -64,7 +64,6 @@ public:
};
class
MainBodySummary
:
public
CHeapObj
{
define_num_seq
(
satb_drain
)
// optional
define_num_seq
(
root_region_scan_wait
)
define_num_seq
(
parallel
)
// parallel only
define_num_seq
(
ext_root_scan
)
...
...
@@ -74,7 +73,6 @@ class MainBodySummary: public CHeapObj {
define_num_seq
(
obj_copy
)
define_num_seq
(
termination
)
// parallel only
define_num_seq
(
parallel_other
)
// parallel only
define_num_seq
(
mark_closure
)
define_num_seq
(
clear_ct
)
};
...
...
@@ -179,7 +177,9 @@ private:
size_t
_cur_collection_pause_used_at_start_bytes
;
size_t
_cur_collection_pause_used_regions_at_start
;
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_ref_proc_time_ms
;
double
_cur_ref_enq_time_ms
;
...
...
@@ -226,8 +226,8 @@ private:
double
*
_par_last_gc_worker_times_ms
;
// Each workers 'other' time i.e. the elapsed time of the parallel
//
phase of the pause
minus the sum of the individual sub-phase
// times for
a given
worker thread.
//
code executed by a worker
minus the sum of the individual sub-phase
// times for
that
worker thread.
double
*
_par_last_gc_worker_other_times_ms
;
// indicates whether we are in young or mixed GC mode
...
...
@@ -488,7 +488,6 @@ public:
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
,
size_t
scanned_cards
);
...
...
@@ -709,7 +708,6 @@ private:
double
_cur_mark_stop_world_time_ms
;
double
_mark_remark_start_sec
;
double
_mark_cleanup_start_sec
;
double
_mark_closure_time_ms
;
double
_root_region_scan_wait_time_ms
;
// Update the young list target length either by setting it to the
...
...
@@ -809,10 +807,6 @@ public:
void
record_concurrent_mark_init_end
(
double
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
)
{
_root_region_scan_wait_time_ms
=
time_ms
;
}
...
...
@@ -846,11 +840,6 @@ public:
_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
)
{
_par_last_update_rs_times_ms
[
thread
]
=
ms
;
}
...
...
@@ -897,6 +886,10 @@ public:
_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
)
{
guarantee
(
i
<
_aux_num
,
"should be within range"
);
_cur_aux_start_times_ms
[
i
]
=
os
::
elapsedTime
()
*
1000.0
;
...
...
src/share/vm/gc_implementation/g1/g1OopClosures.hpp
浏览文件 @
05d15943
...
...
@@ -118,9 +118,11 @@ public:
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:
// 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
...
...
@@ -134,23 +136,11 @@ protected:
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:
G1ParCopyClosure
(
G1CollectedHeap
*
g1
,
G1ParScanThreadState
*
par_scan_state
,
ReferenceProcessor
*
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"
);
}
...
...
src/share/vm/gc_implementation/g1/g1_globals.hpp
浏览文件 @
05d15943
...
...
@@ -69,9 +69,6 @@
diagnostic(bool, G1TraceConcRefinement, false, \
"Trace G1 concurrent refinement") \
\
product(intx, G1MarkRegionStackSize, 1024 * 1024, \
"Size of the region stack for concurrent marking.") \
\
product(double, G1ConcMarkStepDurationMillis, 10.0, \
"Target duration of individual concurrent marking steps " \
"in milliseconds.") \
...
...
src/share/vm/gc_implementation/g1/heapRegion.hpp
浏览文件 @
05d15943
...
...
@@ -373,10 +373,9 @@ class HeapRegion: public G1OffsetTableContigSpace {
ScrubRemSetClaimValue
=
3
,
ParVerifyClaimValue
=
4
,
RebuildRSClaimValue
=
5
,
CompleteMarkCSetClaimValue
=
6
,
ParEvacFailureClaimValue
=
7
,
AggregateCountClaimValue
=
8
,
VerifyCountClaimValue
=
9
ParEvacFailureClaimValue
=
6
,
AggregateCountClaimValue
=
7
,
VerifyCountClaimValue
=
8
};
inline
HeapWord
*
par_allocate_no_bot_updates
(
size_t
word_size
)
{
...
...
src/share/vm/memory/barrierSet.hpp
浏览文件 @
05d15943
...
...
@@ -181,6 +181,8 @@ public:
// within the heap, this function tells whether they are met.
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
src/share/vm/memory/cardTableModRefBS.cpp
浏览文件 @
05d15943
...
...
@@ -711,6 +711,11 @@ void CardTableModRefBS::verify_dirty_region(MemRegion mr) {
}
#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
)
{
return
CardTableModRefBS
::
card_will_be_scanned
(
cv
)
||
...
...
src/share/vm/memory/cardTableModRefBS.hpp
浏览文件 @
05d15943
...
...
@@ -472,6 +472,9 @@ public:
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_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.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -1488,12 +1488,11 @@ void GenCollectedHeap::preload_and_dump(TRAPS) {
// sun.io.Converters
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
static
const
char
map_entry_array_sig
[]
=
"[Ljava/util/Map$Entry;"
;
SymbolTable
::
lookup
(
map_entry_array_sig
,
(
int
)
strlen
(
map_entry_array_sig
),
THREAD
);
(
void
)
SymbolTable
::
new_permanent_symbol
(
map_entry_array_sig
,
THREAD
);
tty
->
print
(
"Loading classes to share ... "
);
while
((
fgets
(
class_name
,
sizeof
class_name
,
file
))
!=
NULL
)
{
...
...
@@ -1512,7 +1511,7 @@ void GenCollectedHeap::preload_and_dump(TRAPS) {
computed_jsum
=
jsum
(
computed_jsum
,
class_name
,
(
const
int
)
name_len
-
1
);
// 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."
);
klassOop
klass
=
SystemDictionary
::
resolve_or_null
(
class_name_symbol
,
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.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -137,7 +137,7 @@ klassOop objArrayKlassKlass::allocate_objArray_klass_impl(objArrayKlassKlassHand
new_str
[
idx
++
]
=
';'
;
}
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
())
{
instanceKlass
*
ik
=
instanceKlass
::
cast
(
element_klass
());
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.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -29,15 +29,25 @@
#include "runtime/os.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
();
for
(
int
i
=
0
;
i
<
_length
;
i
++
)
{
byte_at_put
(
i
,
name
[
i
]);
}
}
void
*
Symbol
::
operator
new
(
size_t
size
,
int
len
)
{
return
(
void
*
)
AllocateHeap
(
object_size
(
len
)
*
HeapWordSize
,
"symbol"
);
void
*
Symbol
::
operator
new
(
size_t
sz
,
int
len
,
TRAPS
)
{
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 {
}
}
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
);)
}
}
void
Symbol
::
decrement_refcount
()
{
if
(
_refcount
>=
0
)
{
Atomic
::
dec
(
&
_refcount
);
#ifdef ASSERT
if
(
_refcount
<
0
)
{
print
();
assert
(
false
,
"reference count underflow for symbol"
);
}
#endif
}
}
// SymbolTable prints this in its statistics
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.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -27,6 +27,7 @@
#include "utilities/utf8.hpp"
#include "memory/allocation.hpp"
#include "runtime/atomic.hpp"
// A Symbol is a canonicalized string.
// All Symbols reside in global SymbolTable and are reference counted.
...
...
@@ -95,7 +96,7 @@
// TempNewSymbol (passed in as a parameter) so the reference count on its symbol
// will be decremented when it goes out of scope.
class
Symbol
:
public
CHeap
Obj
{
class
Symbol
:
public
Resource
Obj
{
friend
class
VMStructs
;
friend
class
SymbolTable
;
friend
class
MoveSymbols
;
...
...
@@ -111,7 +112,7 @@ class Symbol : public CHeapObj {
};
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
);
}
...
...
@@ -120,28 +121,25 @@ class Symbol : public CHeapObj {
_body
[
index
]
=
value
;
}
Symbol
(
const
u1
*
name
,
int
length
);
void
*
operator
new
(
size_t
size
,
int
len
);
Symbol
(
const
u1
*
name
,
int
length
,
int
refcount
);
void
*
operator
new
(
size_t
size
,
int
len
,
TRAPS
);
void
*
operator
new
(
size_t
size
,
int
len
,
Arena
*
arena
,
TRAPS
);
public:
// Low-level access (used with care, since not GC-safe)
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.
static
int
max_length
()
{
return
max_symbol_length
;
}
static
int
max_length
()
{
return
max_symbol_length
;
}
int
identity_hash
()
{
return
_identity_hash
;
}
int
identity_hash
()
{
return
_identity_hash
;
}
// Reference counting. See comments above this class for when to use.
int
refcount
()
const
{
return
_refcount
;
}
void
increment_refcount
();
void
decrement_refcount
();
int
refcount
()
const
{
return
_refcount
;
}
inline
void
increment_refcount
();
inline
void
decrement_refcount
();
int
byte_at
(
int
index
)
const
{
assert
(
index
>=
0
&&
index
<
_length
,
"symbol index overflow"
);
...
...
@@ -220,4 +218,26 @@ int Symbol::fast_compare(Symbol* other) const {
return
(((
uintptr_t
)
this
<
(
uintptr_t
)
other
)
?
-
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
src/share/vm/oops/typeArrayKlass.cpp
浏览文件 @
05d15943
...
...
@@ -55,7 +55,7 @@ klassOop typeArrayKlass::create_klass(BasicType type, int scale,
Symbol
*
sym
=
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
());
...
...
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 @@
#include "precompiled.hpp"
#include "jni.h"
#include "memory/universe.hpp"
#include "oops/oop.inline.hpp"
#include "classfile/symbolTable.hpp"
#include "prims/whitebox.hpp"
#include "prims/wbtestmethods/parserTests.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/os.hpp"
#include "utilities/debug.hpp"
...
...
@@ -41,13 +44,6 @@
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
))
return
(
jlong
)(
void
*
)
JNIHandles
::
resolve
(
obj
);
WB_END
...
...
@@ -81,11 +77,63 @@ WB_ENTRY(jint, WB_G1RegionSize(JNIEnv* env, jobject o))
WB_END
#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*)
static
JNINativeMethod
methods
[]
=
{
{
CC
"getObjectAddress"
,
CC
"(Ljava/lang/Object;)J"
,
(
void
*
)
&
WB_GetObjectAddress
},
{
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
{
CC
"g1InConcurrentMark"
,
CC
"()Z"
,
(
void
*
)
&
WB_G1InConcurrentMark
},
{
CC
"g1IsHumongous"
,
CC
"(Ljava/lang/Object;)Z"
,
(
void
*
)
&
WB_G1IsHumongous
},
...
...
src/share/vm/prims/whitebox.hpp
浏览文件 @
05d15943
...
...
@@ -25,12 +25,29 @@
#ifndef 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
{
private:
static
bool
_used
;
public:
static
bool
used
()
{
return
_used
;
}
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
src/share/vm/runtime/globals.hpp
浏览文件 @
05d15943
...
...
@@ -3807,7 +3807,7 @@ class CommandLineFlags {
product(uintx, SharedReadOnlySize, 10*M, \
"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)") \
\
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) {
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
,
size_t
len
,
TRAPS
)
{
if
(
str
==
NULL
||
sscanf
(
str
,
INT64_FORMAT
,
&
_value
)
!=
1
)
{
...
...
src/share/vm/services/diagnosticArgument.hpp
浏览文件 @
05d15943
...
...
@@ -110,12 +110,20 @@ public:
virtual
void
init_value
(
TRAPS
)
=
0
;
virtual
void
reset
(
TRAPS
)
=
0
;
virtual
void
cleanup
()
=
0
;
virtual
void
value_as_str
(
char
*
buf
,
size_t
len
)
=
0
;
void
set_next
(
GenDCmdArgument
*
arg
)
{
_next
=
arg
;
}
GenDCmdArgument
*
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
{
...
...
@@ -143,6 +151,7 @@ public:
void
parse_value
(
const
char
*
str
,
size_t
len
,
TRAPS
);
void
init_value
(
TRAPS
);
void
destroy_value
();
void
value_as_str
(
char
*
buf
,
size_t
len
)
{
return
to_string
(
_value
,
buf
,
len
);}
};
#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
constructor_args
.
push_oop
(
gcInfo_instance
);
constructor_args
.
push_oop
(
getGcInfoBuilder
(
gcManager
,
THREAD
));
constructor_args
.
push_long
(
gcStatInfo
->
gc_index
());
constructor_args
.
push_long
(
gcStatInfo
->
start_time
(
));
constructor_args
.
push_long
(
gcStatInfo
->
end_time
(
));
constructor_args
.
push_long
(
Management
::
ticks_to_ms
(
gcStatInfo
->
start_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_after_gc_ah
);
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.
*
* 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) {
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
)
{
if
(
value
)
{
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.
*
* This code is free software; you can redistribute it and/or modify it
...
...
@@ -192,31 +192,6 @@ class BitMap VALUE_OBJ_CLASS_SPEC {
void
par_set_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
void
clear_large
();
inline
void
clear
();
...
...
src/share/vm/utilities/vmError.cpp
浏览文件 @
05d15943
...
...
@@ -685,6 +685,12 @@ void VMError::report(outputStream* st) {
// extended (i.e., more detailed) version.
Universe
::
print_on
(
st
,
true
/* extended */
);
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)"
)
...
...
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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录