Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
817c1633
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看板
提交
817c1633
编写于
1月 16, 2013
作者:
A
acorn
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
fd0689d0
ae54a79f
变更
34
隐藏空白更改
内联
并排
Showing
34 changed file
with
1087 addition
and
592 deletion
+1087
-592
agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java
...src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java
+13
-4
src/cpu/sparc/vm/vmStructs_sparc.hpp
src/cpu/sparc/vm/vmStructs_sparc.hpp
+5
-24
src/cpu/sparc/vm/vm_version_sparc.cpp
src/cpu/sparc/vm/vm_version_sparc.cpp
+7
-0
src/cpu/x86/vm/vmStructs_x86.hpp
src/cpu/x86/vm/vmStructs_x86.hpp
+5
-22
src/cpu/x86/vm/vm_version_x86.cpp
src/cpu/x86/vm/vm_version_x86.cpp
+7
-0
src/cpu/zero/vm/vmStructs_zero.hpp
src/cpu/zero/vm/vmStructs_zero.hpp
+4
-20
src/os/windows/vm/decoder_windows.cpp
src/os/windows/vm/decoder_windows.cpp
+75
-3
src/os/windows/vm/decoder_windows.hpp
src/os/windows/vm/decoder_windows.hpp
+2
-0
src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp
src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp
+6
-17
src/os_cpu/bsd_zero/vm/vmStructs_bsd_zero.hpp
src/os_cpu/bsd_zero/vm/vmStructs_bsd_zero.hpp
+4
-12
src/os_cpu/linux_sparc/vm/vmStructs_linux_sparc.hpp
src/os_cpu/linux_sparc/vm/vmStructs_linux_sparc.hpp
+7
-18
src/os_cpu/linux_x86/vm/vmStructs_linux_x86.hpp
src/os_cpu/linux_x86/vm/vmStructs_linux_x86.hpp
+6
-17
src/os_cpu/linux_zero/vm/vmStructs_linux_zero.hpp
src/os_cpu/linux_zero/vm/vmStructs_linux_zero.hpp
+4
-13
src/os_cpu/solaris_sparc/vm/vmStructs_solaris_sparc.hpp
src/os_cpu/solaris_sparc/vm/vmStructs_solaris_sparc.hpp
+7
-19
src/os_cpu/solaris_x86/vm/vmStructs_solaris_x86.hpp
src/os_cpu/solaris_x86/vm/vmStructs_solaris_x86.hpp
+6
-18
src/os_cpu/windows_x86/vm/vmStructs_windows_x86.hpp
src/os_cpu/windows_x86/vm/vmStructs_windows_x86.hpp
+6
-17
src/share/vm/classfile/classFileParser.cpp
src/share/vm/classfile/classFileParser.cpp
+430
-81
src/share/vm/classfile/classFileParser.hpp
src/share/vm/classfile/classFileParser.hpp
+20
-2
src/share/vm/classfile/placeholders.cpp
src/share/vm/classfile/placeholders.cpp
+7
-5
src/share/vm/classfile/placeholders.hpp
src/share/vm/classfile/placeholders.hpp
+6
-4
src/share/vm/classfile/systemDictionary.cpp
src/share/vm/classfile/systemDictionary.cpp
+57
-117
src/share/vm/classfile/vmSymbols.hpp
src/share/vm/classfile/vmSymbols.hpp
+4
-1
src/share/vm/memory/metaspaceShared.cpp
src/share/vm/memory/metaspaceShared.cpp
+37
-10
src/share/vm/oops/constMethod.hpp
src/share/vm/oops/constMethod.hpp
+6
-1
src/share/vm/oops/fieldInfo.hpp
src/share/vm/oops/fieldInfo.hpp
+135
-9
src/share/vm/oops/fieldStreams.hpp
src/share/vm/oops/fieldStreams.hpp
+17
-0
src/share/vm/oops/instanceKlass.hpp
src/share/vm/oops/instanceKlass.hpp
+13
-1
src/share/vm/prims/jvm.cpp
src/share/vm/prims/jvm.cpp
+26
-12
src/share/vm/runtime/globals.hpp
src/share/vm/runtime/globals.hpp
+13
-1
src/share/vm/runtime/java.cpp
src/share/vm/runtime/java.cpp
+4
-0
src/share/vm/runtime/reflection.cpp
src/share/vm/runtime/reflection.cpp
+9
-1
src/share/vm/runtime/thread.cpp
src/share/vm/runtime/thread.cpp
+0
-4
src/share/vm/runtime/vmStructs.cpp
src/share/vm/runtime/vmStructs.cpp
+137
-138
src/share/vm/utilities/exceptions.hpp
src/share/vm/utilities/exceptions.hpp
+2
-1
未找到文件。
agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java
浏览文件 @
817c1633
...
...
@@ -52,6 +52,8 @@ public class InstanceKlass extends Klass {
private
static
int
LOW_OFFSET
;
private
static
int
HIGH_OFFSET
;
private
static
int
FIELD_SLOTS
;
private
static
short
FIELDINFO_TAG_SIZE
;
private
static
short
FIELDINFO_TAG_OFFSET
;
// ClassState constants
private
static
int
CLASS_STATE_ALLOCATED
;
...
...
@@ -96,9 +98,12 @@ public class InstanceKlass extends Klass {
NAME_INDEX_OFFSET
=
db
.
lookupIntConstant
(
"FieldInfo::name_index_offset"
).
intValue
();
SIGNATURE_INDEX_OFFSET
=
db
.
lookupIntConstant
(
"FieldInfo::signature_index_offset"
).
intValue
();
INITVAL_INDEX_OFFSET
=
db
.
lookupIntConstant
(
"FieldInfo::initval_index_offset"
).
intValue
();
LOW_OFFSET
=
db
.
lookupIntConstant
(
"FieldInfo::low_offset"
).
intValue
();
HIGH_OFFSET
=
db
.
lookupIntConstant
(
"FieldInfo::high_offset"
).
intValue
();
LOW_OFFSET
=
db
.
lookupIntConstant
(
"FieldInfo::low_
packed_
offset"
).
intValue
();
HIGH_OFFSET
=
db
.
lookupIntConstant
(
"FieldInfo::high_
packed_
offset"
).
intValue
();
FIELD_SLOTS
=
db
.
lookupIntConstant
(
"FieldInfo::field_slots"
).
intValue
();
FIELDINFO_TAG_SIZE
=
db
.
lookupIntConstant
(
"FIELDINFO_TAG_SIZE"
).
shortValue
();
FIELDINFO_TAG_OFFSET
=
db
.
lookupIntConstant
(
"FIELDINFO_TAG_OFFSET"
).
shortValue
();
// read ClassState constants
CLASS_STATE_ALLOCATED
=
db
.
lookupIntConstant
(
"InstanceKlass::allocated"
).
intValue
();
CLASS_STATE_LOADED
=
db
.
lookupIntConstant
(
"InstanceKlass::loaded"
).
intValue
();
...
...
@@ -314,8 +319,12 @@ public class InstanceKlass extends Klass {
public
int
getFieldOffset
(
int
index
)
{
U2Array
fields
=
getFields
();
return
VM
.
getVM
().
buildIntFromShorts
(
fields
.
at
(
index
*
FIELD_SLOTS
+
LOW_OFFSET
),
fields
.
at
(
index
*
FIELD_SLOTS
+
HIGH_OFFSET
));
short
lo
=
fields
.
at
(
index
*
FIELD_SLOTS
+
LOW_OFFSET
);
short
hi
=
fields
.
at
(
index
*
FIELD_SLOTS
+
HIGH_OFFSET
);
if
((
lo
&
FIELDINFO_TAG_SIZE
)
==
FIELDINFO_TAG_OFFSET
)
{
return
VM
.
getVM
().
buildIntFromShorts
(
lo
,
hi
)
>>
FIELDINFO_TAG_SIZE
;
}
throw
new
RuntimeException
(
"should not reach here"
);
}
// Accessors for declared fields
...
...
src/cpu/sparc/vm/vmStructs_sparc.hpp
浏览文件 @
817c1633
...
...
@@ -29,7 +29,7 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field
, last_entry
) \
#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/
\
/* JavaCallWrapper */
\
...
...
@@ -37,22 +37,12 @@
/******************************/
\
/* JavaFrameAnchor */
\
/******************************/
\
volatile_nonstatic_field(JavaFrameAnchor, _flags, int) \
\
volatile_nonstatic_field(JavaFrameAnchor, _flags, int)
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_STRUCTS_OS_CPU macro (and must */
/* be present there) */
#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_TYPES_OS_CPU macro (and must */
/* be present there) */
#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
/******************************/
\
/* Register numbers (C2 only) */
\
/******************************/
\
...
...
@@ -90,15 +80,6 @@
declare_c2_constant(R_G6_num) \
declare_c2_constant(R_G7_num)
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_INT_CONSTANTS_OS_CPU macro (and must */
/* be present there) */
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and must */
/* be present there) */
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // CPU_SPARC_VM_VMSTRUCTS_SPARC_HPP
src/cpu/sparc/vm/vm_version_sparc.cpp
浏览文件 @
817c1633
...
...
@@ -259,6 +259,10 @@ void VM_Version::initialize() {
if
(
!
has_vis1
())
// Drop to 0 if no VIS1 support
UseVIS
=
0
;
if
(
FLAG_IS_DEFAULT
(
ContendedPaddingWidth
)
&&
(
cache_line_size
>
ContendedPaddingWidth
))
ContendedPaddingWidth
=
cache_line_size
;
#ifndef PRODUCT
if
(
PrintMiscellaneous
&&
Verbose
)
{
tty
->
print
(
"Allocation"
);
...
...
@@ -286,6 +290,9 @@ void VM_Version::initialize() {
if
(
PrefetchFieldsAhead
>
0
)
{
tty
->
print_cr
(
"PrefetchFieldsAhead %d"
,
PrefetchFieldsAhead
);
}
if
(
ContendedPaddingWidth
>
0
)
{
tty
->
print_cr
(
"ContendedPaddingWidth %d"
,
ContendedPaddingWidth
);
}
}
#endif // PRODUCT
}
...
...
src/cpu/x86/vm/vmStructs_x86.hpp
浏览文件 @
817c1633
...
...
@@ -29,7 +29,7 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field
, last_entry
) \
#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/
\
/* JavaCallWrapper */
\
...
...
@@ -37,31 +37,14 @@
/******************************/
\
/* JavaFrameAnchor */
\
/******************************/
\
volatile_nonstatic_field(JavaFrameAnchor, _last_Java_fp, intptr_t*) \
\
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_STRUCTS_OS_CPU macro (and must */
/* be present there) */
#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_TYPES_OS_CPU macro (and must */
/* be present there) */
volatile_nonstatic_field(JavaFrameAnchor, _last_Java_fp, intptr_t*)
#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_INT_CONSTANTS_OS_CPU macro (and must */
/* be present there) */
#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
#define VM_
LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
#define VM_
INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and must */
/* be present there) */
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // CPU_X86_VM_VMSTRUCTS_X86_HPP
src/cpu/x86/vm/vm_version_x86.cpp
浏览文件 @
817c1633
...
...
@@ -745,6 +745,10 @@ void VM_Version::get_processor_features() {
PrefetchFieldsAhead
=
prefetch_fields_ahead
();
#endif
if
(
FLAG_IS_DEFAULT
(
ContendedPaddingWidth
)
&&
(
cache_line_size
>
ContendedPaddingWidth
))
ContendedPaddingWidth
=
cache_line_size
;
#ifndef PRODUCT
if
(
PrintMiscellaneous
&&
Verbose
)
{
tty
->
print_cr
(
"Logical CPUs per core: %u"
,
...
...
@@ -791,6 +795,9 @@ void VM_Version::get_processor_features() {
if
(
PrefetchFieldsAhead
>
0
)
{
tty
->
print_cr
(
"PrefetchFieldsAhead %d"
,
PrefetchFieldsAhead
);
}
if
(
ContendedPaddingWidth
>
0
)
{
tty
->
print_cr
(
"ContendedPaddingWidth %d"
,
ContendedPaddingWidth
);
}
}
#endif // !PRODUCT
}
...
...
src/cpu/zero/vm/vmStructs_zero.hpp
浏览文件 @
817c1633
...
...
@@ -30,28 +30,12 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field
, last_entry) \
#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field
)
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_STRUCTS_OS_CPU macro (and must */
/* be present there) */
#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
#define VM_
TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
#define VM_
INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_TYPES_OS_CPU macro (and must */
/* be present there) */
#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_INT_CONSTANTS_OS_CPU macro (and must */
/* be present there) */
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and must */
/* be present there) */
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // CPU_ZERO_VM_VMSTRUCTS_ZERO_HPP
src/os/windows/vm/decoder_windows.cpp
浏览文件 @
817c1633
...
...
@@ -49,7 +49,7 @@ void WindowsDecoder::initialize() {
pfn_SymSetOptions
_pfnSymSetOptions
=
(
pfn_SymSetOptions
)
::
GetProcAddress
(
handle
,
"SymSetOptions"
);
pfn_SymInitialize
_pfnSymInitialize
=
(
pfn_SymInitialize
)
::
GetProcAddress
(
handle
,
"SymInitialize"
);
_pfnSymGetSymFromAddr64
=
(
pfn_SymGetSymFromAddr64
)
::
GetProcAddress
(
handle
,
"SymGetSymFromAddr64"
);
_pfnUndecorateSymbolName
=
(
pfn_UndecorateSymbolName
)
GetProcAddress
(
handle
,
"UnDecorateSymbolName"
);
_pfnUndecorateSymbolName
=
(
pfn_UndecorateSymbolName
)
::
GetProcAddress
(
handle
,
"UnDecorateSymbolName"
);
if
(
_pfnSymSetOptions
==
NULL
||
_pfnSymInitialize
==
NULL
||
_pfnSymGetSymFromAddr64
==
NULL
)
{
_pfnSymGetSymFromAddr64
=
NULL
;
...
...
@@ -60,8 +60,9 @@ void WindowsDecoder::initialize() {
return
;
}
_pfnSymSetOptions
(
SYMOPT_UNDNAME
|
SYMOPT_DEFERRED_LOADS
);
if
(
!
_pfnSymInitialize
(
GetCurrentProcess
(),
NULL
,
TRUE
))
{
HANDLE
hProcess
=
::
GetCurrentProcess
();
_pfnSymSetOptions
(
SYMOPT_UNDNAME
|
SYMOPT_DEFERRED_LOADS
|
SYMOPT_EXACT_SYMBOLS
);
if
(
!
_pfnSymInitialize
(
hProcess
,
NULL
,
TRUE
))
{
_pfnSymGetSymFromAddr64
=
NULL
;
_pfnUndecorateSymbolName
=
NULL
;
::
FreeLibrary
(
handle
);
...
...
@@ -70,6 +71,77 @@ void WindowsDecoder::initialize() {
return
;
}
// set pdb search paths
pfn_SymSetSearchPath
_pfn_SymSetSearchPath
=
(
pfn_SymSetSearchPath
)
::
GetProcAddress
(
handle
,
"SymSetSearchPath"
);
pfn_SymGetSearchPath
_pfn_SymGetSearchPath
=
(
pfn_SymGetSearchPath
)
::
GetProcAddress
(
handle
,
"SymGetSearchPath"
);
if
(
_pfn_SymSetSearchPath
!=
NULL
&&
_pfn_SymGetSearchPath
!=
NULL
)
{
char
paths
[
MAX_PATH
];
int
len
=
sizeof
(
paths
);
if
(
!
_pfn_SymGetSearchPath
(
hProcess
,
paths
,
len
))
{
paths
[
0
]
=
'\0'
;
}
else
{
// available spaces in path buffer
len
-=
(
int
)
strlen
(
paths
);
}
char
tmp_path
[
MAX_PATH
];
DWORD
dwSize
;
HMODULE
hJVM
=
::
GetModuleHandle
(
"jvm.dll"
);
tmp_path
[
0
]
=
'\0'
;
// append the path where jvm.dll is located
if
(
hJVM
!=
NULL
&&
(
dwSize
=
::
GetModuleFileName
(
hJVM
,
tmp_path
,
sizeof
(
tmp_path
)))
>
0
)
{
while
(
dwSize
>
0
&&
tmp_path
[
dwSize
]
!=
'\\'
)
{
dwSize
--
;
}
tmp_path
[
dwSize
]
=
'\0'
;
if
(
dwSize
>
0
&&
len
>
(
int
)
dwSize
+
1
)
{
strncat
(
paths
,
os
::
path_separator
(),
1
);
strncat
(
paths
,
tmp_path
,
dwSize
);
len
-=
dwSize
+
1
;
}
}
// append $JRE/bin. Arguments::get_java_home actually returns $JRE
// path
char
*
p
=
Arguments
::
get_java_home
();
assert
(
p
!=
NULL
,
"empty java home"
);
size_t
java_home_len
=
strlen
(
p
);
if
(
len
>
(
int
)
java_home_len
+
5
)
{
strncat
(
paths
,
os
::
path_separator
(),
1
);
strncat
(
paths
,
p
,
java_home_len
);
strncat
(
paths
,
"
\\
bin"
,
4
);
len
-=
(
int
)(
java_home_len
+
5
);
}
// append $JDK/bin path if it exists
assert
(
java_home_len
<
MAX_PATH
,
"Invalid path length"
);
// assume $JRE is under $JDK, construct $JDK/bin path and
// see if it exists or not
if
(
strncmp
(
&
p
[
java_home_len
-
3
],
"jre"
,
3
)
==
0
)
{
strncpy
(
tmp_path
,
p
,
java_home_len
-
3
);
tmp_path
[
java_home_len
-
3
]
=
'\0'
;
strncat
(
tmp_path
,
"bin"
,
3
);
// if the directory exists
DWORD
dwAttrib
=
GetFileAttributes
(
tmp_path
);
if
(
dwAttrib
!=
INVALID_FILE_ATTRIBUTES
&&
(
dwAttrib
&
FILE_ATTRIBUTE_DIRECTORY
))
{
// tmp_path should have the same length as java_home_len, since we only
// replaced 'jre' with 'bin'
if
(
len
>
(
int
)
java_home_len
+
1
)
{
strncat
(
paths
,
os
::
path_separator
(),
1
);
strncat
(
paths
,
tmp_path
,
java_home_len
);
}
}
}
_pfn_SymSetSearchPath
(
hProcess
,
paths
);
}
// find out if jvm.dll contains private symbols, by decoding
// current function and comparing the result
address
addr
=
(
address
)
Decoder
::
demangle
;
...
...
src/os/windows/vm/decoder_windows.hpp
浏览文件 @
817c1633
...
...
@@ -35,6 +35,8 @@ typedef DWORD (WINAPI *pfn_SymSetOptions)(DWORD);
typedef
BOOL
(
WINAPI
*
pfn_SymInitialize
)(
HANDLE
,
PCTSTR
,
BOOL
);
typedef
BOOL
(
WINAPI
*
pfn_SymGetSymFromAddr64
)(
HANDLE
,
DWORD64
,
PDWORD64
,
PIMAGEHLP_SYMBOL64
);
typedef
DWORD
(
WINAPI
*
pfn_UndecorateSymbolName
)(
const
char
*
,
char
*
,
DWORD
,
DWORD
);
typedef
BOOL
(
WINAPI
*
pfn_SymSetSearchPath
)(
HANDLE
,
PCTSTR
);
typedef
BOOL
(
WINAPI
*
pfn_SymGetSearchPath
)(
HANDLE
,
PTSTR
,
int
);
class
WindowsDecoder
:
public
AbstractDecoder
{
...
...
src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp
浏览文件 @
817c1633
...
...
@@ -29,37 +29,26 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field
, last_entry
) \
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/
\
/* Threads (NOTE: incomplete) */
\
/******************************/
\
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
nonstatic_field(OSThread, _pthread_id, pthread_t) \
/* This must be the last entry, and must be present */
\
last_entry()
nonstatic_field(OSThread, _pthread_id, pthread_t)
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type
, last_entry
) \
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
\
/**********************/
\
/* Posix Thread IDs */
\
/**********************/
\
\
declare_unsigned_integer_type(OSThread::thread_id_t) \
declare_unsigned_integer_type(pthread_t) \
\
/* This must be the last entry, and must be present */
\
last_entry()
declare_unsigned_integer_type(pthread_t)
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
\
/* This must be the last entry, and must be present */
\
last_entry()
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
\
/* This must be the last entry, and must be present */
\
last_entry()
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_BSD_X86_VM_VMSTRUCTS_BSD_X86_HPP
src/os_cpu/bsd_zero/vm/vmStructs_bsd_zero.hpp
浏览文件 @
817c1633
...
...
@@ -30,21 +30,13 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
/* This must be the last entry, and must be present */
\
last_entry()
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field)
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
/* This must be the last entry, and must be present */
\
last_entry()
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
/* This must be the last entry, and must be present */
\
last_entry()
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
/* This must be the last entry, and must be present */
\
last_entry()
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_BSD_ZERO_VM_VMSTRUCTS_BSD_ZERO_HPP
src/os_cpu/linux_sparc/vm/vmStructs_linux_sparc.hpp
浏览文件 @
817c1633
...
...
@@ -29,7 +29,7 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field
, last_entry
) \
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/
\
/* Threads (NOTE: incomplete) */
\
...
...
@@ -37,38 +37,27 @@
\
nonstatic_field(JavaThread, _base_of_stack_pointer, intptr_t*) \
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
nonstatic_field(OSThread, _pthread_id, pthread_t) \
/* This must be the last entry, and must be present */
\
last_entry()
nonstatic_field(OSThread, _pthread_id, pthread_t)
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type
, last_entry
) \
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
\
/**********************/
\
/* POSIX Thread IDs */
\
/**********************/
\
\
declare_integer_type(OSThread::thread_id_t) \
declare_unsigned_integer_type(pthread_t) \
\
/* This must be the last entry, and must be present */
\
last_entry()
declare_unsigned_integer_type(pthread_t)
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant
, last_entry
) \
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
\
/************************/
\
/* JavaThread constants */
\
/************************/
\
\
declare_constant(JavaFrameAnchor::flushed) \
\
/* This must be the last entry, and must be present */
\
last_entry()
declare_constant(JavaFrameAnchor::flushed)
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
\
/* This must be the last entry, and must be present */
\
last_entry()
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_LINUX_SPARC_VM_VMSTRUCTS_LINUX_SPARC_HPP
src/os_cpu/linux_x86/vm/vmStructs_linux_x86.hpp
浏览文件 @
817c1633
...
...
@@ -29,37 +29,26 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field
, last_entry
) \
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/
\
/* Threads (NOTE: incomplete) */
\
/******************************/
\
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
nonstatic_field(OSThread, _pthread_id, pthread_t) \
/* This must be the last entry, and must be present */
\
last_entry()
nonstatic_field(OSThread, _pthread_id, pthread_t)
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type
, last_entry
) \
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
\
/**********************/
\
/* Posix Thread IDs */
\
/**********************/
\
\
declare_integer_type(OSThread::thread_id_t) \
declare_unsigned_integer_type(pthread_t) \
\
/* This must be the last entry, and must be present */
\
last_entry()
declare_unsigned_integer_type(pthread_t)
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
\
/* This must be the last entry, and must be present */
\
last_entry()
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
\
/* This must be the last entry, and must be present */
\
last_entry()
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_LINUX_X86_VM_VMSTRUCTS_LINUX_X86_HPP
src/os_cpu/linux_zero/vm/vmStructs_linux_zero.hpp
浏览文件 @
817c1633
...
...
@@ -30,21 +30,12 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
/* This must be the last entry, and must be present */
\
last_entry()
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field)
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
/* This must be the last entry, and must be present */
\
last_entry()
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
/* This must be the last entry, and must be present */
\
last_entry()
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
/* This must be the last entry, and must be present */
\
last_entry()
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_LINUX_ZERO_VM_VMSTRUCTS_LINUX_ZERO_HPP
src/os_cpu/solaris_sparc/vm/vmStructs_solaris_sparc.hpp
浏览文件 @
817c1633
...
...
@@ -29,44 +29,32 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field
, last_entry
) \
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/
\
/* Threads (NOTE: incomplete) */
\
/******************************/
\
\
nonstatic_field(JavaThread, _base_of_stack_pointer, intptr_t*) \
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
/* This must be the last entry, and must be present */
\
last_entry()
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t)
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
\
/**********************/
\
/* Solaris Thread IDs */
\
/**********************/
\
\
declare_unsigned_integer_type(OSThread::thread_id_t) \
\
/* This must be the last entry, and must be present */
\
last_entry()
declare_unsigned_integer_type(OSThread::thread_id_t)
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant
, last_entry
) \
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
\
/************************/
\
/* JavaThread constants */
\
/************************/
\
\
declare_constant(JavaFrameAnchor::flushed) \
\
/* This must be the last entry, and must be present */
\
last_entry()
declare_constant(JavaFrameAnchor::flushed)
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
\
/* This must be the last entry, and must be present */
\
last_entry()
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_SOLARIS_SPARC_VM_VMSTRUCTS_SOLARIS_SPARC_HPP
src/os_cpu/solaris_x86/vm/vmStructs_solaris_x86.hpp
浏览文件 @
817c1633
...
...
@@ -29,36 +29,24 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field
, last_entry
) \
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/
\
/* Threads (NOTE: incomplete) */
\
/******************************/
\
\
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
\
/* This must be the last entry, and must be present */
\
last_entry()
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t)
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type
, last_entry
) \
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
\
/**********************/
\
/* Solaris Thread IDs */
\
/**********************/
\
\
declare_unsigned_integer_type(OSThread::thread_id_t) \
\
/* This must be the last entry, and must be present */
\
last_entry()
declare_unsigned_integer_type(OSThread::thread_id_t)
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
\
/* This must be the last entry, and must be present */
\
last_entry()
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
\
/* This must be the last entry, and must be present */
\
last_entry()
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_SOLARIS_X86_VM_VMSTRUCTS_SOLARIS_X86_HPP
src/os_cpu/windows_x86/vm/vmStructs_windows_x86.hpp
浏览文件 @
817c1633
...
...
@@ -29,32 +29,21 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field
, last_entry
) \
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/
\
/* Threads (NOTE: incomplete) */
\
/******************************/
\
\
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
unchecked_nonstatic_field(OSThread, _thread_handle, sizeof(HANDLE))
/* NOTE: no type */
\
\
/* This must be the last entry, and must be present */
\
last_entry()
unchecked_nonstatic_field(OSThread, _thread_handle, sizeof(HANDLE))
/* NOTE: no type */
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type
, last_entry
) \
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
\
declare_unsigned_integer_type(OSThread::thread_id_t) \
/* This must be the last entry, and must be present */
\
last_entry()
declare_unsigned_integer_type(OSThread::thread_id_t)
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
\
/* This must be the last entry, and must be present */
\
last_entry()
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
\
/* This must be the last entry, and must be present */
\
last_entry()
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_WINDOWS_X86_VM_VMSTRUCTS_WINDOWS_X86_HPP
src/share/vm/classfile/classFileParser.cpp
浏览文件 @
817c1633
/*
* Copyright (c) 1997, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
3
, 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
...
...
@@ -59,6 +59,7 @@
#include "services/classLoadingService.hpp"
#include "services/threadService.hpp"
#include "utilities/array.hpp"
#include "utilities/globalDefinitions.hpp"
// We generally try to create the oops directly when parsing, rather than
// allocating temporary data structures and copying the bytes twice. A
...
...
@@ -970,6 +971,12 @@ void ClassFileParser::parse_field_attributes(ClassLoaderData* loader_data,
runtime_visible_annotations_length
=
attribute_length
;
runtime_visible_annotations
=
cfs
->
get_u1_buffer
();
assert
(
runtime_visible_annotations
!=
NULL
,
"null visible annotations"
);
parse_annotations
(
loader_data
,
runtime_visible_annotations
,
runtime_visible_annotations_length
,
cp
,
parsed_annotations
,
CHECK
);
cfs
->
skip_u1
(
runtime_visible_annotations_length
,
CHECK
);
}
else
if
(
PreserveAllAnnotations
&&
attribute_name
==
vmSymbols
::
tag_runtime_invisible_annotations
())
{
runtime_invisible_annotations_length
=
attribute_length
;
...
...
@@ -1216,19 +1223,16 @@ Array<u2>* ClassFileParser::parse_fields(ClassLoaderData* loader_data,
field
->
initialize
(
access_flags
.
as_short
(),
name_index
,
signature_index
,
constantvalue_index
,
0
);
if
(
parsed_annotations
.
has_any_annotations
())
parsed_annotations
.
apply_to
(
field
);
constantvalue_index
);
BasicType
type
=
cp
->
basic_type_for_signature_at
(
signature_index
);
// Remember how many oops we encountered and compute allocation type
FieldAllocationType
atype
=
fac
->
update
(
is_static
,
type
);
field
->
set_allocation_type
(
atype
);
//
The correct offset is computed later (all oop fields will be located together)
// We temporarily store the allocation type in the offset field
field
->
set_offset
(
atype
);
//
After field is initialized with type, we can augment it with aux info
if
(
parsed_annotations
.
has_any_annotations
())
parsed_annotations
.
apply_to
(
field
);
}
int
index
=
length
;
...
...
@@ -1259,17 +1263,13 @@ Array<u2>* ClassFileParser::parse_fields(ClassLoaderData* loader_data,
field
->
initialize
(
JVM_ACC_FIELD_INTERNAL
,
injected
[
n
].
name_index
,
injected
[
n
].
signature_index
,
0
,
0
);
BasicType
type
=
FieldType
::
basic_type
(
injected
[
n
].
signature
());
// Remember how many oops we encountered and compute allocation type
FieldAllocationType
atype
=
fac
->
update
(
false
,
type
);
// The correct offset is computed later (all oop fields will be located together)
// We temporarily store the allocation type in the offset field
field
->
set_offset
(
atype
);
field
->
set_allocation_type
(
atype
);
index
++
;
}
}
...
...
@@ -1735,7 +1735,8 @@ int ClassFileParser::skip_annotation_value(u1* buffer, int limit, int index) {
}
// Sift through annotations, looking for those significant to the VM:
void
ClassFileParser
::
parse_annotations
(
u1
*
buffer
,
int
limit
,
void
ClassFileParser
::
parse_annotations
(
ClassLoaderData
*
loader_data
,
u1
*
buffer
,
int
limit
,
constantPoolHandle
cp
,
ClassFileParser
::
AnnotationCollector
*
coll
,
TRAPS
)
{
...
...
@@ -1752,9 +1753,12 @@ void ClassFileParser::parse_annotations(u1* buffer, int limit,
e_type_off
=
7
,
// utf8 such as 'Ljava/lang/annotation/RetentionPolicy;'
e_con_off
=
9
,
// utf8 payload, such as 'SOURCE', 'CLASS', 'RUNTIME'
e_size
=
11
,
// end of 'e' annotation
c_tag_val
=
'c'
,
c_con_off
=
7
,
// utf8 payload, such as 'I'
or 'Ljava/lang/String;'
c_tag_val
=
'c'
,
// payload is type
c_con_off
=
7
,
// utf8 payload, such as 'I'
c_size
=
9
,
// end of 'c' annotation
s_tag_val
=
's'
,
// payload is String
s_con_off
=
7
,
// utf8 payload, such as 'Ljava/lang/String;'
s_size
=
9
,
min_size
=
6
// smallest possible size (zero members)
};
while
((
--
nann
)
>=
0
&&
(
index
-
2
+
min_size
<=
limit
))
{
...
...
@@ -1773,57 +1777,65 @@ void ClassFileParser::parse_annotations(u1* buffer, int limit,
}
// Here is where parsing particular annotations will take place.
AnnotationCollector
::
ID
id
=
coll
->
annotation_index
(
aname
);
AnnotationCollector
::
ID
id
=
coll
->
annotation_index
(
loader_data
,
aname
);
if
(
id
==
AnnotationCollector
::
_unknown
)
continue
;
coll
->
set_annotation
(
id
);
// If there are no values, just set the bit and move on:
if
(
count
==
0
)
continue
;
// For the record, here is how annotation payloads can be collected.
// Suppose we want to capture @Retention.value. Here is how:
//if (id == AnnotationCollector::_class_Retention) {
// Symbol* payload = NULL;
// if (count == 1
// && e_size == (index0 - index) // match size
// && e_tag_val == *(abase + tag_off)
// && (check_symbol_at(cp, Bytes::get_Java_u2(abase + e_type_off))
// == vmSymbols::RetentionPolicy_signature())
// && member == vmSymbols::value_name()) {
// payload = check_symbol_at(cp, Bytes::get_Java_u2(abase + e_con_off));
// }
// check_property(payload != NULL,
// "Invalid @Retention annotation at offset %u in class file %s",
// index0, CHECK);
// if (payload != NULL) {
// payload->increment_refcount();
// coll->_class_RetentionPolicy = payload;
// }
//}
if
(
id
==
AnnotationCollector
::
_sun_misc_Contended
)
{
if
(
count
==
1
&&
s_size
==
(
index
-
index0
)
// match size
&&
s_tag_val
==
*
(
abase
+
tag_off
)
&&
member
==
vmSymbols
::
value_name
())
{
u2
group_index
=
Bytes
::
get_Java_u2
(
abase
+
s_con_off
);
coll
->
set_contended_group
(
group_index
);
}
else
{
coll
->
set_contended_group
(
0
);
// default contended group
}
coll
->
set_contended
(
true
);
}
else
{
coll
->
set_contended
(
false
);
}
}
}
ClassFileParser
::
AnnotationCollector
::
ID
ClassFileParser
::
AnnotationCollector
::
annotation_index
(
Symbol
*
name
)
{
ClassFileParser
::
AnnotationCollector
::
ID
ClassFileParser
::
AnnotationCollector
::
annotation_index
(
ClassLoaderData
*
loader_data
,
Symbol
*
name
)
{
vmSymbols
::
SID
sid
=
vmSymbols
::
find_sid
(
name
);
bool
privileged
=
false
;
if
(
loader_data
->
is_the_null_class_loader_data
())
{
// Privileged code can use all annotations. Other code silently drops some.
privileged
=
true
;
}
switch
(
sid
)
{
case
vmSymbols
::
VM_SYMBOL_ENUM_NAME
(
java_lang_invoke_ForceInline_signature
):
if
(
_location
!=
_in_method
)
break
;
// only allow for methods
if
(
!
privileged
)
break
;
// only allow in privileged code
return
_method_ForceInline
;
case
vmSymbols
::
VM_SYMBOL_ENUM_NAME
(
java_lang_invoke_DontInline_signature
):
if
(
_location
!=
_in_method
)
break
;
// only allow for methods
if
(
!
privileged
)
break
;
// only allow in privileged code
return
_method_DontInline
;
case
vmSymbols
::
VM_SYMBOL_ENUM_NAME
(
java_lang_invoke_LambdaForm_Compiled_signature
):
if
(
_location
!=
_in_method
)
break
;
// only allow for methods
if
(
!
privileged
)
break
;
// only allow in privileged code
return
_method_LambdaForm_Compiled
;
case
vmSymbols
::
VM_SYMBOL_ENUM_NAME
(
java_lang_invoke_LambdaForm_Hidden_signature
):
if
(
_location
!=
_in_method
)
break
;
// only allow for methods
if
(
!
privileged
)
break
;
// only allow in privileged code
return
_method_LambdaForm_Hidden
;
case
vmSymbols
::
VM_SYMBOL_ENUM_NAME
(
sun_misc_Contended_signature
):
if
(
_location
!=
_in_field
&&
_location
!=
_in_class
)
break
;
// only allow for fields and classes
if
(
!
EnableContended
||
(
RestrictContended
&&
!
privileged
))
break
;
// honor privileges
return
_sun_misc_Contended
;
default:
break
;
}
return
AnnotationCollector
::
_unknown
;
}
void
ClassFileParser
::
FieldAnnotationCollector
::
apply_to
(
FieldInfo
*
f
)
{
fatal
(
"no field annotations yet"
);
if
(
is_contended
())
f
->
set_contended_group
(
contended_group
());
}
void
ClassFileParser
::
MethodAnnotationCollector
::
apply_to
(
methodHandle
m
)
{
...
...
@@ -1838,7 +1850,7 @@ void ClassFileParser::MethodAnnotationCollector::apply_to(methodHandle m) {
}
void
ClassFileParser
::
ClassAnnotationCollector
::
apply_to
(
instanceKlassHandle
k
)
{
fatal
(
"no class annotations yet"
);
k
->
set_is_contended
(
is_contended
()
);
}
...
...
@@ -2148,9 +2160,21 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
cp
,
CHECK_
(
nullHandle
));
}
else
if
(
method_attribute_name
==
vmSymbols
::
tag_method_parameters
())
{
method_parameters_length
=
cfs
->
get_u1_fast
();
// Track the actual size (note: this is written for clarity; a
// decent compiler will CSE and constant-fold this into a single
// expression)
u2
actual_size
=
1
;
method_parameters_data
=
cfs
->
get_u1_buffer
();
actual_size
+=
2
*
method_parameters_length
;
cfs
->
skip_u2_fast
(
method_parameters_length
);
actual_size
+=
4
*
method_parameters_length
;
cfs
->
skip_u4_fast
(
method_parameters_length
);
// Enforce attribute length
if
(
method_attribute_length
!=
actual_size
)
{
classfile_parse_error
(
"Invalid MethodParameters method attribute length %u in class file %s"
,
method_attribute_length
,
CHECK_
(
nullHandle
));
}
// ignore this attribute if it cannot be reflected
if
(
!
SystemDictionary
::
Parameter_klass_loaded
())
method_parameters_length
=
0
;
...
...
@@ -2181,7 +2205,8 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
runtime_visible_annotations_length
=
method_attribute_length
;
runtime_visible_annotations
=
cfs
->
get_u1_buffer
();
assert
(
runtime_visible_annotations
!=
NULL
,
"null visible annotations"
);
parse_annotations
(
runtime_visible_annotations
,
parse_annotations
(
loader_data
,
runtime_visible_annotations
,
runtime_visible_annotations_length
,
cp
,
&
parsed_annotations
,
CHECK_
(
nullHandle
));
cfs
->
skip_u1
(
runtime_visible_annotations_length
,
CHECK_
(
nullHandle
));
...
...
@@ -2297,7 +2322,10 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
elem
[
i
].
name_cp_index
=
Bytes
::
get_Java_u2
(
method_parameters_data
);
method_parameters_data
+=
2
;
elem
[
i
].
flags
=
Bytes
::
get_Java_u4
(
method_parameters_data
);
u4
flags
=
Bytes
::
get_Java_u4
(
method_parameters_data
);
// This caused an alignment fault on Sparc, if flags was a u4
elem
[
i
].
flags_lo
=
extract_low_short_from_int
(
flags
);
elem
[
i
].
flags_hi
=
extract_high_short_from_int
(
flags
);
method_parameters_data
+=
4
;
}
}
...
...
@@ -2886,7 +2914,8 @@ void ClassFileParser::parse_classfile_attributes(ClassLoaderData* loader_data,
runtime_visible_annotations_length
=
attribute_length
;
runtime_visible_annotations
=
cfs
->
get_u1_buffer
();
assert
(
runtime_visible_annotations
!=
NULL
,
"null visible annotations"
);
parse_annotations
(
runtime_visible_annotations
,
parse_annotations
(
loader_data
,
runtime_visible_annotations
,
runtime_visible_annotations_length
,
cp
,
parsed_annotations
,
...
...
@@ -3405,18 +3434,21 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
// Size of Java itable (in words)
itable_size
=
access_flags
.
is_interface
()
?
0
:
klassItable
::
compute_itable_size
(
transitive_interfaces
);
// get the padding width from the option
// TODO: Ask VM about specific CPU we are running on
int
pad_size
=
ContendedPaddingWidth
;
// Field size and offset computation
int
nonstatic_field_size
=
super_klass
()
==
NULL
?
0
:
super_klass
->
nonstatic_field_size
();
#ifndef PRODUCT
int
orig_nonstatic_field_size
=
0
;
#endif
int
static_field_size
=
0
;
int
next_static_oop_offset
;
int
next_static_double_offset
;
int
next_static_word_offset
;
int
next_static_short_offset
;
int
next_static_byte_offset
;
int
next_static_
type
_offset
;
int
next_static_
padded
_offset
;
int
next_nonstatic_oop_offset
;
int
next_nonstatic_double_offset
;
int
next_nonstatic_word_offset
;
...
...
@@ -3426,11 +3458,36 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
int
first_nonstatic_oop_offset
;
int
first_nonstatic_field_offset
;
int
next_nonstatic_field_offset
;
int
next_nonstatic_padded_offset
;
// Count the contended fields by type.
int
static_contended_count
=
0
;
int
nonstatic_contended_count
=
0
;
FieldAllocationCount
fac_contended
;
for
(
AllFieldStream
fs
(
fields
,
cp
);
!
fs
.
done
();
fs
.
next
())
{
FieldAllocationType
atype
=
(
FieldAllocationType
)
fs
.
allocation_type
();
if
(
fs
.
is_contended
())
{
fac_contended
.
count
[
atype
]
++
;
if
(
fs
.
access_flags
().
is_static
())
{
static_contended_count
++
;
}
else
{
nonstatic_contended_count
++
;
}
}
}
int
contended_count
=
static_contended_count
+
nonstatic_contended_count
;
// Calculate the starting byte offsets
next_static_oop_offset
=
InstanceMirrorKlass
::
offset_of_static_fields
();
// class is contended, pad before all the fields
if
(
parsed_annotations
.
is_contended
())
{
next_static_oop_offset
+=
pad_size
;
}
next_static_double_offset
=
next_static_oop_offset
+
(
fac
.
count
[
STATIC_OOP
]
*
heapOopSize
);
(
(
fac
.
count
[
STATIC_OOP
]
-
fac_contended
.
count
[
STATIC_OOP
])
*
heapOopSize
);
if
(
fac
.
count
[
STATIC_DOUBLE
]
&&
(
Universe
::
field_type_should_be_aligned
(
T_DOUBLE
)
||
Universe
::
field_type_should_be_aligned
(
T_LONG
))
)
{
...
...
@@ -3438,25 +3495,29 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
}
next_static_word_offset
=
next_static_double_offset
+
(
fac
.
count
[
STATIC_DOUBLE
]
*
BytesPerLong
);
(
(
fac
.
count
[
STATIC_DOUBLE
]
-
fac_contended
.
count
[
STATIC_DOUBLE
])
*
BytesPerLong
);
next_static_short_offset
=
next_static_word_offset
+
(
fac
.
count
[
STATIC_WORD
]
*
BytesPerInt
);
(
(
fac
.
count
[
STATIC_WORD
]
-
fac_contended
.
count
[
STATIC_WORD
])
*
BytesPerInt
);
next_static_byte_offset
=
next_static_short_offset
+
(
fac
.
count
[
STATIC_SHORT
]
*
BytesPerShort
);
next_static_type_offset
=
align_size_up
((
next_static_byte_offset
+
fac
.
count
[
STATIC_BYTE
]
),
wordSize
);
static_field_size
=
(
next_static_type_offset
-
next_static_oop_offset
)
/
wordSize
;
((
fac
.
count
[
STATIC_SHORT
]
-
fac_contended
.
count
[
STATIC_SHORT
])
*
BytesPerShort
);
next_static_padded_offset
=
next_static_byte_offset
+
((
fac
.
count
[
STATIC_BYTE
]
-
fac_contended
.
count
[
STATIC_BYTE
])
*
1
);
first_nonstatic_field_offset
=
instanceOopDesc
::
base_offset_in_bytes
()
+
nonstatic_field_size
*
heapOopSize
;
// class is contended, pad before all the fields
if
(
parsed_annotations
.
is_contended
())
{
first_nonstatic_field_offset
+=
pad_size
;
}
next_nonstatic_field_offset
=
first_nonstatic_field_offset
;
unsigned
int
nonstatic_double_count
=
fac
.
count
[
NONSTATIC_DOUBLE
];
unsigned
int
nonstatic_word_count
=
fac
.
count
[
NONSTATIC_WORD
];
unsigned
int
nonstatic_short_count
=
fac
.
count
[
NONSTATIC_SHORT
];
unsigned
int
nonstatic_byte_count
=
fac
.
count
[
NONSTATIC_BYTE
];
unsigned
int
nonstatic_oop_count
=
fac
.
count
[
NONSTATIC_OOP
];
unsigned
int
nonstatic_double_count
=
fac
.
count
[
NONSTATIC_DOUBLE
]
-
fac_contended
.
count
[
NONSTATIC_DOUBLE
]
;
unsigned
int
nonstatic_word_count
=
fac
.
count
[
NONSTATIC_WORD
]
-
fac_contended
.
count
[
NONSTATIC_WORD
]
;
unsigned
int
nonstatic_short_count
=
fac
.
count
[
NONSTATIC_SHORT
]
-
fac_contended
.
count
[
NONSTATIC_SHORT
]
;
unsigned
int
nonstatic_byte_count
=
fac
.
count
[
NONSTATIC_BYTE
]
-
fac_contended
.
count
[
NONSTATIC_BYTE
]
;
unsigned
int
nonstatic_oop_count
=
fac
.
count
[
NONSTATIC_OOP
]
-
fac_contended
.
count
[
NONSTATIC_OOP
]
;
bool
super_has_nonstatic_fields
=
(
super_klass
()
!=
NULL
&&
super_klass
->
has_nonstatic_fields
());
...
...
@@ -3529,12 +3590,12 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
}
if
(
allocation_style
==
0
)
{
// Fields order: oops, longs/doubles, ints, shorts/chars, bytes
// Fields order: oops, longs/doubles, ints, shorts/chars, bytes
, padded fields
next_nonstatic_oop_offset
=
next_nonstatic_field_offset
;
next_nonstatic_double_offset
=
next_nonstatic_oop_offset
+
(
nonstatic_oop_count
*
heapOopSize
);
}
else
if
(
allocation_style
==
1
)
{
// Fields order: longs/doubles, ints, shorts/chars, bytes, oops
// Fields order: longs/doubles, ints, shorts/chars, bytes, oops
, padded fields
next_nonstatic_double_offset
=
next_nonstatic_field_offset
;
}
else
if
(
allocation_style
==
2
)
{
// Fields allocation: oops fields in super and sub classes are together.
...
...
@@ -3613,27 +3674,33 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
(
nonstatic_word_count
*
BytesPerInt
);
next_nonstatic_byte_offset
=
next_nonstatic_short_offset
+
(
nonstatic_short_count
*
BytesPerShort
);
next_nonstatic_padded_offset
=
next_nonstatic_byte_offset
+
nonstatic_byte_count
;
int
notaligned_offset
;
if
(
allocation_style
==
0
)
{
notaligned_offset
=
next_nonstatic_byte_offset
+
nonstatic_byte_count
;
}
else
{
// allocation_style == 1
next_nonstatic_oop_offset
=
next_nonstatic_byte_offset
+
nonstatic_byte_count
;
// let oops jump before padding with this allocation style
if
(
allocation_style
==
1
)
{
next_nonstatic_oop_offset
=
next_nonstatic_padded_offset
;
if
(
nonstatic_oop_count
>
0
)
{
next_nonstatic_oop_offset
=
align_size_up
(
next_nonstatic_oop_offset
,
heapOopSize
);
}
n
otalign
ed_offset
=
next_nonstatic_oop_offset
+
(
nonstatic_oop_count
*
heapOopSize
);
n
ext_nonstatic_padd
ed_offset
=
next_nonstatic_oop_offset
+
(
nonstatic_oop_count
*
heapOopSize
);
}
next_nonstatic_type_offset
=
align_size_up
(
notaligned_offset
,
heapOopSize
);
nonstatic_field_size
=
nonstatic_field_size
+
((
next_nonstatic_type_offset
-
first_nonstatic_field_offset
)
/
heapOopSize
);
// Iterate over fields again and compute correct offsets.
// The field allocation type was temporarily stored in the offset slot.
// oop fields are located before non-oop fields (static and non-static).
for
(
AllFieldStream
fs
(
fields
,
cp
);
!
fs
.
done
();
fs
.
next
())
{
// skip already laid out fields
if
(
fs
.
is_offset_set
())
continue
;
// contended fields are handled below
if
(
fs
.
is_contended
())
continue
;
int
real_offset
;
FieldAllocationType
atype
=
(
FieldAllocationType
)
fs
.
offset
();
FieldAllocationType
atype
=
(
FieldAllocationType
)
fs
.
allocation_type
();
// pack the rest of the fields
switch
(
atype
)
{
case
STATIC_OOP
:
real_offset
=
next_static_oop_offset
;
...
...
@@ -3722,13 +3789,225 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
fs
.
set_offset
(
real_offset
);
}
// Handle the contended cases.
//
// Each contended field should not intersect the cache line with another contended field.
// In the absence of alignment information, we end up with pessimistically separating
// the fields with full-width padding.
//
// Additionally, this should not break alignment for the fields, so we round the alignment up
// for each field.
if
(
contended_count
>
0
)
{
// if there is at least one contended field, we need to have pre-padding for them
if
(
nonstatic_contended_count
>
0
)
{
next_nonstatic_padded_offset
+=
pad_size
;
}
// collect all contended groups
BitMap
bm
(
cp
->
size
());
for
(
AllFieldStream
fs
(
fields
,
cp
);
!
fs
.
done
();
fs
.
next
())
{
// skip already laid out fields
if
(
fs
.
is_offset_set
())
continue
;
if
(
fs
.
is_contended
())
{
bm
.
set_bit
(
fs
.
contended_group
());
}
}
int
current_group
=
-
1
;
while
((
current_group
=
(
int
)
bm
.
get_next_one_offset
(
current_group
+
1
))
!=
(
int
)
bm
.
size
())
{
for
(
AllFieldStream
fs
(
fields
,
cp
);
!
fs
.
done
();
fs
.
next
())
{
// skip already laid out fields
if
(
fs
.
is_offset_set
())
continue
;
// skip non-contended fields and fields from different group
if
(
!
fs
.
is_contended
()
||
(
fs
.
contended_group
()
!=
current_group
))
continue
;
// handle statics below
if
(
fs
.
access_flags
().
is_static
())
continue
;
int
real_offset
;
FieldAllocationType
atype
=
(
FieldAllocationType
)
fs
.
allocation_type
();
switch
(
atype
)
{
case
NONSTATIC_BYTE
:
next_nonstatic_padded_offset
=
align_size_up
(
next_nonstatic_padded_offset
,
1
);
real_offset
=
next_nonstatic_padded_offset
;
next_nonstatic_padded_offset
+=
1
;
break
;
case
NONSTATIC_SHORT
:
next_nonstatic_padded_offset
=
align_size_up
(
next_nonstatic_padded_offset
,
BytesPerShort
);
real_offset
=
next_nonstatic_padded_offset
;
next_nonstatic_padded_offset
+=
BytesPerShort
;
break
;
case
NONSTATIC_WORD
:
next_nonstatic_padded_offset
=
align_size_up
(
next_nonstatic_padded_offset
,
BytesPerInt
);
real_offset
=
next_nonstatic_padded_offset
;
next_nonstatic_padded_offset
+=
BytesPerInt
;
break
;
case
NONSTATIC_DOUBLE
:
next_nonstatic_padded_offset
=
align_size_up
(
next_nonstatic_padded_offset
,
BytesPerLong
);
real_offset
=
next_nonstatic_padded_offset
;
next_nonstatic_padded_offset
+=
BytesPerLong
;
break
;
case
NONSTATIC_OOP
:
next_nonstatic_padded_offset
=
align_size_up
(
next_nonstatic_padded_offset
,
heapOopSize
);
real_offset
=
next_nonstatic_padded_offset
;
next_nonstatic_padded_offset
+=
heapOopSize
;
// Create new oop map
nonstatic_oop_offsets
[
nonstatic_oop_map_count
]
=
real_offset
;
nonstatic_oop_counts
[
nonstatic_oop_map_count
]
=
1
;
nonstatic_oop_map_count
+=
1
;
if
(
first_nonstatic_oop_offset
==
0
)
{
// Undefined
first_nonstatic_oop_offset
=
real_offset
;
}
break
;
default:
ShouldNotReachHere
();
}
if
(
fs
.
contended_group
()
==
0
)
{
// Contended group defines the equivalence class over the fields:
// the fields within the same contended group are not inter-padded.
// The only exception is default group, which does not incur the
// equivalence, and so requires intra-padding.
next_nonstatic_padded_offset
+=
pad_size
;
}
fs
.
set_offset
(
real_offset
);
}
// for
// Start laying out the next group.
// Note that this will effectively pad the last group in the back;
// this is expected to alleviate memory contention effects for
// subclass fields and/or adjacent object.
// If this was the default group, the padding is already in place.
if
(
current_group
!=
0
)
{
next_nonstatic_padded_offset
+=
pad_size
;
}
}
// handle static fields
// if there is at least one contended field, we need to have pre-padding for them
if
(
static_contended_count
>
0
)
{
next_static_padded_offset
+=
pad_size
;
}
current_group
=
-
1
;
while
((
current_group
=
(
int
)
bm
.
get_next_one_offset
(
current_group
+
1
))
!=
(
int
)
bm
.
size
())
{
for
(
AllFieldStream
fs
(
fields
,
cp
);
!
fs
.
done
();
fs
.
next
())
{
// skip already laid out fields
if
(
fs
.
is_offset_set
())
continue
;
// skip non-contended fields and fields from different group
if
(
!
fs
.
is_contended
()
||
(
fs
.
contended_group
()
!=
current_group
))
continue
;
// non-statics already handled above
if
(
!
fs
.
access_flags
().
is_static
())
continue
;
int
real_offset
;
FieldAllocationType
atype
=
(
FieldAllocationType
)
fs
.
allocation_type
();
switch
(
atype
)
{
case
STATIC_BYTE
:
next_static_padded_offset
=
align_size_up
(
next_static_padded_offset
,
1
);
real_offset
=
next_static_padded_offset
;
next_static_padded_offset
+=
1
;
break
;
case
STATIC_SHORT
:
next_static_padded_offset
=
align_size_up
(
next_static_padded_offset
,
BytesPerShort
);
real_offset
=
next_static_padded_offset
;
next_static_padded_offset
+=
BytesPerShort
;
break
;
case
STATIC_WORD
:
next_static_padded_offset
=
align_size_up
(
next_static_padded_offset
,
BytesPerInt
);
real_offset
=
next_static_padded_offset
;
next_static_padded_offset
+=
BytesPerInt
;
break
;
case
STATIC_DOUBLE
:
next_static_padded_offset
=
align_size_up
(
next_static_padded_offset
,
BytesPerLong
);
real_offset
=
next_static_padded_offset
;
next_static_padded_offset
+=
BytesPerLong
;
break
;
case
STATIC_OOP
:
next_static_padded_offset
=
align_size_up
(
next_static_padded_offset
,
heapOopSize
);
real_offset
=
next_static_padded_offset
;
next_static_padded_offset
+=
heapOopSize
;
break
;
default:
ShouldNotReachHere
();
}
if
(
fs
.
contended_group
()
==
0
)
{
// Contended group defines the equivalence class over the fields:
// the fields within the same contended group are not inter-padded.
// The only exception is default group, which does not incur the
// equivalence, and so requires intra-padding.
next_static_padded_offset
+=
pad_size
;
}
fs
.
set_offset
(
real_offset
);
}
// for
// Start laying out the next group.
// Note that this will effectively pad the last group in the back;
// this is expected to alleviate memory contention effects for
// subclass fields and/or adjacent object.
// If this was the default group, the padding is already in place.
if
(
current_group
!=
0
)
{
next_static_padded_offset
+=
pad_size
;
}
}
}
// handle contended
// Size of instances
int
instance_size
;
int
notaligned_offset
=
next_nonstatic_padded_offset
;
// Entire class is contended, pad in the back.
// This helps to alleviate memory contention effects for subclass fields
// and/or adjacent object.
if
(
parsed_annotations
.
is_contended
())
{
notaligned_offset
+=
pad_size
;
next_static_padded_offset
+=
pad_size
;
}
int
next_static_type_offset
=
align_size_up
(
next_static_padded_offset
,
wordSize
);
int
static_field_size
=
(
next_static_type_offset
-
InstanceMirrorKlass
::
offset_of_static_fields
())
/
wordSize
;
next_nonstatic_type_offset
=
align_size_up
(
notaligned_offset
,
heapOopSize
);
nonstatic_field_size
=
nonstatic_field_size
+
((
next_nonstatic_type_offset
-
first_nonstatic_field_offset
)
/
heapOopSize
);
next_nonstatic_type_offset
=
align_size_up
(
notaligned_offset
,
wordSize
);
instance_size
=
align_object_size
(
next_nonstatic_type_offset
/
wordSize
);
assert
(
instance_size
==
align_object_size
(
align_size_up
((
instanceOopDesc
::
base_offset_in_bytes
()
+
nonstatic_field_size
*
heapOopSize
),
wordSize
)
/
wordSize
),
"consistent layout helper value"
);
assert
(
instance_size
==
align_object_size
(
align_size_up
(
(
instanceOopDesc
::
base_offset_in_bytes
()
+
nonstatic_field_size
*
heapOopSize
+
((
parsed_annotations
.
is_contended
())
?
pad_size
:
0
)),
wordSize
)
/
wordSize
),
"consistent layout helper value"
);
// Number of non-static oop map blocks allocated at end of klass.
const
unsigned
int
total_oop_map_count
=
...
...
@@ -3912,7 +4191,10 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
// check that if this class is an interface then it doesn't have static methods
if
(
this_klass
->
is_interface
())
{
check_illegal_static_method
(
this_klass
,
CHECK_
(
nullHandle
));
/* An interface in a JAVA 8 classfile can be static */
if
(
_major_version
<
JAVA_8_VERSION
)
{
check_illegal_static_method
(
this_klass
,
CHECK_
(
nullHandle
));
}
}
...
...
@@ -4005,6 +4287,18 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
}
#endif
#ifndef PRODUCT
if
(
PrintFieldLayout
)
{
print_field_layout
(
name
,
fields
,
cp
,
instance_size
,
first_nonstatic_field_offset
,
next_nonstatic_field_offset
,
next_static_type_offset
);
}
#endif
// preserve result across HandleMark
preserve_this_klass
=
this_klass
();
}
...
...
@@ -4017,6 +4311,38 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
return
this_klass
;
}
void
ClassFileParser
::
print_field_layout
(
Symbol
*
name
,
Array
<
u2
>*
fields
,
constantPoolHandle
cp
,
int
instance_size
,
int
instance_fields_start
,
int
instance_fields_end
,
int
static_fields_end
)
{
tty
->
print
(
"%s: field layout
\n
"
,
name
->
as_klass_external_name
());
tty
->
print
(
" @%3d %s
\n
"
,
instance_fields_start
,
"--- instance fields start ---"
);
for
(
AllFieldStream
fs
(
fields
,
cp
);
!
fs
.
done
();
fs
.
next
())
{
if
(
!
fs
.
access_flags
().
is_static
())
{
tty
->
print
(
" @%3d
\"
%s
\"
%s
\n
"
,
fs
.
offset
(),
fs
.
name
()
->
as_klass_external_name
(),
fs
.
signature
()
->
as_klass_external_name
());
}
}
tty
->
print
(
" @%3d %s
\n
"
,
instance_fields_end
,
"--- instance fields end ---"
);
tty
->
print
(
" @%3d %s
\n
"
,
instance_size
*
wordSize
,
"--- instance ends ---"
);
tty
->
print
(
" @%3d %s
\n
"
,
InstanceMirrorKlass
::
offset_of_static_fields
(),
"--- static fields start ---"
);
for
(
AllFieldStream
fs
(
fields
,
cp
);
!
fs
.
done
();
fs
.
next
())
{
if
(
fs
.
access_flags
().
is_static
())
{
tty
->
print
(
" @%3d
\"
%s
\"
%s
\n
"
,
fs
.
offset
(),
fs
.
name
()
->
as_klass_external_name
(),
fs
.
signature
()
->
as_klass_external_name
());
}
}
tty
->
print
(
" @%3d %s
\n
"
,
static_fields_end
,
"--- static fields end ---"
);
tty
->
print
(
"
\n
"
);
}
unsigned
int
ClassFileParser
::
compute_oop_map_count
(
instanceKlassHandle
super
,
unsigned
int
nonstatic_oop_map_count
,
...
...
@@ -4466,6 +4792,7 @@ void ClassFileParser::verify_legal_method_modifiers(
const
bool
is_bridge
=
(
flags
&
JVM_ACC_BRIDGE
)
!=
0
;
const
bool
is_strict
=
(
flags
&
JVM_ACC_STRICT
)
!=
0
;
const
bool
is_synchronized
=
(
flags
&
JVM_ACC_SYNCHRONIZED
)
!=
0
;
const
bool
is_protected
=
(
flags
&
JVM_ACC_PROTECTED
)
!=
0
;
const
bool
major_gte_15
=
_major_version
>=
JAVA_1_5_VERSION
;
const
bool
major_gte_8
=
_major_version
>=
JAVA_8_VERSION
;
const
bool
is_initializer
=
(
name
==
vmSymbols
::
object_initializer_name
());
...
...
@@ -4473,11 +4800,33 @@ void ClassFileParser::verify_legal_method_modifiers(
bool
is_illegal
=
false
;
if
(
is_interface
)
{
if
(
!
is_public
||
is_static
||
is_final
||
is_native
||
((
is_synchronized
||
is_strict
)
&&
major_gte_15
&&
(
!
major_gte_8
||
is_abstract
))
||
(
!
major_gte_8
&&
!
is_abstract
))
{
is_illegal
=
true
;
if
(
major_gte_8
)
{
// Class file version is JAVA_8_VERSION or later Methods of
// interfaces may set any of the flags except ACC_PROTECTED,
// ACC_FINAL, ACC_NATIVE, and ACC_SYNCHRONIZED; they must
// have exactly one of the ACC_PUBLIC or ACC_PRIVATE flags set.
if
((
is_public
==
is_private
)
||
/* Only one of private and public should be true - XNOR */
(
is_native
||
is_protected
||
is_final
||
is_synchronized
)
||
// If a specific method of a class or interface has its
// ACC_ABSTRACT flag set, it must not have any of its
// ACC_FINAL, ACC_NATIVE, ACC_PRIVATE, ACC_STATIC,
// ACC_STRICT, or ACC_SYNCHRONIZED flags set. No need to
// check for ACC_FINAL, ACC_NATIVE or ACC_SYNCHRONIZED as
// those flags are illegal irrespective of ACC_ABSTRACT being set or not.
(
is_abstract
&&
(
is_private
||
is_static
||
is_strict
)))
{
is_illegal
=
true
;
}
}
else
if
(
major_gte_15
)
{
// Class file version in the interval [JAVA_1_5_VERSION, JAVA_8_VERSION)
if
(
!
is_public
||
is_static
||
is_final
||
is_synchronized
||
is_native
||
!
is_abstract
||
is_strict
)
{
is_illegal
=
true
;
}
}
else
{
// Class file version is pre-JAVA_1_5_VERSION
if
(
!
is_public
||
is_static
||
is_final
||
is_native
||
!
is_abstract
)
{
is_illegal
=
true
;
}
}
}
else
{
// not interface
if
(
is_initializer
)
{
...
...
src/share/vm/classfile/classFileParser.hpp
浏览文件 @
817c1633
...
...
@@ -95,17 +95,20 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
_method_DontInline
,
_method_LambdaForm_Compiled
,
_method_LambdaForm_Hidden
,
_sun_misc_Contended
,
_annotation_LIMIT
};
const
Location
_location
;
int
_annotations_present
;
u2
_contended_group
;
AnnotationCollector
(
Location
location
)
:
_location
(
location
),
_annotations_present
(
0
)
{
assert
((
int
)
_annotation_LIMIT
<=
(
int
)
sizeof
(
_annotations_present
)
*
BitsPerByte
,
""
);
}
// If this annotation name has an ID, report it (or _none).
ID
annotation_index
(
Symbol
*
name
);
ID
annotation_index
(
ClassLoaderData
*
loader_data
,
Symbol
*
name
);
// Set the annotation name:
void
set_annotation
(
ID
id
)
{
assert
((
int
)
id
>=
0
&&
(
int
)
id
<
(
int
)
_annotation_LIMIT
,
"oob"
);
...
...
@@ -114,6 +117,12 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
// Report if the annotation is present.
bool
has_any_annotations
()
{
return
_annotations_present
!=
0
;
}
bool
has_annotation
(
ID
id
)
{
return
(
nth_bit
((
int
)
id
)
&
_annotations_present
)
!=
0
;
}
void
set_contended_group
(
u2
group
)
{
_contended_group
=
group
;
}
u2
contended_group
()
{
return
_contended_group
;
}
void
set_contended
(
bool
contended
)
{
set_annotation
(
_sun_misc_Contended
);
}
bool
is_contended
()
{
return
has_annotation
(
_sun_misc_Contended
);
}
};
class
FieldAnnotationCollector
:
public
AnnotationCollector
{
public:
...
...
@@ -177,6 +186,14 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
Array
<
AnnotationArray
*>**
fields_type_annotations
,
u2
*
java_fields_count_ptr
,
TRAPS
);
void
print_field_layout
(
Symbol
*
name
,
Array
<
u2
>*
fields
,
constantPoolHandle
cp
,
int
instance_size
,
int
instance_fields_start
,
int
instance_fields_end
,
int
static_fields_end
);
// Method parsing
methodHandle
parse_method
(
ClassLoaderData
*
loader_data
,
constantPoolHandle
cp
,
...
...
@@ -247,7 +264,8 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
int
runtime_invisible_annotations_length
,
TRAPS
);
int
skip_annotation
(
u1
*
buffer
,
int
limit
,
int
index
);
int
skip_annotation_value
(
u1
*
buffer
,
int
limit
,
int
index
);
void
parse_annotations
(
u1
*
buffer
,
int
limit
,
constantPoolHandle
cp
,
void
parse_annotations
(
ClassLoaderData
*
loader_data
,
u1
*
buffer
,
int
limit
,
constantPoolHandle
cp
,
/* Results (currently, only one result is supported): */
AnnotationCollector
*
result
,
TRAPS
);
...
...
src/share/vm/classfile/placeholders.cpp
浏览文件 @
817c1633
/*
* Copyright (c) 2003, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
3
, 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
...
...
@@ -142,7 +142,7 @@ PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash,
}
// placeholder used to track class loading internal states
// placeholder
is
used to track class loading internal states
// placeholder existence now for loading superclass/superinterface
// superthreadQ tracks class circularity, while loading superclass/superinterface
// loadInstanceThreadQ tracks load_instance_class calls
...
...
@@ -153,15 +153,17 @@ PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash,
// All claimants remove SeenThread after completing action
// On removal: if definer and all queues empty, remove entry
// Note: you can be in both placeholders and systemDictionary
// see parse_stream for redefine classes
// Therefore - must always check SD first
// Ignores the case where entry is not found
void
PlaceholderTable
::
find_and_remove
(
int
index
,
unsigned
int
hash
,
Symbol
*
name
,
ClassLoaderData
*
loader_data
,
Thread
*
thread
)
{
Symbol
*
name
,
ClassLoaderData
*
loader_data
,
classloadAction
action
,
Thread
*
thread
)
{
assert_locked_or_safepoint
(
SystemDictionary_lock
);
PlaceholderEntry
*
probe
=
get_entry
(
index
,
hash
,
name
,
loader_data
);
if
(
probe
!=
NULL
)
{
// No other threads using this entry
probe
->
remove_seen_thread
(
thread
,
action
);
// If no other threads using this entry, and this thread is not using this entry for other states
if
((
probe
->
superThreadQ
()
==
NULL
)
&&
(
probe
->
loadInstanceThreadQ
()
==
NULL
)
&&
(
probe
->
defineThreadQ
()
==
NULL
)
&&
(
probe
->
definer
()
==
NULL
))
{
remove_entry
(
index
,
hash
,
name
,
loader_data
);
...
...
src/share/vm/classfile/placeholders.hpp
浏览文件 @
817c1633
/*
* Copyright (c) 2003, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
3
, 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,7 +82,7 @@ public:
};
// find_and_add returns probe pointer - old or new
// If no entry exists, add a placeholder entry and push SeenThread
// If no entry exists, add a placeholder entry and push SeenThread
for classloadAction
// If entry exists, reuse entry and push SeenThread for classloadAction
PlaceholderEntry
*
find_and_add
(
int
index
,
unsigned
int
hash
,
Symbol
*
name
,
ClassLoaderData
*
loader_data
,
...
...
@@ -92,9 +92,11 @@ public:
void
remove_entry
(
int
index
,
unsigned
int
hash
,
Symbol
*
name
,
ClassLoaderData
*
loader_data
);
// Remove placeholder information
// find_and_remove first removes SeenThread for classloadAction
// If all queues are empty and definer is null, remove the PlacheholderEntry completely
void
find_and_remove
(
int
index
,
unsigned
int
hash
,
Symbol
*
name
,
ClassLoaderData
*
loader_data
,
Thread
*
thread
);
Symbol
*
name
,
ClassLoaderData
*
loader_data
,
classloadAction
action
,
Thread
*
thread
);
// GC support.
void
classes_do
(
KlassClosure
*
f
);
...
...
src/share/vm/classfile/systemDictionary.cpp
浏览文件 @
817c1633
/*
* Copyright (c) 1997, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 201
3
, 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
...
...
@@ -172,7 +172,7 @@ Klass* SystemDictionary::handle_resolution_exception(Symbol* class_name, Handle
assert
(
klass_h
()
==
NULL
,
"Should not have result with exception pending"
);
Handle
e
(
THREAD
,
PENDING_EXCEPTION
);
CLEAR_PENDING_EXCEPTION
;
THROW_MSG_CAUSE_
0
(
vmSymbols
::
java_lang_NoClassDefFoundError
(),
class_name
->
as_C_string
(),
e
);
THROW_MSG_CAUSE_
NULL
(
vmSymbols
::
java_lang_NoClassDefFoundError
(),
class_name
->
as_C_string
(),
e
);
}
else
{
return
NULL
;
}
...
...
@@ -181,9 +181,9 @@ Klass* SystemDictionary::handle_resolution_exception(Symbol* class_name, Handle
if
(
klass_h
()
==
NULL
)
{
ResourceMark
rm
(
THREAD
);
if
(
throw_error
)
{
THROW_MSG_
0
(
vmSymbols
::
java_lang_NoClassDefFoundError
(),
class_name
->
as_C_string
());
THROW_MSG_
NULL
(
vmSymbols
::
java_lang_NoClassDefFoundError
(),
class_name
->
as_C_string
());
}
else
{
THROW_MSG_
0
(
vmSymbols
::
java_lang_ClassNotFoundException
(),
class_name
->
as_C_string
());
THROW_MSG_
NULL
(
vmSymbols
::
java_lang_ClassNotFoundException
(),
class_name
->
as_C_string
());
}
}
return
(
Klass
*
)
klass_h
();
...
...
@@ -343,29 +343,29 @@ Klass* SystemDictionary::resolve_super_or_fail(Symbol* child_name,
}
if
(
throw_circularity_error
)
{
ResourceMark
rm
(
THREAD
);
THROW_MSG_
0
(
vmSymbols
::
java_lang_ClassCircularityError
(),
child_name
->
as_C_string
());
THROW_MSG_
NULL
(
vmSymbols
::
java_lang_ClassCircularityError
(),
child_name
->
as_C_string
());
}
// java.lang.Object should have been found above
assert
(
class_name
!=
NULL
,
"null super class for resolving"
);
// Resolve the super class or interface, check results on return
Klass
*
superk
=
NULL
;
superk
=
SystemDictionary
::
resolve_or_null
(
class_name
,
Klass
*
superk
=
SystemDictionary
::
resolve_or_null
(
class_name
,
class_loader
,
protection_domain
,
THREAD
);
KlassHandle
superk_h
(
THREAD
,
superk
);
// Note: clean up of placeholders currently in callers of
// resolve_super_or_fail - either at update_dictionary time
// or on error
// Clean up of placeholders moved so that each classloadAction registrar self-cleans up
// It is no longer necessary to keep the placeholder table alive until update_dictionary
// or error. GC used to walk the placeholder table as strong roots.
// The instanceKlass is kept alive because the class loader is on the stack,
// which keeps the loader_data alive, as well as all instanceKlasses in
// the loader_data. parseClassFile adds the instanceKlass to loader_data.
{
MutexLocker
mu
(
SystemDictionary_lock
,
THREAD
);
PlaceholderEntry
*
probe
=
placeholders
()
->
get_entry
(
p_index
,
p_hash
,
child_name
,
loader_data
);
if
(
probe
!=
NULL
)
{
probe
->
remove_seen_thread
(
THREAD
,
PlaceholderTable
::
LOAD_SUPER
);
}
MutexLocker
mu
(
SystemDictionary_lock
,
THREAD
);
placeholders
()
->
find_and_remove
(
p_index
,
p_hash
,
child_name
,
loader_data
,
PlaceholderTable
::
LOAD_SUPER
,
THREAD
);
SystemDictionary_lock
->
notify_all
();
}
if
(
HAS_PENDING_EXCEPTION
||
superk_h
()
==
NULL
)
{
// can null superk
...
...
@@ -430,8 +430,8 @@ void SystemDictionary::validate_protection_domain(instanceKlassHandle klass,
// We're using a No_Safepoint_Verifier to catch any place where we
// might potentially do a GC at all.
//
SystemDictionary::do_unloading() asserts that classes
are only
// unloaded at a safepoint.
//
Dictionary::do_unloading() asserts that classes in SD
are only
// unloaded at a safepoint.
Anonymous classes are not in SD.
No_Safepoint_Verifier
nosafepoint
;
dictionary
()
->
add_protection_domain
(
d_index
,
d_hash
,
klass
,
loader_data
,
protection_domain
,
THREAD
);
...
...
@@ -486,7 +486,6 @@ void SystemDictionary::double_lock_wait(Handle lockObject, TRAPS) {
// super class loading here.
// This also is critical in cases where the original thread gets stalled
// even in non-circularity situations.
// Note: only one thread can define the class, but multiple can resolve
// Note: must call resolve_super_or_fail even if null super -
// to force placeholder entry creation for this class for circularity detection
// Caller must check for pending exception
...
...
@@ -518,14 +517,6 @@ instanceKlassHandle SystemDictionary::handle_parallel_super_load(
protection_domain
,
true
,
CHECK_
(
nh
));
// We don't redefine the class, so we just need to clean up if there
// was not an error (don't want to modify any system dictionary
// data structures).
{
MutexLocker
mu
(
SystemDictionary_lock
,
THREAD
);
placeholders
()
->
find_and_remove
(
p_index
,
p_hash
,
name
,
loader_data
,
THREAD
);
SystemDictionary_lock
->
notify_all
();
}
// parallelCapable class loaders do NOT wait for parallel superclass loads to complete
// Serial class loaders and bootstrap classloader do wait for superclass loads
...
...
@@ -595,6 +586,10 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
// Do lookup to see if class already exist and the protection domain
// has the right access
// This call uses find which checks protection domain already matches
// All subsequent calls use find_class, and set has_loaded_class so that
// before we return a result we call out to java to check for valid protection domain
// to allow returning the Klass* and add it to the pd_set if it is valid
unsigned
int
d_hash
=
dictionary
()
->
compute_hash
(
name
,
loader_data
);
int
d_index
=
dictionary
()
->
hash_to_index
(
d_hash
);
Klass
*
probe
=
dictionary
()
->
find
(
d_index
,
d_hash
,
name
,
loader_data
,
...
...
@@ -652,7 +647,7 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
}
}
// If the class i
n i
s in the placeholder table, class loading is in progress
// If the class is in the placeholder table, class loading is in progress
if
(
super_load_in_progress
&&
havesupername
==
true
)
{
k
=
SystemDictionary
::
handle_parallel_super_load
(
name
,
superclassname
,
class_loader
,
protection_domain
,
lockObject
,
THREAD
);
...
...
@@ -664,7 +659,9 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
}
}
bool
throw_circularity_error
=
false
;
if
(
!
class_has_been_loaded
)
{
bool
load_instance_added
=
false
;
// add placeholder entry to record loading instance class
// Five cases:
...
...
@@ -690,7 +687,7 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
// No performance benefit and no deadlock issues.
// case 5. parallelCapable user level classloaders - without objectLocker
// Allow parallel classloading of a class/classloader pair
bool
throw_circularity_error
=
false
;
{
MutexLocker
mu
(
SystemDictionary_lock
,
THREAD
);
if
(
class_loader
.
is_null
()
||
!
is_parallelCapable
(
class_loader
))
{
...
...
@@ -726,12 +723,13 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
}
}
}
// All cases: add LOAD_INSTANCE
// All cases: add LOAD_INSTANCE
holding SystemDictionary_lock
// case 3: UnsyncloadClass || case 5: parallelCapable: allow competing threads to try
// LOAD_INSTANCE in parallel
// add placeholder entry even if error - callers will remove on error
if
(
!
throw_circularity_error
&&
!
class_has_been_loaded
)
{
PlaceholderEntry
*
newprobe
=
placeholders
()
->
find_and_add
(
p_index
,
p_hash
,
name
,
loader_data
,
PlaceholderTable
::
LOAD_INSTANCE
,
NULL
,
THREAD
);
load_instance_added
=
true
;
// For class loaders that do not acquire the classloader object lock,
// if they did not catch another thread holding LOAD_INSTANCE,
// need a check analogous to the acquire ObjectLocker/find_class
...
...
@@ -740,19 +738,18 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
// class loaders holding the ObjectLock shouldn't find the class here
Klass
*
check
=
find_class
(
d_index
,
d_hash
,
name
,
loader_data
);
if
(
check
!=
NULL
)
{
// Klass is already loaded, so
just return it
// Klass is already loaded, so
return it after checking/adding protection domain
k
=
instanceKlassHandle
(
THREAD
,
check
);
class_has_been_loaded
=
true
;
newprobe
->
remove_seen_thread
(
THREAD
,
PlaceholderTable
::
LOAD_INSTANCE
);
placeholders
()
->
find_and_remove
(
p_index
,
p_hash
,
name
,
loader_data
,
THREAD
);
SystemDictionary_lock
->
notify_all
();
}
}
}
// must throw error outside of owning lock
if
(
throw_circularity_error
)
{
assert
(
!
HAS_PENDING_EXCEPTION
&&
load_instance_added
==
false
,
"circularity error cleanup"
);
ResourceMark
rm
(
THREAD
);
THROW_MSG_
0
(
vmSymbols
::
java_lang_ClassCircularityError
(),
name
->
as_C_string
());
THROW_MSG_
NULL
(
vmSymbols
::
java_lang_ClassCircularityError
(),
name
->
as_C_string
());
}
if
(
!
class_has_been_loaded
)
{
...
...
@@ -782,20 +779,6 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
}
}
// clean up placeholder entries for success or error
// This cleans up LOAD_INSTANCE entries
// It also cleans up LOAD_SUPER entries on errors from
// calling load_instance_class
{
MutexLocker
mu
(
SystemDictionary_lock
,
THREAD
);
PlaceholderEntry
*
probe
=
placeholders
()
->
get_entry
(
p_index
,
p_hash
,
name
,
loader_data
);
if
(
probe
!=
NULL
)
{
probe
->
remove_seen_thread
(
THREAD
,
PlaceholderTable
::
LOAD_INSTANCE
);
placeholders
()
->
find_and_remove
(
p_index
,
p_hash
,
name
,
loader_data
,
THREAD
);
SystemDictionary_lock
->
notify_all
();
}
}
// If everything was OK (no exceptions, no null return value), and
// class_loader is NOT the defining loader, do a little more bookkeeping.
if
(
!
HAS_PENDING_EXCEPTION
&&
!
k
.
is_null
()
&&
...
...
@@ -819,18 +802,22 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
}
}
}
if
(
HAS_PENDING_EXCEPTION
||
k
.
is_null
())
{
// On error, clean up placeholders
{
MutexLocker
mu
(
SystemDictionary_lock
,
THREAD
);
placeholders
()
->
find_and_remove
(
p_index
,
p_hash
,
name
,
loader_data
,
THREAD
);
SystemDictionary_lock
->
notify_all
();
}
return
NULL
;
}
}
// load_instance_class loop
if
(
load_instance_added
==
true
)
{
// clean up placeholder entries for LOAD_INSTANCE success or error
// This brackets the SystemDictionary updates for both defining
// and initiating loaders
MutexLocker
mu
(
SystemDictionary_lock
,
THREAD
);
placeholders
()
->
find_and_remove
(
p_index
,
p_hash
,
name
,
loader_data
,
PlaceholderTable
::
LOAD_INSTANCE
,
THREAD
)
;
SystemDictionary_lock
->
notify_all
();
}
}
if
(
HAS_PENDING_EXCEPTION
||
k
.
is_null
())
{
return
NULL
;
}
#ifdef ASSERT
{
ClassLoaderData
*
loader_data
=
k
->
class_loader_data
();
...
...
@@ -850,8 +837,8 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
// so we cannot allow GC to occur while we're holding this entry.
// We're using a No_Safepoint_Verifier to catch any place where we
// might potentially do a GC at all.
//
SystemDictionary::do_unloading() asserts that classes
are only
// unloaded at a safepoint.
//
Dictionary::do_unloading() asserts that classes in SD
are only
// unloaded at a safepoint.
Anonymous classes are not in SD.
No_Safepoint_Verifier
nosafepoint
;
if
(
dictionary
()
->
is_valid_protection_domain
(
d_index
,
d_hash
,
name
,
loader_data
,
...
...
@@ -898,8 +885,8 @@ Klass* SystemDictionary::find(Symbol* class_name,
// so we cannot allow GC to occur while we're holding this entry.
// We're using a No_Safepoint_Verifier to catch any place where we
// might potentially do a GC at all.
//
SystemDictionary::do_unloading() asserts that classes
are only
// unloaded at a safepoint.
//
Dictionary::do_unloading() asserts that classes in SD
are only
// unloaded at a safepoint.
Anonymous classes are not in SD.
No_Safepoint_Verifier
nosafepoint
;
return
dictionary
()
->
find
(
d_index
,
d_hash
,
class_name
,
loader_data
,
protection_domain
,
THREAD
);
...
...
@@ -965,10 +952,6 @@ Klass* SystemDictionary::parse_stream(Symbol* class_name,
// throw potential ClassFormatErrors.
//
// Note: "name" is updated.
// Further note: a placeholder will be added for this class when
// super classes are loaded (resolve_super_or_fail). We expect this
// to be called for all classes but java.lang.Object; and we preload
// java.lang.Object through resolve_or_fail, not this path.
instanceKlassHandle
k
=
ClassFileParser
(
st
).
parseClassFile
(
class_name
,
loader_data
,
...
...
@@ -979,21 +962,6 @@ Klass* SystemDictionary::parse_stream(Symbol* class_name,
true
,
THREAD
);
// We don't redefine the class, so we just need to clean up whether there
// was an error or not (don't want to modify any system dictionary
// data structures).
// Parsed name could be null if we threw an error before we got far
// enough along to parse it -- in that case, there is nothing to clean up.
if
(
parsed_name
!=
NULL
)
{
unsigned
int
p_hash
=
placeholders
()
->
compute_hash
(
parsed_name
,
loader_data
);
int
p_index
=
placeholders
()
->
hash_to_index
(
p_hash
);
{
MutexLocker
mu
(
SystemDictionary_lock
,
THREAD
);
placeholders
()
->
find_and_remove
(
p_index
,
p_hash
,
parsed_name
,
loader_data
,
THREAD
);
SystemDictionary_lock
->
notify_all
();
}
}
if
(
host_klass
.
not_null
()
&&
k
.
not_null
())
{
assert
(
EnableInvokeDynamic
,
""
);
...
...
@@ -1062,10 +1030,6 @@ Klass* SystemDictionary::resolve_from_stream(Symbol* class_name,
// throw potential ClassFormatErrors.
//
// Note: "name" is updated.
// Further note: a placeholder will be added for this class when
// super classes are loaded (resolve_super_or_fail). We expect this
// to be called for all classes but java.lang.Object; and we preload
// java.lang.Object through resolve_or_fail, not this path.
instanceKlassHandle
k
=
ClassFileParser
(
st
).
parseClassFile
(
class_name
,
loader_data
,
...
...
@@ -1114,25 +1078,7 @@ Klass* SystemDictionary::resolve_from_stream(Symbol* class_name,
}
}
// If parsing the class file or define_instance_class failed, we
// need to remove the placeholder added on our behalf. But we
// must make sure parsed_name is valid first (it won't be if we had
// a format error before the class was parsed far enough to
// find the name).
if
(
HAS_PENDING_EXCEPTION
&&
parsed_name
!=
NULL
)
{
unsigned
int
p_hash
=
placeholders
()
->
compute_hash
(
parsed_name
,
loader_data
);
int
p_index
=
placeholders
()
->
hash_to_index
(
p_hash
);
{
MutexLocker
mu
(
SystemDictionary_lock
,
THREAD
);
placeholders
()
->
find_and_remove
(
p_index
,
p_hash
,
parsed_name
,
loader_data
,
THREAD
);
SystemDictionary_lock
->
notify_all
();
}
return
NULL
;
}
// Make sure that we didn't leave a place holder in the
// SystemDictionary; this is only done on success
// Make sure we have an entry in the SystemDictionary on success
debug_only
(
{
if
(
!
HAS_PENDING_EXCEPTION
)
{
assert
(
parsed_name
!=
NULL
,
"parsed_name is still null?"
);
...
...
@@ -1547,8 +1493,7 @@ instanceKlassHandle SystemDictionary::find_or_define_instance_class(Symbol* clas
// Other cases fall through, and may run into duplicate defines
// caught by finding an entry in the SystemDictionary
if
((
UnsyncloadClass
||
is_parallelDefine
(
class_loader
))
&&
(
probe
->
instance_klass
()
!=
NULL
))
{
probe
->
remove_seen_thread
(
THREAD
,
PlaceholderTable
::
DEFINE_CLASS
);
placeholders
()
->
find_and_remove
(
p_index
,
p_hash
,
name_h
,
loader_data
,
THREAD
);
placeholders
()
->
find_and_remove
(
p_index
,
p_hash
,
name_h
,
loader_data
,
PlaceholderTable
::
DEFINE_CLASS
,
THREAD
);
SystemDictionary_lock
->
notify_all
();
#ifdef ASSERT
Klass
*
check
=
find_class
(
d_index
,
d_hash
,
name_h
,
loader_data
);
...
...
@@ -1578,8 +1523,7 @@ instanceKlassHandle SystemDictionary::find_or_define_instance_class(Symbol* clas
probe
->
set_instance_klass
(
k
());
}
probe
->
set_definer
(
NULL
);
probe
->
remove_seen_thread
(
THREAD
,
PlaceholderTable
::
DEFINE_CLASS
);
placeholders
()
->
find_and_remove
(
p_index
,
p_hash
,
name_h
,
loader_data
,
THREAD
);
placeholders
()
->
find_and_remove
(
p_index
,
p_hash
,
name_h
,
loader_data
,
PlaceholderTable
::
DEFINE_CLASS
,
THREAD
);
SystemDictionary_lock
->
notify_all
();
}
}
...
...
@@ -1736,6 +1680,8 @@ int SystemDictionary::calculate_systemdictionary_size(int classcount) {
}
return
newsize
;
}
// Assumes classes in the SystemDictionary are only unloaded at a safepoint
// Note: anonymous classes are not in the SD.
bool
SystemDictionary
::
do_unloading
(
BoolObjectClosure
*
is_alive
)
{
// First, mark for unload all ClassLoaderData referencing a dead class loader.
bool
has_dead_loaders
=
ClassLoaderDataGraph
::
do_unloading
(
is_alive
);
...
...
@@ -2105,9 +2051,7 @@ void SystemDictionary::update_dictionary(int d_index, unsigned int d_hash,
// All loaded classes get a unique ID.
TRACE_INIT_ID
(
k
);
// Check for a placeholder. If there, remove it and make a
// new system dictionary entry.
placeholders
()
->
find_and_remove
(
p_index
,
p_hash
,
name
,
loader_data
,
THREAD
);
// Make a new system dictionary entry.
Klass
*
sd_check
=
find_class
(
d_index
,
d_hash
,
name
,
loader_data
);
if
(
sd_check
==
NULL
)
{
dictionary
()
->
add_klass
(
name
,
loader_data
,
k
);
...
...
@@ -2116,12 +2060,8 @@ void SystemDictionary::update_dictionary(int d_index, unsigned int d_hash,
#ifdef ASSERT
sd_check
=
find_class
(
d_index
,
d_hash
,
name
,
loader_data
);
assert
(
sd_check
!=
NULL
,
"should have entry in system dictionary"
);
// Changed to allow PH to remain to complete class circularity checking
// while only one thread can define a class at one time, multiple
// classes can resolve the superclass for a class at one time,
// and the placeholder is used to track that
// Symbol* ph_check = find_placeholder(name, class_loader);
// assert (ph_check == NULL, "should not have a placeholder entry");
// Note: there may be a placeholder entry: for circularity testing
// or for parallel defines
#endif
SystemDictionary_lock
->
notify_all
();
}
...
...
src/share/vm/classfile/vmSymbols.hpp
浏览文件 @
817c1633
...
...
@@ -194,7 +194,10 @@
template(java_lang_VirtualMachineError, "java/lang/VirtualMachineError") \
template(java_lang_StackOverflowError, "java/lang/StackOverflowError") \
template(java_lang_StackTraceElement, "java/lang/StackTraceElement") \
\
/* Concurrency support */
\
template(java_util_concurrent_locks_AbstractOwnableSynchronizer, "java/util/concurrent/locks/AbstractOwnableSynchronizer") \
template(sun_misc_Contended_signature, "Lsun/misc/Contended;") \
\
/* class symbols needed by intrinsics */
\
VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, template, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE) \
...
...
@@ -284,7 +287,7 @@
NOT_LP64( do_alias(intptr_signature, int_signature) ) \
LP64_ONLY( do_alias(intptr_signature, long_signature) ) \
template(selectAlternative_signature, "(ZLjava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;") \
\
\
/* common method and field names */
\
template(object_initializer_name, "<init>") \
template(class_initializer_name, "<clinit>") \
...
...
src/share/vm/memory/metaspaceShared.cpp
浏览文件 @
817c1633
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012,
2013,
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
...
...
@@ -373,17 +373,44 @@ void VM_PopulateDumpSharedSpace::doit() {
md_top
=
wc
.
get_top
();
// Print shared spaces all the time
const
char
*
fmt
=
"%s space:
"
PTR_FORMAT
" out of "
PTR_FORMAT
" words allocated at "
PTR_FORMAT
"."
;
const
char
*
fmt
=
"%s space:
%9d [ %4.1f%% of total] out of %9d bytes [%4.1f%% used] at "
PTR_FORMAT
;
Metaspace
*
ro_space
=
_loader_data
->
ro_metaspace
();
Metaspace
*
rw_space
=
_loader_data
->
rw_metaspace
();
tty
->
print_cr
(
fmt
,
"ro"
,
ro_space
->
used_words
(
Metaspace
::
NonClassType
),
ro_space
->
capacity_words
(
Metaspace
::
NonClassType
),
ro_space
->
bottom
());
tty
->
print_cr
(
fmt
,
"rw"
,
rw_space
->
used_words
(
Metaspace
::
NonClassType
),
rw_space
->
capacity_words
(
Metaspace
::
NonClassType
),
rw_space
->
bottom
());
tty
->
print_cr
(
fmt
,
"md"
,
md_top
-
md_low
,
md_end
-
md_low
,
md_low
);
tty
->
print_cr
(
fmt
,
"mc"
,
mc_top
-
mc_low
,
mc_end
-
mc_low
,
mc_low
);
const
size_t
BPW
=
BytesPerWord
;
// Allocated size of each space (may not be all occupied)
const
size_t
ro_alloced
=
ro_space
->
capacity_words
(
Metaspace
::
NonClassType
)
*
BPW
;
const
size_t
rw_alloced
=
rw_space
->
capacity_words
(
Metaspace
::
NonClassType
)
*
BPW
;
const
size_t
md_alloced
=
md_end
-
md_low
;
const
size_t
mc_alloced
=
mc_end
-
mc_low
;
const
size_t
total_alloced
=
ro_alloced
+
rw_alloced
+
md_alloced
+
mc_alloced
;
// Occupied size of each space.
const
size_t
ro_bytes
=
ro_space
->
used_words
(
Metaspace
::
NonClassType
)
*
BPW
;
const
size_t
rw_bytes
=
rw_space
->
used_words
(
Metaspace
::
NonClassType
)
*
BPW
;
const
size_t
md_bytes
=
size_t
(
md_top
-
md_low
);
const
size_t
mc_bytes
=
size_t
(
mc_top
-
mc_low
);
// Percent of total size
const
size_t
total_bytes
=
ro_bytes
+
rw_bytes
+
md_bytes
+
mc_bytes
;
const
double
ro_t_perc
=
ro_bytes
/
double
(
total_bytes
)
*
100.0
;
const
double
rw_t_perc
=
rw_bytes
/
double
(
total_bytes
)
*
100.0
;
const
double
md_t_perc
=
md_bytes
/
double
(
total_bytes
)
*
100.0
;
const
double
mc_t_perc
=
mc_bytes
/
double
(
total_bytes
)
*
100.0
;
// Percent of fullness of each space
const
double
ro_u_perc
=
ro_bytes
/
double
(
ro_alloced
)
*
100.0
;
const
double
rw_u_perc
=
rw_bytes
/
double
(
rw_alloced
)
*
100.0
;
const
double
md_u_perc
=
md_bytes
/
double
(
md_alloced
)
*
100.0
;
const
double
mc_u_perc
=
mc_bytes
/
double
(
mc_alloced
)
*
100.0
;
const
double
total_u_perc
=
total_bytes
/
double
(
total_alloced
)
*
100.0
;
tty
->
print_cr
(
fmt
,
"ro"
,
ro_bytes
,
ro_t_perc
,
ro_alloced
,
ro_u_perc
,
ro_space
->
bottom
());
tty
->
print_cr
(
fmt
,
"rw"
,
rw_bytes
,
rw_t_perc
,
rw_alloced
,
rw_u_perc
,
rw_space
->
bottom
());
tty
->
print_cr
(
fmt
,
"md"
,
md_bytes
,
md_t_perc
,
md_alloced
,
md_u_perc
,
md_low
);
tty
->
print_cr
(
fmt
,
"mc"
,
mc_bytes
,
mc_t_perc
,
mc_alloced
,
mc_u_perc
,
mc_low
);
tty
->
print_cr
(
"total : %9d [100.0%% of total] out of %9d bytes [%4.1f%% used]"
,
total_bytes
,
total_alloced
,
total_u_perc
);
// Update the vtable pointers in all of the Klass objects in the
// heap. They should point to newly generated vtable.
...
...
src/share/vm/oops/constMethod.hpp
浏览文件 @
817c1633
...
...
@@ -122,7 +122,12 @@ class ExceptionTableElement VALUE_OBJ_CLASS_SPEC {
class
MethodParametersElement
VALUE_OBJ_CLASS_SPEC
{
public:
u2
name_cp_index
;
u4
flags
;
// This has to happen, otherwise it will cause SIGBUS from a
// misaligned u4 on some architectures (ie SPARC)
// because MethodParametersElements are only aligned mod 2
// within the ConstMethod container u2 flags_hi;
u2
flags_hi
;
u2
flags_lo
;
};
...
...
src/share/vm/oops/fieldInfo.hpp
浏览文件 @
817c1633
...
...
@@ -43,14 +43,29 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC {
public:
// fields
// Field info extracted from the class file and stored
// as an array of 7 shorts
// as an array of 6 shorts.
#define FIELDINFO_TAG_SIZE 2
#define FIELDINFO_TAG_BLANK 0
#define FIELDINFO_TAG_OFFSET 1
#define FIELDINFO_TAG_TYPE_PLAIN 2
#define FIELDINFO_TAG_TYPE_CONTENDED 3
#define FIELDINFO_TAG_MASK 3
// Packed field has the tag, and can be either of:
// hi bits <--------------------------- lo bits
// |---------high---------|---------low---------|
// ..........................................00 - blank
// [------------------offset----------------]01 - real field offset
// ......................[-------type-------]10 - plain field with type
// [--contention_group--][-------type-------]11 - contended field with type and contention group
enum
FieldOffset
{
access_flags_offset
=
0
,
name_index_offset
=
1
,
signature_index_offset
=
2
,
initval_index_offset
=
3
,
low_
offset
=
4
,
high_
offset
=
5
,
low_
packed_offset
=
4
,
high_
packed_offset
=
5
,
field_slots
=
6
};
...
...
@@ -76,17 +91,90 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC {
void
initialize
(
u2
access_flags
,
u2
name_index
,
u2
signature_index
,
u2
initval_index
,
u4
offset
)
{
u2
initval_index
)
{
_shorts
[
access_flags_offset
]
=
access_flags
;
_shorts
[
name_index_offset
]
=
name_index
;
_shorts
[
signature_index_offset
]
=
signature_index
;
_shorts
[
initval_index_offset
]
=
initval_index
;
set_offset
(
offset
);
_shorts
[
low_packed_offset
]
=
0
;
_shorts
[
high_packed_offset
]
=
0
;
}
u2
access_flags
()
const
{
return
_shorts
[
access_flags_offset
];
}
u4
offset
()
const
{
return
build_int_from_shorts
(
_shorts
[
low_offset
],
_shorts
[
high_offset
]);
}
u4
offset
()
const
{
u2
lo
=
_shorts
[
low_packed_offset
];
switch
(
lo
&
FIELDINFO_TAG_MASK
)
{
case
FIELDINFO_TAG_OFFSET
:
return
build_int_from_shorts
(
_shorts
[
low_packed_offset
],
_shorts
[
high_packed_offset
])
>>
FIELDINFO_TAG_SIZE
;
#ifndef PRODUCT
case
FIELDINFO_TAG_TYPE_PLAIN
:
ShouldNotReachHere2
(
"Asking offset for the plain type field"
);
case
FIELDINFO_TAG_TYPE_CONTENDED
:
ShouldNotReachHere2
(
"Asking offset for the contended type field"
);
case
FIELDINFO_TAG_BLANK
:
ShouldNotReachHere2
(
"Asking offset for the blank field"
);
#endif
}
ShouldNotReachHere
();
return
0
;
}
bool
is_contended
()
const
{
u2
lo
=
_shorts
[
low_packed_offset
];
switch
(
lo
&
FIELDINFO_TAG_MASK
)
{
case
FIELDINFO_TAG_TYPE_PLAIN
:
return
false
;
case
FIELDINFO_TAG_TYPE_CONTENDED
:
return
true
;
#ifndef PRODUCT
case
FIELDINFO_TAG_OFFSET
:
ShouldNotReachHere2
(
"Asking contended flag for the field with offset"
);
case
FIELDINFO_TAG_BLANK
:
ShouldNotReachHere2
(
"Asking contended flag for the blank field"
);
#endif
}
ShouldNotReachHere
();
return
false
;
}
u2
contended_group
()
const
{
u2
lo
=
_shorts
[
low_packed_offset
];
switch
(
lo
&
FIELDINFO_TAG_MASK
)
{
case
FIELDINFO_TAG_TYPE_PLAIN
:
return
0
;
case
FIELDINFO_TAG_TYPE_CONTENDED
:
return
_shorts
[
high_packed_offset
];
#ifndef PRODUCT
case
FIELDINFO_TAG_OFFSET
:
ShouldNotReachHere2
(
"Asking the contended group for the field with offset"
);
case
FIELDINFO_TAG_BLANK
:
ShouldNotReachHere2
(
"Asking the contended group for the blank field"
);
#endif
}
ShouldNotReachHere
();
return
0
;
}
u2
allocation_type
()
const
{
u2
lo
=
_shorts
[
low_packed_offset
];
switch
(
lo
&
FIELDINFO_TAG_MASK
)
{
case
FIELDINFO_TAG_TYPE_PLAIN
:
case
FIELDINFO_TAG_TYPE_CONTENDED
:
return
(
lo
>>
FIELDINFO_TAG_SIZE
);
#ifndef PRODUCT
case
FIELDINFO_TAG_OFFSET
:
ShouldNotReachHere2
(
"Asking the field type for field with offset"
);
case
FIELDINFO_TAG_BLANK
:
ShouldNotReachHere2
(
"Asking the field type for the blank field"
);
#endif
}
ShouldNotReachHere
();
return
0
;
}
bool
is_offset_set
()
const
{
return
(
_shorts
[
low_packed_offset
]
&
FIELDINFO_TAG_MASK
)
==
FIELDINFO_TAG_OFFSET
;
}
Symbol
*
name
(
constantPoolHandle
cp
)
const
{
int
index
=
name_index
();
...
...
@@ -106,8 +194,46 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC {
void
set_access_flags
(
u2
val
)
{
_shorts
[
access_flags_offset
]
=
val
;
}
void
set_offset
(
u4
val
)
{
_shorts
[
low_offset
]
=
extract_low_short_from_int
(
val
);
_shorts
[
high_offset
]
=
extract_high_short_from_int
(
val
);
val
=
val
<<
FIELDINFO_TAG_SIZE
;
// make room for tag
_shorts
[
low_packed_offset
]
=
extract_low_short_from_int
(
val
)
|
FIELDINFO_TAG_OFFSET
;
_shorts
[
high_packed_offset
]
=
extract_high_short_from_int
(
val
);
}
void
set_allocation_type
(
int
type
)
{
u2
lo
=
_shorts
[
low_packed_offset
];
switch
(
lo
&
FIELDINFO_TAG_MASK
)
{
case
FIELDINFO_TAG_BLANK
:
_shorts
[
low_packed_offset
]
=
((
type
<<
FIELDINFO_TAG_SIZE
))
&
0xFFFF
;
_shorts
[
low_packed_offset
]
&=
~
FIELDINFO_TAG_MASK
;
_shorts
[
low_packed_offset
]
|=
FIELDINFO_TAG_TYPE_PLAIN
;
return
;
#ifndef PRODUCT
case
FIELDINFO_TAG_TYPE_PLAIN
:
case
FIELDINFO_TAG_TYPE_CONTENDED
:
case
FIELDINFO_TAG_OFFSET
:
ShouldNotReachHere2
(
"Setting the field type with overwriting"
);
#endif
}
ShouldNotReachHere
();
}
void
set_contended_group
(
u2
val
)
{
u2
lo
=
_shorts
[
low_packed_offset
];
switch
(
lo
&
FIELDINFO_TAG_MASK
)
{
case
FIELDINFO_TAG_TYPE_PLAIN
:
_shorts
[
low_packed_offset
]
|=
FIELDINFO_TAG_TYPE_CONTENDED
;
_shorts
[
high_packed_offset
]
=
val
;
return
;
#ifndef PRODUCT
case
FIELDINFO_TAG_TYPE_CONTENDED
:
ShouldNotReachHere2
(
"Overwriting contended group"
);
case
FIELDINFO_TAG_BLANK
:
ShouldNotReachHere2
(
"Setting contended group for the blank field"
);
case
FIELDINFO_TAG_OFFSET
:
ShouldNotReachHere2
(
"Setting contended group for field with offset"
);
#endif
}
ShouldNotReachHere
();
}
bool
is_internal
()
const
{
...
...
src/share/vm/oops/fieldStreams.hpp
浏览文件 @
817c1633
...
...
@@ -160,9 +160,26 @@ class FieldStreamBase : public StackObj {
return
field
()
->
offset
();
}
int
allocation_type
()
const
{
return
field
()
->
allocation_type
();
}
void
set_offset
(
int
offset
)
{
field
()
->
set_offset
(
offset
);
}
bool
is_offset_set
()
const
{
return
field
()
->
is_offset_set
();
}
bool
is_contended
()
const
{
return
field
()
->
is_contended
();
}
int
contended_group
()
const
{
return
field
()
->
contended_group
();
}
};
// Iterate over only the internal fields
...
...
src/share/vm/oops/instanceKlass.hpp
浏览文件 @
817c1633
...
...
@@ -230,7 +230,8 @@ class InstanceKlass: public Klass {
_misc_rewritten
=
1
<<
0
,
// methods rewritten.
_misc_has_nonstatic_fields
=
1
<<
1
,
// for sizing with UseCompressedOops
_misc_should_verify_class
=
1
<<
2
,
// allow caching of preverification
_misc_is_anonymous
=
1
<<
3
// has embedded _inner_classes field
_misc_is_anonymous
=
1
<<
3
,
// has embedded _inner_classes field
_misc_is_contended
=
1
<<
4
// marked with contended annotation
};
u2
_misc_flags
;
u2
_minor_version
;
// minor version number of class file
...
...
@@ -550,6 +551,17 @@ class InstanceKlass: public Klass {
return
is_anonymous
()
?
java_mirror
()
:
class_loader
();
}
bool
is_contended
()
const
{
return
(
_misc_flags
&
_misc_is_contended
)
!=
0
;
}
void
set_is_contended
(
bool
value
)
{
if
(
value
)
{
_misc_flags
|=
_misc_is_contended
;
}
else
{
_misc_flags
&=
~
_misc_is_contended
;
}
}
// signers
objArrayOop
signers
()
const
{
return
_signers
;
}
void
set_signers
(
objArrayOop
s
)
{
klass_oop_store
((
oop
*
)
&
_signers
,
s
);
}
...
...
src/share/vm/prims/jvm.cpp
浏览文件 @
817c1633
...
...
@@ -1589,6 +1589,12 @@ JVM_ENTRY(jbyteArray, JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls))
return
NULL
;
JVM_END
static
void
bounds_check
(
constantPoolHandle
cp
,
jint
index
,
TRAPS
)
{
if
(
!
cp
->
is_within_bounds
(
index
))
{
THROW_MSG
(
vmSymbols
::
java_lang_IllegalArgumentException
(),
"Constant pool index out of bounds"
);
}
}
JVM_ENTRY
(
jobjectArray
,
JVM_GetMethodParameters
(
JNIEnv
*
env
,
jobject
method
))
{
JVMWrapper
(
"JVM_GetMethodParameters"
);
...
...
@@ -1598,15 +1604,31 @@ JVM_ENTRY(jobjectArray, JVM_GetMethodParameters(JNIEnv *env, jobject method))
Handle
reflected_method
(
THREAD
,
JNIHandles
::
resolve_non_null
(
method
));
const
int
num_params
=
mh
->
method_parameters_length
();
if
(
0
!=
num_params
)
{
if
(
0
!=
num_params
)
{
// make sure all the symbols are properly formatted
for
(
int
i
=
0
;
i
<
num_params
;
i
++
)
{
MethodParametersElement
*
params
=
mh
->
method_parameters_start
();
int
index
=
params
[
i
].
name_cp_index
;
bounds_check
(
mh
->
constants
(),
index
,
CHECK_NULL
);
if
(
0
!=
index
&&
!
mh
->
constants
()
->
tag_at
(
index
).
is_utf8
())
{
THROW_MSG_0
(
vmSymbols
::
java_lang_IllegalArgumentException
(),
"Wrong type at constant pool index"
);
}
}
objArrayOop
result_oop
=
oopFactory
::
new_objArray
(
SystemDictionary
::
reflect_Parameter_klass
(),
num_params
,
CHECK_NULL
);
objArrayHandle
result
(
THREAD
,
result_oop
);
for
(
int
i
=
0
;
i
<
num_params
;
i
++
)
{
for
(
int
i
=
0
;
i
<
num_params
;
i
++
)
{
MethodParametersElement
*
params
=
mh
->
method_parameters_start
();
Symbol
*
const
sym
=
mh
->
constants
()
->
symbol_at
(
params
[
i
].
name_cp_index
);
// For a 0 index, give a NULL symbol
Symbol
*
const
sym
=
0
!=
params
[
i
].
name_cp_index
?
mh
->
constants
()
->
symbol_at
(
params
[
i
].
name_cp_index
)
:
NULL
;
int
flags
=
build_int_from_shorts
(
params
[
i
].
flags_lo
,
params
[
i
].
flags_hi
);
oop
param
=
Reflection
::
new_parameter
(
reflected_method
,
i
,
sym
,
params
[
i
].
flags
,
CHECK_NULL
);
flags
,
CHECK_NULL
);
result
->
obj_at_put
(
i
,
param
);
}
return
(
jobjectArray
)
JNIHandles
::
make_local
(
env
,
result
());
...
...
@@ -1830,13 +1852,6 @@ JVM_ENTRY(jint, JVM_ConstantPoolGetSize(JNIEnv *env, jobject obj, jobject unused
JVM_END
static
void
bounds_check
(
constantPoolHandle
cp
,
jint
index
,
TRAPS
)
{
if
(
!
cp
->
is_within_bounds
(
index
))
{
THROW_MSG
(
vmSymbols
::
java_lang_IllegalArgumentException
(),
"Constant pool index out of bounds"
);
}
}
JVM_ENTRY
(
jclass
,
JVM_ConstantPoolGetClassAt
(
JNIEnv
*
env
,
jobject
obj
,
jobject
unused
,
jint
index
))
{
JVMWrapper
(
"JVM_ConstantPoolGetClassAt"
);
...
...
@@ -1851,7 +1866,6 @@ JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject obj, jobject u
}
JVM_END
JVM_ENTRY
(
jclass
,
JVM_ConstantPoolGetClassAtIfLoaded
(
JNIEnv
*
env
,
jobject
obj
,
jobject
unused
,
jint
index
))
{
JVMWrapper
(
"JVM_ConstantPoolGetClassAtIfLoaded"
);
...
...
src/share/vm/runtime/globals.hpp
浏览文件 @
817c1633
...
...
@@ -1075,7 +1075,7 @@ class CommandLineFlags {
\
product(intx, ClearFPUAtPark, 0, "(Unsafe,Unstable)" ) \
\
product(intx, hashCode,
0
, \
product(intx, hashCode,
5
, \
"(Unstable) select hashCode generation algorithm" ) \
\
product(intx, WorkAroundNPTLTimedWaitHang, 1, \
...
...
@@ -1166,6 +1166,18 @@ class CommandLineFlags {
notproduct(bool, PrintCompactFieldsSavings, false, \
"Print how many words were saved with CompactFields") \
\
notproduct(bool, PrintFieldLayout, false, \
"Print field layout for each class") \
\
product(intx, ContendedPaddingWidth, 128, \
"How many bytes to pad the fields/classes marked @Contended with")\
\
product(bool, EnableContended, true, \
"Enable @Contended annotation support") \
\
product(bool, RestrictContended, true, \
"Restrict @Contended to trusted classes") \
\
product(bool, UseBiasedLocking, true, \
"Enable biased locking in JVM") \
\
...
...
src/share/vm/runtime/java.cpp
浏览文件 @
817c1633
...
...
@@ -542,6 +542,10 @@ void before_exit(JavaThread * thread) {
BeforeExit_lock
->
notify_all
();
}
// Shutdown NMT before exit. Otherwise,
// it will run into trouble when system destroys static variables.
MemTracker
::
shutdown
(
MemTracker
::
NMT_normal
);
#undef BEFORE_EXIT_NOT_RUN
#undef BEFORE_EXIT_RUNNING
#undef BEFORE_EXIT_DONE
...
...
src/share/vm/runtime/reflection.cpp
浏览文件 @
817c1633
...
...
@@ -862,7 +862,15 @@ oop Reflection::new_field(fieldDescriptor* fd, bool intern_name, TRAPS) {
oop
Reflection
::
new_parameter
(
Handle
method
,
int
index
,
Symbol
*
sym
,
int
flags
,
TRAPS
)
{
Handle
name
=
java_lang_String
::
create_from_symbol
(
sym
,
CHECK_NULL
);
Handle
name
;
// A null symbol here translates to the empty string
if
(
NULL
!=
sym
)
{
name
=
java_lang_String
::
create_from_symbol
(
sym
,
CHECK_NULL
);
}
else
{
name
=
java_lang_String
::
create_from_str
(
""
,
CHECK_NULL
);
}
Handle
rh
=
java_lang_reflect_Parameter
::
create
(
CHECK_NULL
);
java_lang_reflect_Parameter
::
set_name
(
rh
(),
name
());
java_lang_reflect_Parameter
::
set_modifiers
(
rh
(),
flags
);
...
...
src/share/vm/runtime/thread.cpp
浏览文件 @
817c1633
...
...
@@ -4011,10 +4011,6 @@ bool Threads::destroy_vm() {
Mutex
::
_as_suspend_equivalent_flag
);
}
// Shutdown NMT before exit. Otherwise,
// it will run into trouble when system destroys static variables.
MemTracker
::
shutdown
(
MemTracker
::
NMT_normal
);
// Hang forever on exit if we are reporting an error.
if
(
ShowMessageBoxOnError
&&
is_error_reported
())
{
os
::
infinite_sleep
();
...
...
src/share/vm/runtime/vmStructs.cpp
浏览文件 @
817c1633
...
...
@@ -257,8 +257,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
c1_nonstatic_field, \
c2_nonstatic_field, \
unchecked_c1_static_field, \
unchecked_c2_static_field, \
last_entry) \
unchecked_c2_static_field) \
\
/******************************************************************/
\
/* OopDesc and Klass hierarchies (NOTE: MethodData* incomplete) */
\
...
...
@@ -718,7 +717,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
nonstatic_field(ClassLoaderData, _next, ClassLoaderData*) \
\
static_field(ClassLoaderDataGraph, _head, ClassLoaderData*) \
nonstatic_field(ClassLoaderDataGraph, _unloading, ClassLoaderData*) \
\
/*******************/
\
/* GrowableArrays */
\
...
...
@@ -1238,9 +1236,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
nonstatic_field(FreeList<Metablock>, _count, ssize_t) \
nonstatic_field(MetablockTreeDictionary, _total_size, size_t)
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_STRUCTS_OS_CPU macro (and must */
/* be present there) */
//--------------------------------------------------------------------------------
// VM_TYPES
...
...
@@ -1280,8 +1275,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
declare_unsigned_integer_type, \
declare_c1_toplevel_type, \
declare_c2_type, \
declare_c2_toplevel_type, \
last_entry) \
declare_c2_toplevel_type) \
\
/*************************************************************/
\
/* Java primitive types -- required by the SA implementation */
\
...
...
@@ -2098,10 +2092,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
declare_type(MetablockTreeDictionary, FreeBlockDictionary<Metablock>)
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_TYPES_OS_CPU macro (and must be */
/* present there) */
//--------------------------------------------------------------------------------
// VM_INT_CONSTANTS
//
...
...
@@ -2114,8 +2104,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
declare_preprocessor_constant, \
declare_c1_constant, \
declare_c2_constant, \
declare_c2_preprocessor_constant, \
last_entry) \
declare_c2_preprocessor_constant) \
\
/******************/
\
/* Useful globals */
\
...
...
@@ -2294,10 +2283,17 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
declare_constant(FieldInfo::name_index_offset) \
declare_constant(FieldInfo::signature_index_offset) \
declare_constant(FieldInfo::initval_index_offset) \
declare_constant(FieldInfo::low_
offset)
\
declare_constant(FieldInfo::high_
offset)
\
declare_constant(FieldInfo::low_
packed_offset)
\
declare_constant(FieldInfo::high_
packed_offset)
\
declare_constant(FieldInfo::field_slots) \
\
/*************************************/
\
/* FieldInfo tag constants */
\
/*************************************/
\
\
declare_preprocessor_constant("FIELDINFO_TAG_SIZE", FIELDINFO_TAG_SIZE) \
declare_preprocessor_constant("FIELDINFO_TAG_OFFSET", FIELDINFO_TAG_OFFSET) \
\
/************************************************/
\
/* InstanceKlass InnerClassAttributeOffset enum */
\
/************************************************/
\
...
...
@@ -2483,9 +2479,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
declare_c2_preprocessor_constant("SAVED_ON_ENTRY_REG_COUNT", SAVED_ON_ENTRY_REG_COUNT) \
declare_c2_preprocessor_constant("C_SAVED_ON_ENTRY_REG_COUNT", C_SAVED_ON_ENTRY_REG_COUNT)
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_INT_CONSTANTS_OS_CPU macro (and */
/* must be present there) */
//--------------------------------------------------------------------------------
// VM_LONG_CONSTANTS
...
...
@@ -2495,7 +2488,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
// enums, etc., while "declare_preprocessor_constant" must be used for
// all #defined constants.
#define VM_LONG_CONSTANTS(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant
, last_entry
) \
#define VM_LONG_CONSTANTS(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
\
/*********************/
\
/* MarkOop constants */
\
...
...
@@ -2541,11 +2534,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
/* Constants in markOop used by CMS. */
\
declare_constant(markOopDesc::cms_shift) \
declare_constant(markOopDesc::cms_mask) \
declare_constant(markOopDesc::size_shift) \
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and */
/* must be present there) */
declare_constant(markOopDesc::size_shift)
//--------------------------------------------------------------------------------
...
...
@@ -2585,7 +2574,8 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
// This macro checks the type of a VMStructEntry by comparing pointer types
#define CHECK_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
{typeName *dummyObj = NULL; type* dummy = &dummyObj->fieldName; }
{typeName *dummyObj = NULL; type* dummy = &dummyObj->fieldName; \
assert(offset_of(typeName, fieldName) < sizeof(typeName), "Illegal nonstatic struct entry, field offset too large"); }
// This macro checks the type of a volatile VMStructEntry by comparing pointer types
#define CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
...
...
@@ -2608,9 +2598,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
// This is a no-op macro for unchecked fields
#define CHECK_NO_OP(a, b, c)
// This is a no-op macro for the sentinel value
#define CHECK_SENTINEL()
//
// Build-specific macros:
//
...
...
@@ -2789,48 +2776,47 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
// as long as class VMStructs is a friend
VMStructEntry
VMStructs
::
localHotSpotVMStructs
[]
=
{
VM_STRUCTS
(
GENERATE_NONSTATIC_VM_STRUCT_ENTRY
,
\
GENERATE_STATIC_VM_STRUCT_ENTRY
,
\
GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY
,
\
GENERATE_NONSTATIC_VM_STRUCT_ENTRY
,
\
GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY
,
\
GENERATE_C1_NONSTATIC_VM_STRUCT_ENTRY
,
\
GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY
,
\
GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY
,
\
GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY
,
\
GENERATE_VM_STRUCT_LAST_ENTRY
)
VM_STRUCTS
(
GENERATE_NONSTATIC_VM_STRUCT_ENTRY
,
GENERATE_STATIC_VM_STRUCT_ENTRY
,
GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY
,
GENERATE_NONSTATIC_VM_STRUCT_ENTRY
,
GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY
,
GENERATE_C1_NONSTATIC_VM_STRUCT_ENTRY
,
GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY
,
GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY
,
GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY
)
#ifndef SERIALGC
VM_STRUCTS_PARALLELGC
(
GENERATE_NONSTATIC_VM_STRUCT_ENTRY
,
\
VM_STRUCTS_PARALLELGC
(
GENERATE_NONSTATIC_VM_STRUCT_ENTRY
,
GENERATE_STATIC_VM_STRUCT_ENTRY
)
VM_STRUCTS_CMS
(
GENERATE_NONSTATIC_VM_STRUCT_ENTRY
,
\
GENERATE_NONSTATIC_VM_STRUCT_ENTRY
,
\
VM_STRUCTS_CMS
(
GENERATE_NONSTATIC_VM_STRUCT_ENTRY
,
GENERATE_NONSTATIC_VM_STRUCT_ENTRY
,
GENERATE_STATIC_VM_STRUCT_ENTRY
)
VM_STRUCTS_G1
(
GENERATE_NONSTATIC_VM_STRUCT_ENTRY
,
\
VM_STRUCTS_G1
(
GENERATE_NONSTATIC_VM_STRUCT_ENTRY
,
GENERATE_STATIC_VM_STRUCT_ENTRY
)
#endif // SERIALGC
VM_STRUCTS_CPU
(
GENERATE_NONSTATIC_VM_STRUCT_ENTRY
,
\
GENERATE_STATIC_VM_STRUCT_ENTRY
,
\
GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY
,
\
GENERATE_NONSTATIC_VM_STRUCT_ENTRY
,
\
GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY
,
\
GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY
,
\
GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY
,
\
GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY
,
\
GENERATE_VM_STRUCT_LAST_ENTRY
)
VM_STRUCTS_OS_CPU
(
GENERATE_NONSTATIC_VM_STRUCT_ENTRY
,
\
GENERATE_
STATIC_VM_STRUCT_ENTRY
,
\
GENERATE_
UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY
,
\
GENERATE_NON
STATIC_VM_STRUCT_ENTRY
,
\
GENERATE_
NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY
,
\
GENERATE_C
2_NONSTATIC_VM_STRUCT_ENTRY
,
\
GENERATE_C
1_UNCHECKED_STATIC_VM_STRUCT_ENTRY
,
\
GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY
,
\
GENERATE_VM_STRUCT_LAST_ENTRY
)
VM_STRUCTS_CPU
(
GENERATE_NONSTATIC_VM_STRUCT_ENTRY
,
GENERATE_STATIC_VM_STRUCT_ENTRY
,
GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY
,
GENERATE_NONSTATIC_VM_STRUCT_ENTRY
,
GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY
,
GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY
,
GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY
,
GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY
)
VM_STRUCTS_OS_CPU
(
GENERATE_NONSTATIC_VM_STRUCT_ENTRY
,
GENERATE_STATIC_VM_STRUCT_ENTRY
,
GENERATE_
UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY
,
GENERATE_
NONSTATIC_VM_STRUCT_ENTRY
,
GENERATE_NON
PRODUCT_NONSTATIC_VM_STRUCT_ENTRY
,
GENERATE_
C2_NONSTATIC_VM_STRUCT_ENTRY
,
GENERATE_C
1_UNCHECKED_STATIC_VM_STRUCT_ENTRY
,
GENERATE_C
2_UNCHECKED_STATIC_VM_STRUCT_ENTRY
)
GENERATE_VM_STRUCT_LAST_ENTRY
(
)
};
VMTypeEntry
VMStructs
::
localHotSpotVMTypes
[]
=
{
...
...
@@ -2842,8 +2828,7 @@ VMTypeEntry VMStructs::localHotSpotVMTypes[] = {
GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY
,
GENERATE_C1_TOPLEVEL_VM_TYPE_ENTRY
,
GENERATE_C2_VM_TYPE_ENTRY
,
GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY
,
GENERATE_VM_TYPE_LAST_ENTRY
)
GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY
)
#ifndef SERIALGC
VM_TYPES_PARALLELGC
(
GENERATE_VM_TYPE_ENTRY
,
...
...
@@ -2865,8 +2850,7 @@ VMTypeEntry VMStructs::localHotSpotVMTypes[] = {
GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY
,
GENERATE_C1_TOPLEVEL_VM_TYPE_ENTRY
,
GENERATE_C2_VM_TYPE_ENTRY
,
GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY
,
GENERATE_VM_TYPE_LAST_ENTRY
)
GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY
)
VM_TYPES_OS_CPU
(
GENERATE_VM_TYPE_ENTRY
,
GENERATE_TOPLEVEL_VM_TYPE_ENTRY
,
...
...
@@ -2875,8 +2859,9 @@ VMTypeEntry VMStructs::localHotSpotVMTypes[] = {
GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY
,
GENERATE_C1_TOPLEVEL_VM_TYPE_ENTRY
,
GENERATE_C2_VM_TYPE_ENTRY
,
GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY
,
GENERATE_VM_TYPE_LAST_ENTRY
)
GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY
)
GENERATE_VM_TYPE_LAST_ENTRY
()
};
VMIntConstantEntry
VMStructs
::
localHotSpotVMIntConstants
[]
=
{
...
...
@@ -2885,8 +2870,7 @@ VMIntConstantEntry VMStructs::localHotSpotVMIntConstants[] = {
GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY
,
GENERATE_C1_VM_INT_CONSTANT_ENTRY
,
GENERATE_C2_VM_INT_CONSTANT_ENTRY
,
GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY
,
GENERATE_VM_INT_CONSTANT_LAST_ENTRY
)
GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY
)
#ifndef SERIALGC
VM_INT_CONSTANTS_CMS
(
GENERATE_VM_INT_CONSTANT_ENTRY
)
...
...
@@ -2898,15 +2882,15 @@ VMIntConstantEntry VMStructs::localHotSpotVMIntConstants[] = {
GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY
,
GENERATE_C1_VM_INT_CONSTANT_ENTRY
,
GENERATE_C2_VM_INT_CONSTANT_ENTRY
,
GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY
,
GENERATE_VM_INT_CONSTANT_LAST_ENTRY
)
GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY
)
VM_INT_CONSTANTS_OS_CPU
(
GENERATE_VM_INT_CONSTANT_ENTRY
,
GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY
,
GENERATE_C1_VM_INT_CONSTANT_ENTRY
,
GENERATE_C2_VM_INT_CONSTANT_ENTRY
,
GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY
,
GENERATE_VM_INT_CONSTANT_LAST_ENTRY
)
GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY
)
GENERATE_VM_INT_CONSTANT_LAST_ENTRY
()
};
VMLongConstantEntry
VMStructs
::
localHotSpotVMLongConstants
[]
=
{
...
...
@@ -2915,22 +2899,21 @@ VMLongConstantEntry VMStructs::localHotSpotVMLongConstants[] = {
GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY
,
GENERATE_C1_VM_LONG_CONSTANT_ENTRY
,
GENERATE_C2_VM_LONG_CONSTANT_ENTRY
,
GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY
,
GENERATE_VM_LONG_CONSTANT_LAST_ENTRY
)
GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY
)
VM_LONG_CONSTANTS_CPU
(
GENERATE_VM_LONG_CONSTANT_ENTRY
,
GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY
,
GENERATE_C1_VM_LONG_CONSTANT_ENTRY
,
GENERATE_C2_VM_LONG_CONSTANT_ENTRY
,
GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY
,
GENERATE_VM_LONG_CONSTANT_LAST_ENTRY
)
GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY
)
VM_LONG_CONSTANTS_OS_CPU
(
GENERATE_VM_LONG_CONSTANT_ENTRY
,
GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY
,
GENERATE_C1_VM_LONG_CONSTANT_ENTRY
,
GENERATE_C2_VM_LONG_CONSTANT_ENTRY
,
GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY
,
GENERATE_VM_LONG_CONSTANT_LAST_ENTRY
)
GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY
)
GENERATE_VM_LONG_CONSTANT_LAST_ENTRY
()
};
// This is used both to check the types of referenced fields and, in
...
...
@@ -2945,8 +2928,7 @@ VMStructs::init() {
CHECK_C1_NONSTATIC_VM_STRUCT_ENTRY
,
CHECK_C2_NONSTATIC_VM_STRUCT_ENTRY
,
CHECK_NO_OP
,
CHECK_NO_OP
,
CHECK_SENTINEL
);
CHECK_NO_OP
);
#ifndef SERIALGC
VM_STRUCTS_PARALLELGC
(
CHECK_NONSTATIC_VM_STRUCT_ENTRY
,
...
...
@@ -2967,8 +2949,7 @@ VMStructs::init() {
CHECK_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY
,
CHECK_C2_NONSTATIC_VM_STRUCT_ENTRY
,
CHECK_NO_OP
,
CHECK_NO_OP
,
CHECK_SENTINEL
);
CHECK_NO_OP
);
VM_STRUCTS_OS_CPU
(
CHECK_NONSTATIC_VM_STRUCT_ENTRY
,
CHECK_STATIC_VM_STRUCT_ENTRY
,
...
...
@@ -2977,8 +2958,7 @@ VMStructs::init() {
CHECK_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY
,
CHECK_C2_NONSTATIC_VM_STRUCT_ENTRY
,
CHECK_NO_OP
,
CHECK_NO_OP
,
CHECK_SENTINEL
);
CHECK_NO_OP
);
VM_TYPES
(
CHECK_VM_TYPE_ENTRY
,
CHECK_SINGLE_ARG_VM_TYPE_NO_OP
,
...
...
@@ -2987,8 +2967,7 @@ VMStructs::init() {
CHECK_SINGLE_ARG_VM_TYPE_NO_OP
,
CHECK_C1_TOPLEVEL_VM_TYPE_ENTRY
,
CHECK_C2_VM_TYPE_ENTRY
,
CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY
,
CHECK_SENTINEL
);
CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY
);
#ifndef SERIALGC
VM_TYPES_PARALLELGC
(
CHECK_VM_TYPE_ENTRY
,
...
...
@@ -3010,8 +2989,7 @@ VMStructs::init() {
CHECK_SINGLE_ARG_VM_TYPE_NO_OP
,
CHECK_C1_TOPLEVEL_VM_TYPE_ENTRY
,
CHECK_C2_VM_TYPE_ENTRY
,
CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY
,
CHECK_SENTINEL
);
CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY
);
VM_TYPES_OS_CPU
(
CHECK_VM_TYPE_ENTRY
,
CHECK_SINGLE_ARG_VM_TYPE_NO_OP
,
...
...
@@ -3020,8 +2998,7 @@ VMStructs::init() {
CHECK_SINGLE_ARG_VM_TYPE_NO_OP
,
CHECK_C1_TOPLEVEL_VM_TYPE_ENTRY
,
CHECK_C2_VM_TYPE_ENTRY
,
CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY
,
CHECK_SENTINEL
);
CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY
);
//
// Split VM_STRUCTS() invocation into two parts to allow MS VC++ 6.0
...
...
@@ -3040,53 +3017,49 @@ VMStructs::init() {
// Solstice NFS setup. If everyone switches to local workspaces on
// Win32, we can put this back in.
#ifndef _WINDOWS
debug_only
(
VM_STRUCTS
(
ENSURE_FIELD_TYPE_PRESENT
,
\
CHECK_NO_OP
,
\
CHECK_NO_OP
,
\
CHECK_NO_OP
,
\
CHECK_NO_OP
,
\
CHECK_NO_OP
,
\
CHECK_NO_OP
,
\
CHECK_NO_OP
,
\
CHECK_NO_OP
,
\
CHECK_SENTINEL
));
debug_only
(
VM_STRUCTS
(
CHECK_NO_OP
,
\
ENSURE_FIELD_TYPE_PRESENT
,
\
CHECK_NO_OP
,
\
ENSURE_FIELD_TYPE_PRESENT
,
\
ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT
,
\
ENSURE_C1_FIELD_TYPE_PRESENT
,
\
ENSURE_C2_FIELD_TYPE_PRESENT
,
\
CHECK_NO_OP
,
\
CHECK_NO_OP
,
\
CHECK_SENTINEL
));
debug_only
(
VM_STRUCTS
(
ENSURE_FIELD_TYPE_PRESENT
,
CHECK_NO_OP
,
CHECK_NO_OP
,
CHECK_NO_OP
,
CHECK_NO_OP
,
CHECK_NO_OP
,
CHECK_NO_OP
,
CHECK_NO_OP
,
CHECK_NO_OP
));
debug_only
(
VM_STRUCTS
(
CHECK_NO_OP
,
ENSURE_FIELD_TYPE_PRESENT
,
CHECK_NO_OP
,
ENSURE_FIELD_TYPE_PRESENT
,
ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT
,
ENSURE_C1_FIELD_TYPE_PRESENT
,
ENSURE_C2_FIELD_TYPE_PRESENT
,
CHECK_NO_OP
,
CHECK_NO_OP
));
#ifndef SERIALGC
debug_only
(
VM_STRUCTS_PARALLELGC
(
ENSURE_FIELD_TYPE_PRESENT
,
\
debug_only
(
VM_STRUCTS_PARALLELGC
(
ENSURE_FIELD_TYPE_PRESENT
,
ENSURE_FIELD_TYPE_PRESENT
));
debug_only
(
VM_STRUCTS_CMS
(
ENSURE_FIELD_TYPE_PRESENT
,
\
ENSURE_FIELD_TYPE_PRESENT
,
\
debug_only
(
VM_STRUCTS_CMS
(
ENSURE_FIELD_TYPE_PRESENT
,
ENSURE_FIELD_TYPE_PRESENT
,
ENSURE_FIELD_TYPE_PRESENT
));
debug_only
(
VM_STRUCTS_G1
(
ENSURE_FIELD_TYPE_PRESENT
,
\
debug_only
(
VM_STRUCTS_G1
(
ENSURE_FIELD_TYPE_PRESENT
,
ENSURE_FIELD_TYPE_PRESENT
));
#endif // SERIALGC
debug_only
(
VM_STRUCTS_CPU
(
ENSURE_FIELD_TYPE_PRESENT
,
\
ENSURE_FIELD_TYPE_PRESENT
,
\
CHECK_NO_OP
,
\
ENSURE_FIELD_TYPE_PRESENT
,
\
ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT
,
\
ENSURE_C2_FIELD_TYPE_PRESENT
,
\
CHECK_NO_OP
,
\
CHECK_NO_OP
,
\
CHECK_SENTINEL
));
debug_only
(
VM_STRUCTS_OS_CPU
(
ENSURE_FIELD_TYPE_PRESENT
,
\
ENSURE_FIELD_TYPE_PRESENT
,
\
CHECK_NO_OP
,
\
ENSURE_FIELD_TYPE_PRESENT
,
\
ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT
,
\
ENSURE_C2_FIELD_TYPE_PRESENT
,
\
CHECK_NO_OP
,
\
CHECK_NO_OP
,
\
CHECK_SENTINEL
));
debug_only
(
VM_STRUCTS_CPU
(
ENSURE_FIELD_TYPE_PRESENT
,
ENSURE_FIELD_TYPE_PRESENT
,
CHECK_NO_OP
,
ENSURE_FIELD_TYPE_PRESENT
,
ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT
,
ENSURE_C2_FIELD_TYPE_PRESENT
,
CHECK_NO_OP
,
CHECK_NO_OP
));
debug_only
(
VM_STRUCTS_OS_CPU
(
ENSURE_FIELD_TYPE_PRESENT
,
ENSURE_FIELD_TYPE_PRESENT
,
CHECK_NO_OP
,
ENSURE_FIELD_TYPE_PRESENT
,
ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT
,
ENSURE_C2_FIELD_TYPE_PRESENT
,
CHECK_NO_OP
,
CHECK_NO_OP
));
#endif
}
...
...
@@ -3146,10 +3119,10 @@ static int recursiveFindType(VMTypeEntry* origtypes, const char* typeName, bool
s
[
len
-
1
]
=
'\0'
;
// tty->print_cr("checking \"%s\" for \"%s\"", s, typeName);
if
(
recursiveFindType
(
origtypes
,
s
,
true
)
==
1
)
{
delete
s
;
delete
[]
s
;
return
1
;
}
delete
s
;
delete
[]
s
;
}
const
char
*
start
=
NULL
;
if
(
strstr
(
typeName
,
"GrowableArray<"
)
==
typeName
)
{
...
...
@@ -3165,10 +3138,10 @@ static int recursiveFindType(VMTypeEntry* origtypes, const char* typeName, bool
s
[
len
-
1
]
=
'\0'
;
// tty->print_cr("checking \"%s\" for \"%s\"", s, typeName);
if
(
recursiveFindType
(
origtypes
,
s
,
true
)
==
1
)
{
delete
s
;
delete
[]
s
;
return
1
;
}
delete
s
;
delete
[]
s
;
}
if
(
strstr
(
typeName
,
"const "
)
==
typeName
)
{
const
char
*
s
=
typeName
+
strlen
(
"const "
);
...
...
@@ -3182,8 +3155,10 @@ static int recursiveFindType(VMTypeEntry* origtypes, const char* typeName, bool
s
[
len
-
6
]
=
'\0'
;
// tty->print_cr("checking \"%s\" for \"%s\"", s, typeName);
if
(
recursiveFindType
(
origtypes
,
s
,
true
)
==
1
)
{
free
(
s
);
return
1
;
}
free
(
s
);
}
if
(
!
isRecurse
)
{
tty
->
print_cr
(
"type
\"
%s
\"
not found"
,
typeName
);
...
...
@@ -3206,6 +3181,30 @@ void vmStructs_init() {
#ifndef PRODUCT
void
VMStructs
::
test
()
{
// Make sure last entry in the each array is indeed the correct end marker.
// The reason why these are static is to make sure they are zero initialized.
// Putting them on the stack will leave some garbage in the padding of some fields.
static
VMStructEntry
struct_last_entry
=
GENERATE_VM_STRUCT_LAST_ENTRY
();
assert
(
memcmp
(
&
localHotSpotVMStructs
[(
sizeof
(
localHotSpotVMStructs
)
/
sizeof
(
VMStructEntry
))
-
1
],
&
struct_last_entry
,
sizeof
(
VMStructEntry
))
==
0
,
"Incorrect last entry in localHotSpotVMStructs"
);
static
VMTypeEntry
type_last_entry
=
GENERATE_VM_TYPE_LAST_ENTRY
();
assert
(
memcmp
(
&
localHotSpotVMTypes
[
sizeof
(
localHotSpotVMTypes
)
/
sizeof
(
VMTypeEntry
)
-
1
],
&
type_last_entry
,
sizeof
(
VMTypeEntry
))
==
0
,
"Incorrect last entry in localHotSpotVMTypes"
);
static
VMIntConstantEntry
int_last_entry
=
GENERATE_VM_INT_CONSTANT_LAST_ENTRY
();
assert
(
memcmp
(
&
localHotSpotVMIntConstants
[
sizeof
(
localHotSpotVMIntConstants
)
/
sizeof
(
VMIntConstantEntry
)
-
1
],
&
int_last_entry
,
sizeof
(
VMIntConstantEntry
))
==
0
,
"Incorrect last entry in localHotSpotVMIntConstants"
);
static
VMLongConstantEntry
long_last_entry
=
GENERATE_VM_LONG_CONSTANT_LAST_ENTRY
();
assert
(
memcmp
(
&
localHotSpotVMLongConstants
[
sizeof
(
localHotSpotVMLongConstants
)
/
sizeof
(
VMLongConstantEntry
)
-
1
],
&
long_last_entry
,
sizeof
(
VMLongConstantEntry
))
==
0
,
"Incorrect last entry in localHotSpotVMLongConstants"
);
// Check for duplicate entries in type array
for
(
int
i
=
0
;
localHotSpotVMTypes
[
i
].
typeName
!=
NULL
;
i
++
)
{
for
(
int
j
=
i
+
1
;
localHotSpotVMTypes
[
j
].
typeName
!=
NULL
;
j
++
)
{
...
...
src/share/vm/utilities/exceptions.hpp
浏览文件 @
817c1633
/*
* Copyright (c) 1998, 201
2
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 201
3
, 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
...
...
@@ -267,6 +267,7 @@ class Exceptions {
#define THROW_WRAPPED_0(name, oop_to_wrap) THROW_WRAPPED_(name, oop_to_wrap, 0)
#define THROW_ARG_0(name, signature, arg) THROW_ARG_(name, signature, arg, 0)
#define THROW_MSG_CAUSE_0(name, message, cause) THROW_MSG_CAUSE_(name, message, cause, 0)
#define THROW_MSG_CAUSE_NULL(name, message, cause) THROW_MSG_CAUSE_(name, message, cause, NULL)
#define THROW_NULL(name) THROW_(name, NULL)
#define THROW_MSG_NULL(name, message) THROW_MSG_(name, message, NULL)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录