mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +02:00
Merge
This commit is contained in:
commit
6e8916cdbb
34 changed files with 1085 additions and 590 deletions
|
@ -52,6 +52,8 @@ public class InstanceKlass extends Klass {
|
||||||
private static int LOW_OFFSET;
|
private static int LOW_OFFSET;
|
||||||
private static int HIGH_OFFSET;
|
private static int HIGH_OFFSET;
|
||||||
private static int FIELD_SLOTS;
|
private static int FIELD_SLOTS;
|
||||||
|
private static short FIELDINFO_TAG_SIZE;
|
||||||
|
private static short FIELDINFO_TAG_OFFSET;
|
||||||
|
|
||||||
// ClassState constants
|
// ClassState constants
|
||||||
private static int CLASS_STATE_ALLOCATED;
|
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();
|
NAME_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::name_index_offset").intValue();
|
||||||
SIGNATURE_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::signature_index_offset").intValue();
|
SIGNATURE_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::signature_index_offset").intValue();
|
||||||
INITVAL_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::initval_index_offset").intValue();
|
INITVAL_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::initval_index_offset").intValue();
|
||||||
LOW_OFFSET = db.lookupIntConstant("FieldInfo::low_offset").intValue();
|
LOW_OFFSET = db.lookupIntConstant("FieldInfo::low_packed_offset").intValue();
|
||||||
HIGH_OFFSET = db.lookupIntConstant("FieldInfo::high_offset").intValue();
|
HIGH_OFFSET = db.lookupIntConstant("FieldInfo::high_packed_offset").intValue();
|
||||||
FIELD_SLOTS = db.lookupIntConstant("FieldInfo::field_slots").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
|
// read ClassState constants
|
||||||
CLASS_STATE_ALLOCATED = db.lookupIntConstant("InstanceKlass::allocated").intValue();
|
CLASS_STATE_ALLOCATED = db.lookupIntConstant("InstanceKlass::allocated").intValue();
|
||||||
CLASS_STATE_LOADED = db.lookupIntConstant("InstanceKlass::loaded").intValue();
|
CLASS_STATE_LOADED = db.lookupIntConstant("InstanceKlass::loaded").intValue();
|
||||||
|
@ -314,8 +319,12 @@ public class InstanceKlass extends Klass {
|
||||||
|
|
||||||
public int getFieldOffset(int index) {
|
public int getFieldOffset(int index) {
|
||||||
U2Array fields = getFields();
|
U2Array fields = getFields();
|
||||||
return VM.getVM().buildIntFromShorts(fields.at(index * FIELD_SLOTS + LOW_OFFSET),
|
short lo = fields.at(index * FIELD_SLOTS + LOW_OFFSET);
|
||||||
fields.at(index * FIELD_SLOTS + HIGH_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
|
// Accessors for declared fields
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
// constants required by the Serviceability Agent. This file is
|
// constants required by the Serviceability Agent. This file is
|
||||||
// referenced by vmStructs.cpp.
|
// 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 */ \
|
/* JavaCallWrapper */ \
|
||||||
|
@ -37,22 +37,12 @@
|
||||||
/******************************/ \
|
/******************************/ \
|
||||||
/* JavaFrameAnchor */ \
|
/* 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 */
|
#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)
|
||||||
/* 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) \
|
#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) \
|
|
||||||
/******************************/ \
|
/******************************/ \
|
||||||
/* Register numbers (C2 only) */ \
|
/* Register numbers (C2 only) */ \
|
||||||
/******************************/ \
|
/******************************/ \
|
||||||
|
@ -90,15 +80,6 @@
|
||||||
declare_c2_constant(R_G6_num) \
|
declare_c2_constant(R_G6_num) \
|
||||||
declare_c2_constant(R_G7_num)
|
declare_c2_constant(R_G7_num)
|
||||||
|
|
||||||
|
#define VM_LONG_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_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) */
|
|
||||||
|
|
||||||
#endif // CPU_SPARC_VM_VMSTRUCTS_SPARC_HPP
|
#endif // CPU_SPARC_VM_VMSTRUCTS_SPARC_HPP
|
||||||
|
|
|
@ -259,6 +259,10 @@ void VM_Version::initialize() {
|
||||||
if (!has_vis1()) // Drop to 0 if no VIS1 support
|
if (!has_vis1()) // Drop to 0 if no VIS1 support
|
||||||
UseVIS = 0;
|
UseVIS = 0;
|
||||||
|
|
||||||
|
if (FLAG_IS_DEFAULT(ContendedPaddingWidth) &&
|
||||||
|
(cache_line_size > ContendedPaddingWidth))
|
||||||
|
ContendedPaddingWidth = cache_line_size;
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
if (PrintMiscellaneous && Verbose) {
|
if (PrintMiscellaneous && Verbose) {
|
||||||
tty->print("Allocation");
|
tty->print("Allocation");
|
||||||
|
@ -286,6 +290,9 @@ void VM_Version::initialize() {
|
||||||
if (PrefetchFieldsAhead > 0) {
|
if (PrefetchFieldsAhead > 0) {
|
||||||
tty->print_cr("PrefetchFieldsAhead %d", PrefetchFieldsAhead);
|
tty->print_cr("PrefetchFieldsAhead %d", PrefetchFieldsAhead);
|
||||||
}
|
}
|
||||||
|
if (ContendedPaddingWidth > 0) {
|
||||||
|
tty->print_cr("ContendedPaddingWidth %d", ContendedPaddingWidth);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif // PRODUCT
|
#endif // PRODUCT
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
// constants required by the Serviceability Agent. This file is
|
// constants required by the Serviceability Agent. This file is
|
||||||
// referenced by vmStructs.cpp.
|
// 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 */ \
|
/* JavaCallWrapper */ \
|
||||||
|
@ -37,31 +37,14 @@
|
||||||
/******************************/ \
|
/******************************/ \
|
||||||
/* JavaFrameAnchor */ \
|
/* JavaFrameAnchor */ \
|
||||||
/******************************/ \
|
/******************************/ \
|
||||||
volatile_nonstatic_field(JavaFrameAnchor, _last_Java_fp, intptr_t*) \
|
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 */
|
#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)
|
||||||
/* 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)
|
||||||
|
|
||||||
#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
|
#define VM_LONG_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_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) */
|
|
||||||
|
|
||||||
#endif // CPU_X86_VM_VMSTRUCTS_X86_HPP
|
#endif // CPU_X86_VM_VMSTRUCTS_X86_HPP
|
||||||
|
|
|
@ -745,6 +745,10 @@ void VM_Version::get_processor_features() {
|
||||||
PrefetchFieldsAhead = prefetch_fields_ahead();
|
PrefetchFieldsAhead = prefetch_fields_ahead();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (FLAG_IS_DEFAULT(ContendedPaddingWidth) &&
|
||||||
|
(cache_line_size > ContendedPaddingWidth))
|
||||||
|
ContendedPaddingWidth = cache_line_size;
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
if (PrintMiscellaneous && Verbose) {
|
if (PrintMiscellaneous && Verbose) {
|
||||||
tty->print_cr("Logical CPUs per core: %u",
|
tty->print_cr("Logical CPUs per core: %u",
|
||||||
|
@ -791,6 +795,9 @@ void VM_Version::get_processor_features() {
|
||||||
if (PrefetchFieldsAhead > 0) {
|
if (PrefetchFieldsAhead > 0) {
|
||||||
tty->print_cr("PrefetchFieldsAhead %d", PrefetchFieldsAhead);
|
tty->print_cr("PrefetchFieldsAhead %d", PrefetchFieldsAhead);
|
||||||
}
|
}
|
||||||
|
if (ContendedPaddingWidth > 0) {
|
||||||
|
tty->print_cr("ContendedPaddingWidth %d", ContendedPaddingWidth);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif // !PRODUCT
|
#endif // !PRODUCT
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,28 +30,12 @@
|
||||||
// constants required by the Serviceability Agent. This file is
|
// constants required by the Serviceability Agent. This file is
|
||||||
// referenced by vmStructs.cpp.
|
// 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 */
|
#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)
|
||||||
/* 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) \
|
#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 */
|
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
|
||||||
/* 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) */
|
|
||||||
|
|
||||||
#endif // CPU_ZERO_VM_VMSTRUCTS_ZERO_HPP
|
#endif // CPU_ZERO_VM_VMSTRUCTS_ZERO_HPP
|
||||||
|
|
|
@ -49,7 +49,7 @@ void WindowsDecoder::initialize() {
|
||||||
pfn_SymSetOptions _pfnSymSetOptions = (pfn_SymSetOptions)::GetProcAddress(handle, "SymSetOptions");
|
pfn_SymSetOptions _pfnSymSetOptions = (pfn_SymSetOptions)::GetProcAddress(handle, "SymSetOptions");
|
||||||
pfn_SymInitialize _pfnSymInitialize = (pfn_SymInitialize)::GetProcAddress(handle, "SymInitialize");
|
pfn_SymInitialize _pfnSymInitialize = (pfn_SymInitialize)::GetProcAddress(handle, "SymInitialize");
|
||||||
_pfnSymGetSymFromAddr64 = (pfn_SymGetSymFromAddr64)::GetProcAddress(handle, "SymGetSymFromAddr64");
|
_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) {
|
if (_pfnSymSetOptions == NULL || _pfnSymInitialize == NULL || _pfnSymGetSymFromAddr64 == NULL) {
|
||||||
_pfnSymGetSymFromAddr64 = NULL;
|
_pfnSymGetSymFromAddr64 = NULL;
|
||||||
|
@ -60,8 +60,9 @@ void WindowsDecoder::initialize() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_pfnSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
|
HANDLE hProcess = ::GetCurrentProcess();
|
||||||
if (!_pfnSymInitialize(GetCurrentProcess(), NULL, TRUE)) {
|
_pfnSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_EXACT_SYMBOLS);
|
||||||
|
if (!_pfnSymInitialize(hProcess, NULL, TRUE)) {
|
||||||
_pfnSymGetSymFromAddr64 = NULL;
|
_pfnSymGetSymFromAddr64 = NULL;
|
||||||
_pfnUndecorateSymbolName = NULL;
|
_pfnUndecorateSymbolName = NULL;
|
||||||
::FreeLibrary(handle);
|
::FreeLibrary(handle);
|
||||||
|
@ -70,6 +71,77 @@ void WindowsDecoder::initialize() {
|
||||||
return;
|
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
|
// find out if jvm.dll contains private symbols, by decoding
|
||||||
// current function and comparing the result
|
// current function and comparing the result
|
||||||
address addr = (address)Decoder::demangle;
|
address addr = (address)Decoder::demangle;
|
||||||
|
|
|
@ -35,6 +35,8 @@ typedef DWORD (WINAPI *pfn_SymSetOptions)(DWORD);
|
||||||
typedef BOOL (WINAPI *pfn_SymInitialize)(HANDLE, PCTSTR, BOOL);
|
typedef BOOL (WINAPI *pfn_SymInitialize)(HANDLE, PCTSTR, BOOL);
|
||||||
typedef BOOL (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
|
typedef BOOL (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
|
||||||
typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWORD);
|
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 {
|
class WindowsDecoder : public AbstractDecoder {
|
||||||
|
|
||||||
|
|
|
@ -29,37 +29,26 @@
|
||||||
// constants required by the Serviceability Agent. This file is
|
// constants required by the Serviceability Agent. This file is
|
||||||
// referenced by vmStructs.cpp.
|
// 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) */ \
|
/* Threads (NOTE: incomplete) */ \
|
||||||
/******************************/ \
|
/******************************/ \
|
||||||
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
|
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
|
||||||
nonstatic_field(OSThread, _pthread_id, pthread_t) \
|
nonstatic_field(OSThread, _pthread_id, pthread_t)
|
||||||
/* 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, 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 */ \
|
/* Posix Thread IDs */ \
|
||||||
/**********************/ \
|
/**********************/ \
|
||||||
\
|
\
|
||||||
declare_unsigned_integer_type(OSThread::thread_id_t) \
|
declare_unsigned_integer_type(OSThread::thread_id_t) \
|
||||||
declare_unsigned_integer_type(pthread_t) \
|
declare_unsigned_integer_type(pthread_t)
|
||||||
\
|
|
||||||
/* 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, last_entry) \
|
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
|
||||||
\
|
|
||||||
/* 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) \
|
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
|
||||||
\
|
|
||||||
/* This must be the last entry, and must be present */ \
|
|
||||||
last_entry()
|
|
||||||
|
|
||||||
#endif // OS_CPU_BSD_X86_VM_VMSTRUCTS_BSD_X86_HPP
|
#endif // OS_CPU_BSD_X86_VM_VMSTRUCTS_BSD_X86_HPP
|
||||||
|
|
|
@ -30,21 +30,13 @@
|
||||||
// constants required by the Serviceability Agent. This file is
|
// constants required by the Serviceability Agent. This file is
|
||||||
// referenced by vmStructs.cpp.
|
// 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)
|
||||||
/* 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, 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)
|
||||||
/* 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, last_entry) \
|
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
|
||||||
/* 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) \
|
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
|
||||||
/* This must be the last entry, and must be present */ \
|
|
||||||
last_entry()
|
|
||||||
|
|
||||||
#endif // OS_CPU_BSD_ZERO_VM_VMSTRUCTS_BSD_ZERO_HPP
|
#endif // OS_CPU_BSD_ZERO_VM_VMSTRUCTS_BSD_ZERO_HPP
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
// constants required by the Serviceability Agent. This file is
|
// constants required by the Serviceability Agent. This file is
|
||||||
// referenced by vmStructs.cpp.
|
// 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) */ \
|
/* Threads (NOTE: incomplete) */ \
|
||||||
|
@ -37,38 +37,27 @@
|
||||||
\
|
\
|
||||||
nonstatic_field(JavaThread, _base_of_stack_pointer, intptr_t*) \
|
nonstatic_field(JavaThread, _base_of_stack_pointer, intptr_t*) \
|
||||||
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
|
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
|
||||||
nonstatic_field(OSThread, _pthread_id, pthread_t) \
|
nonstatic_field(OSThread, _pthread_id, pthread_t)
|
||||||
/* 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, 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 */ \
|
/* POSIX Thread IDs */ \
|
||||||
/**********************/ \
|
/**********************/ \
|
||||||
\
|
\
|
||||||
declare_integer_type(OSThread::thread_id_t) \
|
declare_integer_type(OSThread::thread_id_t) \
|
||||||
declare_unsigned_integer_type(pthread_t) \
|
declare_unsigned_integer_type(pthread_t)
|
||||||
\
|
|
||||||
/* 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, 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 */ \
|
/* JavaThread constants */ \
|
||||||
/************************/ \
|
/************************/ \
|
||||||
\
|
\
|
||||||
declare_constant(JavaFrameAnchor::flushed) \
|
declare_constant(JavaFrameAnchor::flushed)
|
||||||
\
|
|
||||||
/* 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) \
|
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
|
||||||
\
|
|
||||||
/* This must be the last entry, and must be present */ \
|
|
||||||
last_entry()
|
|
||||||
|
|
||||||
#endif // OS_CPU_LINUX_SPARC_VM_VMSTRUCTS_LINUX_SPARC_HPP
|
#endif // OS_CPU_LINUX_SPARC_VM_VMSTRUCTS_LINUX_SPARC_HPP
|
||||||
|
|
|
@ -29,37 +29,26 @@
|
||||||
// constants required by the Serviceability Agent. This file is
|
// constants required by the Serviceability Agent. This file is
|
||||||
// referenced by vmStructs.cpp.
|
// 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) */ \
|
/* Threads (NOTE: incomplete) */ \
|
||||||
/******************************/ \
|
/******************************/ \
|
||||||
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
|
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
|
||||||
nonstatic_field(OSThread, _pthread_id, pthread_t) \
|
nonstatic_field(OSThread, _pthread_id, pthread_t)
|
||||||
/* 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, 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 */ \
|
/* Posix Thread IDs */ \
|
||||||
/**********************/ \
|
/**********************/ \
|
||||||
\
|
\
|
||||||
declare_integer_type(OSThread::thread_id_t) \
|
declare_integer_type(OSThread::thread_id_t) \
|
||||||
declare_unsigned_integer_type(pthread_t) \
|
declare_unsigned_integer_type(pthread_t)
|
||||||
\
|
|
||||||
/* 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, last_entry) \
|
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
|
||||||
\
|
|
||||||
/* 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) \
|
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
|
||||||
\
|
|
||||||
/* This must be the last entry, and must be present */ \
|
|
||||||
last_entry()
|
|
||||||
|
|
||||||
#endif // OS_CPU_LINUX_X86_VM_VMSTRUCTS_LINUX_X86_HPP
|
#endif // OS_CPU_LINUX_X86_VM_VMSTRUCTS_LINUX_X86_HPP
|
||||||
|
|
|
@ -30,21 +30,12 @@
|
||||||
// constants required by the Serviceability Agent. This file is
|
// constants required by the Serviceability Agent. This file is
|
||||||
// referenced by vmStructs.cpp.
|
// 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)
|
||||||
/* 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_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_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
|
||||||
/* 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, last_entry) \
|
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
|
||||||
/* 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()
|
|
||||||
|
|
||||||
#endif // OS_CPU_LINUX_ZERO_VM_VMSTRUCTS_LINUX_ZERO_HPP
|
#endif // OS_CPU_LINUX_ZERO_VM_VMSTRUCTS_LINUX_ZERO_HPP
|
||||||
|
|
|
@ -29,44 +29,32 @@
|
||||||
// constants required by the Serviceability Agent. This file is
|
// constants required by the Serviceability Agent. This file is
|
||||||
// referenced by vmStructs.cpp.
|
// 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) */ \
|
/* Threads (NOTE: incomplete) */ \
|
||||||
/******************************/ \
|
/******************************/ \
|
||||||
\
|
\
|
||||||
nonstatic_field(JavaThread, _base_of_stack_pointer, intptr_t*) \
|
nonstatic_field(JavaThread, _base_of_stack_pointer, intptr_t*) \
|
||||||
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
|
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t)
|
||||||
/* 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_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) \
|
|
||||||
\
|
\
|
||||||
/**********************/ \
|
/**********************/ \
|
||||||
/* Solaris Thread IDs */ \
|
/* Solaris Thread IDs */ \
|
||||||
/**********************/ \
|
/**********************/ \
|
||||||
\
|
\
|
||||||
declare_unsigned_integer_type(OSThread::thread_id_t) \
|
declare_unsigned_integer_type(OSThread::thread_id_t)
|
||||||
\
|
|
||||||
/* 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, 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 */ \
|
/* JavaThread constants */ \
|
||||||
/************************/ \
|
/************************/ \
|
||||||
\
|
\
|
||||||
declare_constant(JavaFrameAnchor::flushed) \
|
declare_constant(JavaFrameAnchor::flushed)
|
||||||
\
|
|
||||||
/* 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) \
|
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
|
||||||
\
|
|
||||||
/* This must be the last entry, and must be present */ \
|
|
||||||
last_entry()
|
|
||||||
|
|
||||||
#endif // OS_CPU_SOLARIS_SPARC_VM_VMSTRUCTS_SOLARIS_SPARC_HPP
|
#endif // OS_CPU_SOLARIS_SPARC_VM_VMSTRUCTS_SOLARIS_SPARC_HPP
|
||||||
|
|
|
@ -29,36 +29,24 @@
|
||||||
// constants required by the Serviceability Agent. This file is
|
// constants required by the Serviceability Agent. This file is
|
||||||
// referenced by vmStructs.cpp.
|
// 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) */ \
|
/* Threads (NOTE: incomplete) */ \
|
||||||
/******************************/ \
|
/******************************/ \
|
||||||
\
|
\
|
||||||
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
|
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t)
|
||||||
\
|
|
||||||
/* 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, 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 */ \
|
/* Solaris Thread IDs */ \
|
||||||
/**********************/ \
|
/**********************/ \
|
||||||
\
|
\
|
||||||
declare_unsigned_integer_type(OSThread::thread_id_t) \
|
declare_unsigned_integer_type(OSThread::thread_id_t)
|
||||||
\
|
|
||||||
/* 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, last_entry) \
|
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
|
||||||
\
|
|
||||||
/* 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) \
|
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
|
||||||
\
|
|
||||||
/* This must be the last entry, and must be present */ \
|
|
||||||
last_entry()
|
|
||||||
|
|
||||||
#endif // OS_CPU_SOLARIS_X86_VM_VMSTRUCTS_SOLARIS_X86_HPP
|
#endif // OS_CPU_SOLARIS_X86_VM_VMSTRUCTS_SOLARIS_X86_HPP
|
||||||
|
|
|
@ -29,32 +29,21 @@
|
||||||
// constants required by the Serviceability Agent. This file is
|
// constants required by the Serviceability Agent. This file is
|
||||||
// referenced by vmStructs.cpp.
|
// 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) */ \
|
/* Threads (NOTE: incomplete) */ \
|
||||||
/******************************/ \
|
/******************************/ \
|
||||||
\
|
\
|
||||||
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
|
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
|
||||||
unchecked_nonstatic_field(OSThread, _thread_handle, sizeof(HANDLE)) /* NOTE: no type */ \
|
unchecked_nonstatic_field(OSThread, _thread_handle, sizeof(HANDLE)) /* NOTE: no type */
|
||||||
\
|
|
||||||
/* 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, 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) \
|
declare_unsigned_integer_type(OSThread::thread_id_t)
|
||||||
/* 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, last_entry) \
|
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
|
||||||
\
|
|
||||||
/* 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) \
|
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
|
||||||
\
|
|
||||||
/* This must be the last entry, and must be present */ \
|
|
||||||
last_entry()
|
|
||||||
|
|
||||||
#endif // OS_CPU_WINDOWS_X86_VM_VMSTRUCTS_WINDOWS_X86_HPP
|
#endif // OS_CPU_WINDOWS_X86_VM_VMSTRUCTS_WINDOWS_X86_HPP
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -59,6 +59,7 @@
|
||||||
#include "services/classLoadingService.hpp"
|
#include "services/classLoadingService.hpp"
|
||||||
#include "services/threadService.hpp"
|
#include "services/threadService.hpp"
|
||||||
#include "utilities/array.hpp"
|
#include "utilities/array.hpp"
|
||||||
|
#include "utilities/globalDefinitions.hpp"
|
||||||
|
|
||||||
// We generally try to create the oops directly when parsing, rather than
|
// We generally try to create the oops directly when parsing, rather than
|
||||||
// allocating temporary data structures and copying the bytes twice. A
|
// 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_length = attribute_length;
|
||||||
runtime_visible_annotations = cfs->get_u1_buffer();
|
runtime_visible_annotations = cfs->get_u1_buffer();
|
||||||
assert(runtime_visible_annotations != NULL, "null visible annotations");
|
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);
|
cfs->skip_u1(runtime_visible_annotations_length, CHECK);
|
||||||
} else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
|
} else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
|
||||||
runtime_invisible_annotations_length = attribute_length;
|
runtime_invisible_annotations_length = attribute_length;
|
||||||
|
@ -1216,19 +1223,16 @@ Array<u2>* ClassFileParser::parse_fields(ClassLoaderData* loader_data,
|
||||||
field->initialize(access_flags.as_short(),
|
field->initialize(access_flags.as_short(),
|
||||||
name_index,
|
name_index,
|
||||||
signature_index,
|
signature_index,
|
||||||
constantvalue_index,
|
constantvalue_index);
|
||||||
0);
|
|
||||||
if (parsed_annotations.has_any_annotations())
|
|
||||||
parsed_annotations.apply_to(field);
|
|
||||||
|
|
||||||
BasicType type = cp->basic_type_for_signature_at(signature_index);
|
BasicType type = cp->basic_type_for_signature_at(signature_index);
|
||||||
|
|
||||||
// Remember how many oops we encountered and compute allocation type
|
// Remember how many oops we encountered and compute allocation type
|
||||||
FieldAllocationType atype = fac->update(is_static, 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)
|
// After field is initialized with type, we can augment it with aux info
|
||||||
// We temporarily store the allocation type in the offset field
|
if (parsed_annotations.has_any_annotations())
|
||||||
field->set_offset(atype);
|
parsed_annotations.apply_to(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = length;
|
int index = length;
|
||||||
|
@ -1259,17 +1263,13 @@ Array<u2>* ClassFileParser::parse_fields(ClassLoaderData* loader_data,
|
||||||
field->initialize(JVM_ACC_FIELD_INTERNAL,
|
field->initialize(JVM_ACC_FIELD_INTERNAL,
|
||||||
injected[n].name_index,
|
injected[n].name_index,
|
||||||
injected[n].signature_index,
|
injected[n].signature_index,
|
||||||
0,
|
|
||||||
0);
|
0);
|
||||||
|
|
||||||
BasicType type = FieldType::basic_type(injected[n].signature());
|
BasicType type = FieldType::basic_type(injected[n].signature());
|
||||||
|
|
||||||
// Remember how many oops we encountered and compute allocation type
|
// Remember how many oops we encountered and compute allocation type
|
||||||
FieldAllocationType atype = fac->update(false, type);
|
FieldAllocationType atype = fac->update(false, 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);
|
|
||||||
index++;
|
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:
|
// 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,
|
constantPoolHandle cp,
|
||||||
ClassFileParser::AnnotationCollector* coll,
|
ClassFileParser::AnnotationCollector* coll,
|
||||||
TRAPS) {
|
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_type_off = 7, // utf8 such as 'Ljava/lang/annotation/RetentionPolicy;'
|
||||||
e_con_off = 9, // utf8 payload, such as 'SOURCE', 'CLASS', 'RUNTIME'
|
e_con_off = 9, // utf8 payload, such as 'SOURCE', 'CLASS', 'RUNTIME'
|
||||||
e_size = 11, // end of 'e' annotation
|
e_size = 11, // end of 'e' annotation
|
||||||
c_tag_val = 'c',
|
c_tag_val = 'c', // payload is type
|
||||||
c_con_off = 7, // utf8 payload, such as 'I' or 'Ljava/lang/String;'
|
c_con_off = 7, // utf8 payload, such as 'I'
|
||||||
c_size = 9, // end of 'c' annotation
|
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)
|
min_size = 6 // smallest possible size (zero members)
|
||||||
};
|
};
|
||||||
while ((--nann) >= 0 && (index-2 + min_size <= limit)) {
|
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.
|
// 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;
|
if (id == AnnotationCollector::_unknown) continue;
|
||||||
coll->set_annotation(id);
|
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.
|
if (id == AnnotationCollector::_sun_misc_Contended) {
|
||||||
// Suppose we want to capture @Retention.value. Here is how:
|
if (count == 1
|
||||||
//if (id == AnnotationCollector::_class_Retention) {
|
&& s_size == (index - index0) // match size
|
||||||
// Symbol* payload = NULL;
|
&& s_tag_val == *(abase + tag_off)
|
||||||
// if (count == 1
|
&& member == vmSymbols::value_name()) {
|
||||||
// && e_size == (index0 - index) // match size
|
u2 group_index = Bytes::get_Java_u2(abase + s_con_off);
|
||||||
// && e_tag_val == *(abase + tag_off)
|
coll->set_contended_group(group_index);
|
||||||
// && (check_symbol_at(cp, Bytes::get_Java_u2(abase + e_type_off))
|
} else {
|
||||||
// == vmSymbols::RetentionPolicy_signature())
|
coll->set_contended_group(0); // default contended group
|
||||||
// && member == vmSymbols::value_name()) {
|
}
|
||||||
// payload = check_symbol_at(cp, Bytes::get_Java_u2(abase + e_con_off));
|
coll->set_contended(true);
|
||||||
// }
|
} else {
|
||||||
// check_property(payload != NULL,
|
coll->set_contended(false);
|
||||||
// "Invalid @Retention annotation at offset %u in class file %s",
|
}
|
||||||
// index0, CHECK);
|
|
||||||
// if (payload != NULL) {
|
|
||||||
// payload->increment_refcount();
|
|
||||||
// coll->_class_RetentionPolicy = payload;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
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) {
|
switch (sid) {
|
||||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_ForceInline_signature):
|
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_ForceInline_signature):
|
||||||
if (_location != _in_method) break; // only allow for methods
|
if (_location != _in_method) break; // only allow for methods
|
||||||
|
if (!privileged) break; // only allow in privileged code
|
||||||
return _method_ForceInline;
|
return _method_ForceInline;
|
||||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_DontInline_signature):
|
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_DontInline_signature):
|
||||||
if (_location != _in_method) break; // only allow for methods
|
if (_location != _in_method) break; // only allow for methods
|
||||||
|
if (!privileged) break; // only allow in privileged code
|
||||||
return _method_DontInline;
|
return _method_DontInline;
|
||||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Compiled_signature):
|
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Compiled_signature):
|
||||||
if (_location != _in_method) break; // only allow for methods
|
if (_location != _in_method) break; // only allow for methods
|
||||||
|
if (!privileged) break; // only allow in privileged code
|
||||||
return _method_LambdaForm_Compiled;
|
return _method_LambdaForm_Compiled;
|
||||||
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Hidden_signature):
|
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Hidden_signature):
|
||||||
if (_location != _in_method) break; // only allow for methods
|
if (_location != _in_method) break; // only allow for methods
|
||||||
|
if (!privileged) break; // only allow in privileged code
|
||||||
return _method_LambdaForm_Hidden;
|
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;
|
default: break;
|
||||||
}
|
}
|
||||||
return AnnotationCollector::_unknown;
|
return AnnotationCollector::_unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassFileParser::FieldAnnotationCollector::apply_to(FieldInfo* f) {
|
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) {
|
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) {
|
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));
|
cp, CHECK_(nullHandle));
|
||||||
} else if (method_attribute_name == vmSymbols::tag_method_parameters()) {
|
} else if (method_attribute_name == vmSymbols::tag_method_parameters()) {
|
||||||
method_parameters_length = cfs->get_u1_fast();
|
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();
|
method_parameters_data = cfs->get_u1_buffer();
|
||||||
|
actual_size += 2 * method_parameters_length;
|
||||||
cfs->skip_u2_fast(method_parameters_length);
|
cfs->skip_u2_fast(method_parameters_length);
|
||||||
|
actual_size += 4 * method_parameters_length;
|
||||||
cfs->skip_u4_fast(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
|
// ignore this attribute if it cannot be reflected
|
||||||
if (!SystemDictionary::Parameter_klass_loaded())
|
if (!SystemDictionary::Parameter_klass_loaded())
|
||||||
method_parameters_length = 0;
|
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_length = method_attribute_length;
|
||||||
runtime_visible_annotations = cfs->get_u1_buffer();
|
runtime_visible_annotations = cfs->get_u1_buffer();
|
||||||
assert(runtime_visible_annotations != NULL, "null visible annotations");
|
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,
|
runtime_visible_annotations_length, cp, &parsed_annotations,
|
||||||
CHECK_(nullHandle));
|
CHECK_(nullHandle));
|
||||||
cfs->skip_u1(runtime_visible_annotations_length, 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 =
|
elem[i].name_cp_index =
|
||||||
Bytes::get_Java_u2(method_parameters_data);
|
Bytes::get_Java_u2(method_parameters_data);
|
||||||
method_parameters_data += 2;
|
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;
|
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_length = attribute_length;
|
||||||
runtime_visible_annotations = cfs->get_u1_buffer();
|
runtime_visible_annotations = cfs->get_u1_buffer();
|
||||||
assert(runtime_visible_annotations != NULL, "null visible annotations");
|
assert(runtime_visible_annotations != NULL, "null visible annotations");
|
||||||
parse_annotations(runtime_visible_annotations,
|
parse_annotations(loader_data,
|
||||||
|
runtime_visible_annotations,
|
||||||
runtime_visible_annotations_length,
|
runtime_visible_annotations_length,
|
||||||
cp,
|
cp,
|
||||||
parsed_annotations,
|
parsed_annotations,
|
||||||
|
@ -3405,18 +3434,21 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||||
// Size of Java itable (in words)
|
// Size of Java itable (in words)
|
||||||
itable_size = access_flags.is_interface() ? 0 : klassItable::compute_itable_size(transitive_interfaces);
|
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
|
// Field size and offset computation
|
||||||
int nonstatic_field_size = super_klass() == NULL ? 0 : super_klass->nonstatic_field_size();
|
int nonstatic_field_size = super_klass() == NULL ? 0 : super_klass->nonstatic_field_size();
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
int orig_nonstatic_field_size = 0;
|
int orig_nonstatic_field_size = 0;
|
||||||
#endif
|
#endif
|
||||||
int static_field_size = 0;
|
|
||||||
int next_static_oop_offset;
|
int next_static_oop_offset;
|
||||||
int next_static_double_offset;
|
int next_static_double_offset;
|
||||||
int next_static_word_offset;
|
int next_static_word_offset;
|
||||||
int next_static_short_offset;
|
int next_static_short_offset;
|
||||||
int next_static_byte_offset;
|
int next_static_byte_offset;
|
||||||
int next_static_type_offset;
|
int next_static_padded_offset;
|
||||||
int next_nonstatic_oop_offset;
|
int next_nonstatic_oop_offset;
|
||||||
int next_nonstatic_double_offset;
|
int next_nonstatic_double_offset;
|
||||||
int next_nonstatic_word_offset;
|
int next_nonstatic_word_offset;
|
||||||
|
@ -3426,11 +3458,36 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||||
int first_nonstatic_oop_offset;
|
int first_nonstatic_oop_offset;
|
||||||
int first_nonstatic_field_offset;
|
int first_nonstatic_field_offset;
|
||||||
int next_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
|
// Calculate the starting byte offsets
|
||||||
next_static_oop_offset = InstanceMirrorKlass::offset_of_static_fields();
|
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 +
|
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] &&
|
if ( fac.count[STATIC_DOUBLE] &&
|
||||||
(Universe::field_type_should_be_aligned(T_DOUBLE) ||
|
(Universe::field_type_should_be_aligned(T_DOUBLE) ||
|
||||||
Universe::field_type_should_be_aligned(T_LONG)) ) {
|
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 +
|
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 +
|
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 +
|
next_static_byte_offset = next_static_short_offset +
|
||||||
(fac.count[STATIC_SHORT] * BytesPerShort);
|
((fac.count[STATIC_SHORT] - fac_contended.count[STATIC_SHORT]) * BytesPerShort);
|
||||||
next_static_type_offset = align_size_up((next_static_byte_offset +
|
next_static_padded_offset = next_static_byte_offset +
|
||||||
fac.count[STATIC_BYTE] ), wordSize );
|
((fac.count[STATIC_BYTE] - fac_contended.count[STATIC_BYTE]) * 1);
|
||||||
static_field_size = (next_static_type_offset -
|
|
||||||
next_static_oop_offset) / wordSize;
|
|
||||||
|
|
||||||
first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() +
|
first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() +
|
||||||
nonstatic_field_size * heapOopSize;
|
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;
|
next_nonstatic_field_offset = first_nonstatic_field_offset;
|
||||||
|
|
||||||
unsigned int nonstatic_double_count = fac.count[NONSTATIC_DOUBLE];
|
unsigned int nonstatic_double_count = fac.count[NONSTATIC_DOUBLE] - fac_contended.count[NONSTATIC_DOUBLE];
|
||||||
unsigned int nonstatic_word_count = fac.count[NONSTATIC_WORD];
|
unsigned int nonstatic_word_count = fac.count[NONSTATIC_WORD] - fac_contended.count[NONSTATIC_WORD];
|
||||||
unsigned int nonstatic_short_count = fac.count[NONSTATIC_SHORT];
|
unsigned int nonstatic_short_count = fac.count[NONSTATIC_SHORT] - fac_contended.count[NONSTATIC_SHORT];
|
||||||
unsigned int nonstatic_byte_count = fac.count[NONSTATIC_BYTE];
|
unsigned int nonstatic_byte_count = fac.count[NONSTATIC_BYTE] - fac_contended.count[NONSTATIC_BYTE];
|
||||||
unsigned int nonstatic_oop_count = fac.count[NONSTATIC_OOP];
|
unsigned int nonstatic_oop_count = fac.count[NONSTATIC_OOP] - fac_contended.count[NONSTATIC_OOP];
|
||||||
|
|
||||||
bool super_has_nonstatic_fields =
|
bool super_has_nonstatic_fields =
|
||||||
(super_klass() != NULL && super_klass->has_nonstatic_fields());
|
(super_klass() != NULL && super_klass->has_nonstatic_fields());
|
||||||
|
@ -3529,12 +3590,12 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||||
}
|
}
|
||||||
|
|
||||||
if( allocation_style == 0 ) {
|
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_oop_offset = next_nonstatic_field_offset;
|
||||||
next_nonstatic_double_offset = next_nonstatic_oop_offset +
|
next_nonstatic_double_offset = next_nonstatic_oop_offset +
|
||||||
(nonstatic_oop_count * heapOopSize);
|
(nonstatic_oop_count * heapOopSize);
|
||||||
} else if( allocation_style == 1 ) {
|
} 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;
|
next_nonstatic_double_offset = next_nonstatic_field_offset;
|
||||||
} else if( allocation_style == 2 ) {
|
} else if( allocation_style == 2 ) {
|
||||||
// Fields allocation: oops fields in super and sub classes are together.
|
// Fields allocation: oops fields in super and sub classes are together.
|
||||||
|
@ -3613,27 +3674,33 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||||
(nonstatic_word_count * BytesPerInt);
|
(nonstatic_word_count * BytesPerInt);
|
||||||
next_nonstatic_byte_offset = next_nonstatic_short_offset +
|
next_nonstatic_byte_offset = next_nonstatic_short_offset +
|
||||||
(nonstatic_short_count * BytesPerShort);
|
(nonstatic_short_count * BytesPerShort);
|
||||||
|
next_nonstatic_padded_offset = next_nonstatic_byte_offset +
|
||||||
|
nonstatic_byte_count;
|
||||||
|
|
||||||
int notaligned_offset;
|
// let oops jump before padding with this allocation style
|
||||||
if( allocation_style == 0 ) {
|
if( allocation_style == 1 ) {
|
||||||
notaligned_offset = next_nonstatic_byte_offset + nonstatic_byte_count;
|
next_nonstatic_oop_offset = next_nonstatic_padded_offset;
|
||||||
} else { // allocation_style == 1
|
|
||||||
next_nonstatic_oop_offset = next_nonstatic_byte_offset + nonstatic_byte_count;
|
|
||||||
if( nonstatic_oop_count > 0 ) {
|
if( nonstatic_oop_count > 0 ) {
|
||||||
next_nonstatic_oop_offset = align_size_up(next_nonstatic_oop_offset, heapOopSize);
|
next_nonstatic_oop_offset = align_size_up(next_nonstatic_oop_offset, heapOopSize);
|
||||||
}
|
}
|
||||||
notaligned_offset = next_nonstatic_oop_offset + (nonstatic_oop_count * heapOopSize);
|
next_nonstatic_padded_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.
|
// Iterate over fields again and compute correct offsets.
|
||||||
// The field allocation type was temporarily stored in the offset slot.
|
// The field allocation type was temporarily stored in the offset slot.
|
||||||
// oop fields are located before non-oop fields (static and non-static).
|
// oop fields are located before non-oop fields (static and non-static).
|
||||||
for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) {
|
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;
|
int real_offset;
|
||||||
FieldAllocationType atype = (FieldAllocationType) fs.offset();
|
FieldAllocationType atype = (FieldAllocationType) fs.allocation_type();
|
||||||
|
|
||||||
|
// pack the rest of the fields
|
||||||
switch (atype) {
|
switch (atype) {
|
||||||
case STATIC_OOP:
|
case STATIC_OOP:
|
||||||
real_offset = next_static_oop_offset;
|
real_offset = next_static_oop_offset;
|
||||||
|
@ -3722,13 +3789,225 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||||
fs.set_offset(real_offset);
|
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
|
// Size of instances
|
||||||
int instance_size;
|
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 );
|
next_nonstatic_type_offset = align_size_up(notaligned_offset, wordSize );
|
||||||
instance_size = align_object_size(next_nonstatic_type_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.
|
// Number of non-static oop map blocks allocated at end of klass.
|
||||||
const unsigned int total_oop_map_count =
|
const unsigned int total_oop_map_count =
|
||||||
|
@ -3912,8 +4191,11 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||||
|
|
||||||
// check that if this class is an interface then it doesn't have static methods
|
// check that if this class is an interface then it doesn't have static methods
|
||||||
if (this_klass->is_interface()) {
|
if (this_klass->is_interface()) {
|
||||||
|
/* An interface in a JAVA 8 classfile can be static */
|
||||||
|
if (_major_version < JAVA_8_VERSION) {
|
||||||
check_illegal_static_method(this_klass, CHECK_(nullHandle));
|
check_illegal_static_method(this_klass, CHECK_(nullHandle));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
|
@ -4005,6 +4287,18 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||||
}
|
}
|
||||||
#endif
|
#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 result across HandleMark
|
||||||
preserve_this_klass = this_klass();
|
preserve_this_klass = this_klass();
|
||||||
}
|
}
|
||||||
|
@ -4017,6 +4311,38 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
|
||||||
return this_klass;
|
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
|
unsigned int
|
||||||
ClassFileParser::compute_oop_map_count(instanceKlassHandle super,
|
ClassFileParser::compute_oop_map_count(instanceKlassHandle super,
|
||||||
unsigned int nonstatic_oop_map_count,
|
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_bridge = (flags & JVM_ACC_BRIDGE) != 0;
|
||||||
const bool is_strict = (flags & JVM_ACC_STRICT) != 0;
|
const bool is_strict = (flags & JVM_ACC_STRICT) != 0;
|
||||||
const bool is_synchronized = (flags & JVM_ACC_SYNCHRONIZED) != 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_15 = _major_version >= JAVA_1_5_VERSION;
|
||||||
const bool major_gte_8 = _major_version >= JAVA_8_VERSION;
|
const bool major_gte_8 = _major_version >= JAVA_8_VERSION;
|
||||||
const bool is_initializer = (name == vmSymbols::object_initializer_name());
|
const bool is_initializer = (name == vmSymbols::object_initializer_name());
|
||||||
|
@ -4473,12 +4800,34 @@ void ClassFileParser::verify_legal_method_modifiers(
|
||||||
bool is_illegal = false;
|
bool is_illegal = false;
|
||||||
|
|
||||||
if (is_interface) {
|
if (is_interface) {
|
||||||
if (!is_public || is_static || is_final || is_native ||
|
if (major_gte_8) {
|
||||||
((is_synchronized || is_strict) && major_gte_15 &&
|
// Class file version is JAVA_8_VERSION or later Methods of
|
||||||
(!major_gte_8 || is_abstract)) ||
|
// interfaces may set any of the flags except ACC_PROTECTED,
|
||||||
(!major_gte_8 && !is_abstract)) {
|
// 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;
|
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
|
} else { // not interface
|
||||||
if (is_initializer) {
|
if (is_initializer) {
|
||||||
if (is_static || is_final || is_synchronized || is_native ||
|
if (is_static || is_final || is_synchronized || is_native ||
|
||||||
|
|
|
@ -95,17 +95,20 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
||||||
_method_DontInline,
|
_method_DontInline,
|
||||||
_method_LambdaForm_Compiled,
|
_method_LambdaForm_Compiled,
|
||||||
_method_LambdaForm_Hidden,
|
_method_LambdaForm_Hidden,
|
||||||
|
_sun_misc_Contended,
|
||||||
_annotation_LIMIT
|
_annotation_LIMIT
|
||||||
};
|
};
|
||||||
const Location _location;
|
const Location _location;
|
||||||
int _annotations_present;
|
int _annotations_present;
|
||||||
|
u2 _contended_group;
|
||||||
|
|
||||||
AnnotationCollector(Location location)
|
AnnotationCollector(Location location)
|
||||||
: _location(location), _annotations_present(0)
|
: _location(location), _annotations_present(0)
|
||||||
{
|
{
|
||||||
assert((int)_annotation_LIMIT <= (int)sizeof(_annotations_present) * BitsPerByte, "");
|
assert((int)_annotation_LIMIT <= (int)sizeof(_annotations_present) * BitsPerByte, "");
|
||||||
}
|
}
|
||||||
// If this annotation name has an ID, report it (or _none).
|
// 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:
|
// Set the annotation name:
|
||||||
void set_annotation(ID id) {
|
void set_annotation(ID id) {
|
||||||
assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob");
|
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.
|
// Report if the annotation is present.
|
||||||
bool has_any_annotations() { return _annotations_present != 0; }
|
bool has_any_annotations() { return _annotations_present != 0; }
|
||||||
bool has_annotation(ID id) { return (nth_bit((int)id) & _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 {
|
class FieldAnnotationCollector: public AnnotationCollector {
|
||||||
public:
|
public:
|
||||||
|
@ -177,6 +186,14 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
||||||
Array<AnnotationArray*>** fields_type_annotations,
|
Array<AnnotationArray*>** fields_type_annotations,
|
||||||
u2* java_fields_count_ptr, TRAPS);
|
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
|
// Method parsing
|
||||||
methodHandle parse_method(ClassLoaderData* loader_data,
|
methodHandle parse_method(ClassLoaderData* loader_data,
|
||||||
constantPoolHandle cp,
|
constantPoolHandle cp,
|
||||||
|
@ -247,7 +264,8 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
||||||
int runtime_invisible_annotations_length, TRAPS);
|
int runtime_invisible_annotations_length, TRAPS);
|
||||||
int skip_annotation(u1* buffer, int limit, int index);
|
int skip_annotation(u1* buffer, int limit, int index);
|
||||||
int skip_annotation_value(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): */
|
/* Results (currently, only one result is supported): */
|
||||||
AnnotationCollector* result,
|
AnnotationCollector* result,
|
||||||
TRAPS);
|
TRAPS);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -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
|
// placeholder existence now for loading superclass/superinterface
|
||||||
// superthreadQ tracks class circularity, while loading superclass/superinterface
|
// superthreadQ tracks class circularity, while loading superclass/superinterface
|
||||||
// loadInstanceThreadQ tracks load_instance_class calls
|
// 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
|
// All claimants remove SeenThread after completing action
|
||||||
// On removal: if definer and all queues empty, remove entry
|
// On removal: if definer and all queues empty, remove entry
|
||||||
// Note: you can be in both placeholders and systemDictionary
|
// Note: you can be in both placeholders and systemDictionary
|
||||||
// see parse_stream for redefine classes
|
|
||||||
// Therefore - must always check SD first
|
// Therefore - must always check SD first
|
||||||
// Ignores the case where entry is not found
|
// Ignores the case where entry is not found
|
||||||
void PlaceholderTable::find_and_remove(int index, unsigned int hash,
|
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);
|
assert_locked_or_safepoint(SystemDictionary_lock);
|
||||||
PlaceholderEntry *probe = get_entry(index, hash, name, loader_data);
|
PlaceholderEntry *probe = get_entry(index, hash, name, loader_data);
|
||||||
if (probe != NULL) {
|
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)
|
if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL)
|
||||||
&& (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)) {
|
&& (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)) {
|
||||||
remove_entry(index, hash, name, loader_data);
|
remove_entry(index, hash, name, loader_data);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -82,7 +82,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// find_and_add returns probe pointer - old or new
|
// 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
|
// If entry exists, reuse entry and push SeenThread for classloadAction
|
||||||
PlaceholderEntry* find_and_add(int index, unsigned int hash,
|
PlaceholderEntry* find_and_add(int index, unsigned int hash,
|
||||||
Symbol* name, ClassLoaderData* loader_data,
|
Symbol* name, ClassLoaderData* loader_data,
|
||||||
|
@ -92,9 +92,11 @@ public:
|
||||||
void remove_entry(int index, unsigned int hash,
|
void remove_entry(int index, unsigned int hash,
|
||||||
Symbol* name, ClassLoaderData* loader_data);
|
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,
|
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.
|
// GC support.
|
||||||
void classes_do(KlassClosure* f);
|
void classes_do(KlassClosure* f);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -172,7 +172,7 @@ Klass* SystemDictionary::handle_resolution_exception(Symbol* class_name, Handle
|
||||||
assert(klass_h() == NULL, "Should not have result with exception pending");
|
assert(klass_h() == NULL, "Should not have result with exception pending");
|
||||||
Handle e(THREAD, PENDING_EXCEPTION);
|
Handle e(THREAD, PENDING_EXCEPTION);
|
||||||
CLEAR_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 {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -181,9 +181,9 @@ Klass* SystemDictionary::handle_resolution_exception(Symbol* class_name, Handle
|
||||||
if (klass_h() == NULL) {
|
if (klass_h() == NULL) {
|
||||||
ResourceMark rm(THREAD);
|
ResourceMark rm(THREAD);
|
||||||
if (throw_error) {
|
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 {
|
} 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();
|
return (Klass*)klass_h();
|
||||||
|
@ -343,29 +343,29 @@ Klass* SystemDictionary::resolve_super_or_fail(Symbol* child_name,
|
||||||
}
|
}
|
||||||
if (throw_circularity_error) {
|
if (throw_circularity_error) {
|
||||||
ResourceMark rm(THREAD);
|
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
|
// java.lang.Object should have been found above
|
||||||
assert(class_name != NULL, "null super class for resolving");
|
assert(class_name != NULL, "null super class for resolving");
|
||||||
// Resolve the super class or interface, check results on return
|
// Resolve the super class or interface, check results on return
|
||||||
Klass* superk = NULL;
|
Klass* superk = SystemDictionary::resolve_or_null(class_name,
|
||||||
superk = SystemDictionary::resolve_or_null(class_name,
|
|
||||||
class_loader,
|
class_loader,
|
||||||
protection_domain,
|
protection_domain,
|
||||||
THREAD);
|
THREAD);
|
||||||
|
|
||||||
KlassHandle superk_h(THREAD, superk);
|
KlassHandle superk_h(THREAD, superk);
|
||||||
|
|
||||||
// Note: clean up of placeholders currently in callers of
|
// Clean up of placeholders moved so that each classloadAction registrar self-cleans up
|
||||||
// resolve_super_or_fail - either at update_dictionary time
|
// It is no longer necessary to keep the placeholder table alive until update_dictionary
|
||||||
// or on error
|
// 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);
|
MutexLocker mu(SystemDictionary_lock, THREAD);
|
||||||
PlaceholderEntry* probe = placeholders()->get_entry(p_index, p_hash, child_name, loader_data);
|
placeholders()->find_and_remove(p_index, p_hash, child_name, loader_data, PlaceholderTable::LOAD_SUPER, THREAD);
|
||||||
if (probe != NULL) {
|
SystemDictionary_lock->notify_all();
|
||||||
probe->remove_seen_thread(THREAD, PlaceholderTable::LOAD_SUPER);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (HAS_PENDING_EXCEPTION || superk_h() == NULL) {
|
if (HAS_PENDING_EXCEPTION || superk_h() == NULL) {
|
||||||
// can null superk
|
// 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
|
// We're using a No_Safepoint_Verifier to catch any place where we
|
||||||
// might potentially do a GC at all.
|
// might potentially do a GC at all.
|
||||||
// SystemDictionary::do_unloading() asserts that classes are only
|
// Dictionary::do_unloading() asserts that classes in SD are only
|
||||||
// unloaded at a safepoint.
|
// unloaded at a safepoint. Anonymous classes are not in SD.
|
||||||
No_Safepoint_Verifier nosafepoint;
|
No_Safepoint_Verifier nosafepoint;
|
||||||
dictionary()->add_protection_domain(d_index, d_hash, klass, loader_data,
|
dictionary()->add_protection_domain(d_index, d_hash, klass, loader_data,
|
||||||
protection_domain, THREAD);
|
protection_domain, THREAD);
|
||||||
|
@ -486,7 +486,6 @@ void SystemDictionary::double_lock_wait(Handle lockObject, TRAPS) {
|
||||||
// super class loading here.
|
// super class loading here.
|
||||||
// This also is critical in cases where the original thread gets stalled
|
// This also is critical in cases where the original thread gets stalled
|
||||||
// even in non-circularity situations.
|
// 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 -
|
// Note: must call resolve_super_or_fail even if null super -
|
||||||
// to force placeholder entry creation for this class for circularity detection
|
// to force placeholder entry creation for this class for circularity detection
|
||||||
// Caller must check for pending exception
|
// Caller must check for pending exception
|
||||||
|
@ -518,14 +517,6 @@ instanceKlassHandle SystemDictionary::handle_parallel_super_load(
|
||||||
protection_domain,
|
protection_domain,
|
||||||
true,
|
true,
|
||||||
CHECK_(nh));
|
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
|
// parallelCapable class loaders do NOT wait for parallel superclass loads to complete
|
||||||
// Serial class loaders and bootstrap classloader do wait for superclass loads
|
// 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
|
// Do lookup to see if class already exist and the protection domain
|
||||||
// has the right access
|
// 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);
|
unsigned int d_hash = dictionary()->compute_hash(name, loader_data);
|
||||||
int d_index = dictionary()->hash_to_index(d_hash);
|
int d_index = dictionary()->hash_to_index(d_hash);
|
||||||
Klass* probe = dictionary()->find(d_index, d_hash, name, loader_data,
|
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 in is 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) {
|
if (super_load_in_progress && havesupername==true) {
|
||||||
k = SystemDictionary::handle_parallel_super_load(name, superclassname,
|
k = SystemDictionary::handle_parallel_super_load(name, superclassname,
|
||||||
class_loader, protection_domain, lockObject, THREAD);
|
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) {
|
if (!class_has_been_loaded) {
|
||||||
|
bool load_instance_added = false;
|
||||||
|
|
||||||
// add placeholder entry to record loading instance class
|
// add placeholder entry to record loading instance class
|
||||||
// Five cases:
|
// Five cases:
|
||||||
|
@ -690,7 +687,7 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
|
||||||
// No performance benefit and no deadlock issues.
|
// No performance benefit and no deadlock issues.
|
||||||
// case 5. parallelCapable user level classloaders - without objectLocker
|
// case 5. parallelCapable user level classloaders - without objectLocker
|
||||||
// Allow parallel classloading of a class/classloader pair
|
// Allow parallel classloading of a class/classloader pair
|
||||||
bool throw_circularity_error = false;
|
|
||||||
{
|
{
|
||||||
MutexLocker mu(SystemDictionary_lock, THREAD);
|
MutexLocker mu(SystemDictionary_lock, THREAD);
|
||||||
if (class_loader.is_null() || !is_parallelCapable(class_loader)) {
|
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
|
// case 3: UnsyncloadClass || case 5: parallelCapable: allow competing threads to try
|
||||||
// LOAD_INSTANCE in parallel
|
// LOAD_INSTANCE in parallel
|
||||||
// add placeholder entry even if error - callers will remove on error
|
|
||||||
if (!throw_circularity_error && !class_has_been_loaded) {
|
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);
|
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,
|
// For class loaders that do not acquire the classloader object lock,
|
||||||
// if they did not catch another thread holding LOAD_INSTANCE,
|
// if they did not catch another thread holding LOAD_INSTANCE,
|
||||||
// need a check analogous to the acquire ObjectLocker/find_class
|
// 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
|
// class loaders holding the ObjectLock shouldn't find the class here
|
||||||
Klass* check = find_class(d_index, d_hash, name, loader_data);
|
Klass* check = find_class(d_index, d_hash, name, loader_data);
|
||||||
if (check != NULL) {
|
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);
|
k = instanceKlassHandle(THREAD, check);
|
||||||
class_has_been_loaded = true;
|
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
|
// must throw error outside of owning lock
|
||||||
if (throw_circularity_error) {
|
if (throw_circularity_error) {
|
||||||
|
assert(!HAS_PENDING_EXCEPTION && load_instance_added == false,"circularity error cleanup");
|
||||||
ResourceMark rm(THREAD);
|
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) {
|
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
|
// If everything was OK (no exceptions, no null return value), and
|
||||||
// class_loader is NOT the defining loader, do a little more bookkeeping.
|
// class_loader is NOT the defining loader, do a little more bookkeeping.
|
||||||
if (!HAS_PENDING_EXCEPTION && !k.is_null() &&
|
if (!HAS_PENDING_EXCEPTION && !k.is_null() &&
|
||||||
|
@ -819,17 +802,21 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (HAS_PENDING_EXCEPTION || k.is_null()) {
|
} // load_instance_class loop
|
||||||
// On error, clean up placeholders
|
|
||||||
{
|
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);
|
MutexLocker mu(SystemDictionary_lock, THREAD);
|
||||||
placeholders()->find_and_remove(p_index, p_hash, name, loader_data, THREAD);
|
placeholders()->find_and_remove(p_index, p_hash, name, loader_data, PlaceholderTable::LOAD_INSTANCE, THREAD);
|
||||||
SystemDictionary_lock->notify_all();
|
SystemDictionary_lock->notify_all();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HAS_PENDING_EXCEPTION || k.is_null()) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
{
|
{
|
||||||
|
@ -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.
|
// 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
|
// We're using a No_Safepoint_Verifier to catch any place where we
|
||||||
// might potentially do a GC at all.
|
// might potentially do a GC at all.
|
||||||
// SystemDictionary::do_unloading() asserts that classes are only
|
// Dictionary::do_unloading() asserts that classes in SD are only
|
||||||
// unloaded at a safepoint.
|
// unloaded at a safepoint. Anonymous classes are not in SD.
|
||||||
No_Safepoint_Verifier nosafepoint;
|
No_Safepoint_Verifier nosafepoint;
|
||||||
if (dictionary()->is_valid_protection_domain(d_index, d_hash, name,
|
if (dictionary()->is_valid_protection_domain(d_index, d_hash, name,
|
||||||
loader_data,
|
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.
|
// 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
|
// We're using a No_Safepoint_Verifier to catch any place where we
|
||||||
// might potentially do a GC at all.
|
// might potentially do a GC at all.
|
||||||
// SystemDictionary::do_unloading() asserts that classes are only
|
// Dictionary::do_unloading() asserts that classes in SD are only
|
||||||
// unloaded at a safepoint.
|
// unloaded at a safepoint. Anonymous classes are not in SD.
|
||||||
No_Safepoint_Verifier nosafepoint;
|
No_Safepoint_Verifier nosafepoint;
|
||||||
return dictionary()->find(d_index, d_hash, class_name, loader_data,
|
return dictionary()->find(d_index, d_hash, class_name, loader_data,
|
||||||
protection_domain, THREAD);
|
protection_domain, THREAD);
|
||||||
|
@ -965,10 +952,6 @@ Klass* SystemDictionary::parse_stream(Symbol* class_name,
|
||||||
// throw potential ClassFormatErrors.
|
// throw potential ClassFormatErrors.
|
||||||
//
|
//
|
||||||
// Note: "name" is updated.
|
// 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,
|
instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
|
||||||
loader_data,
|
loader_data,
|
||||||
|
@ -979,21 +962,6 @@ Klass* SystemDictionary::parse_stream(Symbol* class_name,
|
||||||
true,
|
true,
|
||||||
THREAD);
|
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()) {
|
if (host_klass.not_null() && k.not_null()) {
|
||||||
assert(EnableInvokeDynamic, "");
|
assert(EnableInvokeDynamic, "");
|
||||||
|
@ -1062,10 +1030,6 @@ Klass* SystemDictionary::resolve_from_stream(Symbol* class_name,
|
||||||
// throw potential ClassFormatErrors.
|
// throw potential ClassFormatErrors.
|
||||||
//
|
//
|
||||||
// Note: "name" is updated.
|
// 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,
|
instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
|
||||||
loader_data,
|
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
|
// Make sure we have an entry in the SystemDictionary on success
|
||||||
// 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
|
|
||||||
debug_only( {
|
debug_only( {
|
||||||
if (!HAS_PENDING_EXCEPTION) {
|
if (!HAS_PENDING_EXCEPTION) {
|
||||||
assert(parsed_name != NULL, "parsed_name is still null?");
|
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
|
// Other cases fall through, and may run into duplicate defines
|
||||||
// caught by finding an entry in the SystemDictionary
|
// caught by finding an entry in the SystemDictionary
|
||||||
if ((UnsyncloadClass || is_parallelDefine(class_loader)) && (probe->instance_klass() != NULL)) {
|
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, PlaceholderTable::DEFINE_CLASS, THREAD);
|
||||||
placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, THREAD);
|
|
||||||
SystemDictionary_lock->notify_all();
|
SystemDictionary_lock->notify_all();
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
Klass* check = find_class(d_index, d_hash, name_h, loader_data);
|
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_instance_klass(k());
|
||||||
}
|
}
|
||||||
probe->set_definer(NULL);
|
probe->set_definer(NULL);
|
||||||
probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS);
|
placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, THREAD);
|
||||||
placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, THREAD);
|
|
||||||
SystemDictionary_lock->notify_all();
|
SystemDictionary_lock->notify_all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1736,6 +1680,8 @@ int SystemDictionary::calculate_systemdictionary_size(int classcount) {
|
||||||
}
|
}
|
||||||
return newsize;
|
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) {
|
bool SystemDictionary::do_unloading(BoolObjectClosure* is_alive) {
|
||||||
// First, mark for unload all ClassLoaderData referencing a dead class loader.
|
// First, mark for unload all ClassLoaderData referencing a dead class loader.
|
||||||
bool has_dead_loaders = ClassLoaderDataGraph::do_unloading(is_alive);
|
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.
|
// All loaded classes get a unique ID.
|
||||||
TRACE_INIT_ID(k);
|
TRACE_INIT_ID(k);
|
||||||
|
|
||||||
// Check for a placeholder. If there, remove it and make a
|
// Make a new system dictionary entry.
|
||||||
// new system dictionary entry.
|
|
||||||
placeholders()->find_and_remove(p_index, p_hash, name, loader_data, THREAD);
|
|
||||||
Klass* sd_check = find_class(d_index, d_hash, name, loader_data);
|
Klass* sd_check = find_class(d_index, d_hash, name, loader_data);
|
||||||
if (sd_check == NULL) {
|
if (sd_check == NULL) {
|
||||||
dictionary()->add_klass(name, loader_data, k);
|
dictionary()->add_klass(name, loader_data, k);
|
||||||
|
@ -2116,12 +2060,8 @@ void SystemDictionary::update_dictionary(int d_index, unsigned int d_hash,
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
sd_check = find_class(d_index, d_hash, name, loader_data);
|
sd_check = find_class(d_index, d_hash, name, loader_data);
|
||||||
assert (sd_check != NULL, "should have entry in system dictionary");
|
assert (sd_check != NULL, "should have entry in system dictionary");
|
||||||
// Changed to allow PH to remain to complete class circularity checking
|
// Note: there may be a placeholder entry: for circularity testing
|
||||||
// while only one thread can define a class at one time, multiple
|
// or for parallel defines
|
||||||
// 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");
|
|
||||||
#endif
|
#endif
|
||||||
SystemDictionary_lock->notify_all();
|
SystemDictionary_lock->notify_all();
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,7 +194,10 @@
|
||||||
template(java_lang_VirtualMachineError, "java/lang/VirtualMachineError") \
|
template(java_lang_VirtualMachineError, "java/lang/VirtualMachineError") \
|
||||||
template(java_lang_StackOverflowError, "java/lang/StackOverflowError") \
|
template(java_lang_StackOverflowError, "java/lang/StackOverflowError") \
|
||||||
template(java_lang_StackTraceElement, "java/lang/StackTraceElement") \
|
template(java_lang_StackTraceElement, "java/lang/StackTraceElement") \
|
||||||
|
\
|
||||||
|
/* Concurrency support */ \
|
||||||
template(java_util_concurrent_locks_AbstractOwnableSynchronizer, "java/util/concurrent/locks/AbstractOwnableSynchronizer") \
|
template(java_util_concurrent_locks_AbstractOwnableSynchronizer, "java/util/concurrent/locks/AbstractOwnableSynchronizer") \
|
||||||
|
template(sun_misc_Contended_signature, "Lsun/misc/Contended;") \
|
||||||
\
|
\
|
||||||
/* class symbols needed by intrinsics */ \
|
/* class symbols needed by intrinsics */ \
|
||||||
VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, template, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE) \
|
VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, template, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE) \
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* 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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -373,17 +373,44 @@ void VM_PopulateDumpSharedSpace::doit() {
|
||||||
md_top = wc.get_top();
|
md_top = wc.get_top();
|
||||||
|
|
||||||
// Print shared spaces all the time
|
// 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* ro_space = _loader_data->ro_metaspace();
|
||||||
Metaspace* rw_space = _loader_data->rw_metaspace();
|
Metaspace* rw_space = _loader_data->rw_metaspace();
|
||||||
tty->print_cr(fmt, "ro", ro_space->used_words(Metaspace::NonClassType),
|
const size_t BPW = BytesPerWord;
|
||||||
ro_space->capacity_words(Metaspace::NonClassType),
|
|
||||||
ro_space->bottom());
|
// Allocated size of each space (may not be all occupied)
|
||||||
tty->print_cr(fmt, "rw", rw_space->used_words(Metaspace::NonClassType),
|
const size_t ro_alloced = ro_space->capacity_words(Metaspace::NonClassType) * BPW;
|
||||||
rw_space->capacity_words(Metaspace::NonClassType),
|
const size_t rw_alloced = rw_space->capacity_words(Metaspace::NonClassType) * BPW;
|
||||||
rw_space->bottom());
|
const size_t md_alloced = md_end-md_low;
|
||||||
tty->print_cr(fmt, "md", md_top - md_low, md_end-md_low, md_low);
|
const size_t mc_alloced = mc_end-mc_low;
|
||||||
tty->print_cr(fmt, "mc", mc_top - mc_low, mc_end-mc_low, 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
|
// Update the vtable pointers in all of the Klass objects in the
|
||||||
// heap. They should point to newly generated vtable.
|
// heap. They should point to newly generated vtable.
|
||||||
|
|
|
@ -122,7 +122,12 @@ class ExceptionTableElement VALUE_OBJ_CLASS_SPEC {
|
||||||
class MethodParametersElement VALUE_OBJ_CLASS_SPEC {
|
class MethodParametersElement VALUE_OBJ_CLASS_SPEC {
|
||||||
public:
|
public:
|
||||||
u2 name_cp_index;
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,14 +43,29 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC {
|
||||||
public:
|
public:
|
||||||
// fields
|
// fields
|
||||||
// Field info extracted from the class file and stored
|
// 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 {
|
enum FieldOffset {
|
||||||
access_flags_offset = 0,
|
access_flags_offset = 0,
|
||||||
name_index_offset = 1,
|
name_index_offset = 1,
|
||||||
signature_index_offset = 2,
|
signature_index_offset = 2,
|
||||||
initval_index_offset = 3,
|
initval_index_offset = 3,
|
||||||
low_offset = 4,
|
low_packed_offset = 4,
|
||||||
high_offset = 5,
|
high_packed_offset = 5,
|
||||||
field_slots = 6
|
field_slots = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,17 +91,90 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC {
|
||||||
void initialize(u2 access_flags,
|
void initialize(u2 access_flags,
|
||||||
u2 name_index,
|
u2 name_index,
|
||||||
u2 signature_index,
|
u2 signature_index,
|
||||||
u2 initval_index,
|
u2 initval_index) {
|
||||||
u4 offset) {
|
|
||||||
_shorts[access_flags_offset] = access_flags;
|
_shorts[access_flags_offset] = access_flags;
|
||||||
_shorts[name_index_offset] = name_index;
|
_shorts[name_index_offset] = name_index;
|
||||||
_shorts[signature_index_offset] = signature_index;
|
_shorts[signature_index_offset] = signature_index;
|
||||||
_shorts[initval_index_offset] = initval_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]; }
|
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 {
|
Symbol* name(constantPoolHandle cp) const {
|
||||||
int index = name_index();
|
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_access_flags(u2 val) { _shorts[access_flags_offset] = val; }
|
||||||
void set_offset(u4 val) {
|
void set_offset(u4 val) {
|
||||||
_shorts[low_offset] = extract_low_short_from_int(val);
|
val = val << FIELDINFO_TAG_SIZE; // make room for tag
|
||||||
_shorts[high_offset] = extract_high_short_from_int(val);
|
_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 {
|
bool is_internal() const {
|
||||||
|
|
|
@ -160,9 +160,26 @@ class FieldStreamBase : public StackObj {
|
||||||
return field()->offset();
|
return field()->offset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int allocation_type() const {
|
||||||
|
return field()->allocation_type();
|
||||||
|
}
|
||||||
|
|
||||||
void set_offset(int offset) {
|
void set_offset(int offset) {
|
||||||
field()->set_offset(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
|
// Iterate over only the internal fields
|
||||||
|
|
|
@ -234,7 +234,8 @@ class InstanceKlass: public Klass {
|
||||||
_misc_has_nonstatic_fields = 1 << 1, // for sizing with UseCompressedOops
|
_misc_has_nonstatic_fields = 1 << 1, // for sizing with UseCompressedOops
|
||||||
_misc_should_verify_class = 1 << 2, // allow caching of preverification
|
_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_has_default_methods = 1 << 4 // class/superclass/implemented interfaces has default methods
|
_misc_is_contended = 1 << 4, // marked with contended annotation
|
||||||
|
_misc_has_default_methods = 1 << 5 // class/superclass/implemented interfaces has default methods
|
||||||
};
|
};
|
||||||
u2 _misc_flags;
|
u2 _misc_flags;
|
||||||
u2 _minor_version; // minor version number of class file
|
u2 _minor_version; // minor version number of class file
|
||||||
|
@ -552,6 +553,17 @@ class InstanceKlass: public Klass {
|
||||||
return is_anonymous() ? java_mirror() : class_loader();
|
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
|
// signers
|
||||||
objArrayOop signers() const { return _signers; }
|
objArrayOop signers() const { return _signers; }
|
||||||
void set_signers(objArrayOop s) { klass_oop_store((oop*)&_signers, s); }
|
void set_signers(objArrayOop s) { klass_oop_store((oop*)&_signers, s); }
|
||||||
|
|
|
@ -1589,6 +1589,12 @@ JVM_ENTRY(jbyteArray, JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls))
|
||||||
return NULL;
|
return NULL;
|
||||||
JVM_END
|
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))
|
JVM_ENTRY(jobjectArray, JVM_GetMethodParameters(JNIEnv *env, jobject method))
|
||||||
{
|
{
|
||||||
JVMWrapper("JVM_GetMethodParameters");
|
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));
|
Handle reflected_method (THREAD, JNIHandles::resolve_non_null(method));
|
||||||
const int num_params = mh->method_parameters_length();
|
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);
|
objArrayOop result_oop = oopFactory::new_objArray(SystemDictionary::reflect_Parameter_klass(), num_params, CHECK_NULL);
|
||||||
objArrayHandle result (THREAD, result_oop);
|
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();
|
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,
|
oop param = Reflection::new_parameter(reflected_method, i, sym,
|
||||||
params[i].flags, CHECK_NULL);
|
flags, CHECK_NULL);
|
||||||
result->obj_at_put(i, param);
|
result->obj_at_put(i, param);
|
||||||
}
|
}
|
||||||
return (jobjectArray)JNIHandles::make_local(env, result());
|
return (jobjectArray)JNIHandles::make_local(env, result());
|
||||||
|
@ -1830,13 +1852,6 @@ JVM_ENTRY(jint, JVM_ConstantPoolGetSize(JNIEnv *env, jobject obj, jobject unused
|
||||||
JVM_END
|
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))
|
JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject obj, jobject unused, jint index))
|
||||||
{
|
{
|
||||||
JVMWrapper("JVM_ConstantPoolGetClassAt");
|
JVMWrapper("JVM_ConstantPoolGetClassAt");
|
||||||
|
@ -1851,7 +1866,6 @@ JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject obj, jobject u
|
||||||
}
|
}
|
||||||
JVM_END
|
JVM_END
|
||||||
|
|
||||||
|
|
||||||
JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAtIfLoaded(JNIEnv *env, jobject obj, jobject unused, jint index))
|
JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAtIfLoaded(JNIEnv *env, jobject obj, jobject unused, jint index))
|
||||||
{
|
{
|
||||||
JVMWrapper("JVM_ConstantPoolGetClassAtIfLoaded");
|
JVMWrapper("JVM_ConstantPoolGetClassAtIfLoaded");
|
||||||
|
|
|
@ -1078,7 +1078,7 @@ class CommandLineFlags {
|
||||||
\
|
\
|
||||||
product(intx, ClearFPUAtPark, 0, "(Unsafe,Unstable)" ) \
|
product(intx, ClearFPUAtPark, 0, "(Unsafe,Unstable)" ) \
|
||||||
\
|
\
|
||||||
product(intx, hashCode, 0, \
|
product(intx, hashCode, 5, \
|
||||||
"(Unstable) select hashCode generation algorithm" ) \
|
"(Unstable) select hashCode generation algorithm" ) \
|
||||||
\
|
\
|
||||||
product(intx, WorkAroundNPTLTimedWaitHang, 1, \
|
product(intx, WorkAroundNPTLTimedWaitHang, 1, \
|
||||||
|
@ -1169,6 +1169,18 @@ class CommandLineFlags {
|
||||||
notproduct(bool, PrintCompactFieldsSavings, false, \
|
notproduct(bool, PrintCompactFieldsSavings, false, \
|
||||||
"Print how many words were saved with CompactFields") \
|
"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, \
|
product(bool, UseBiasedLocking, true, \
|
||||||
"Enable biased locking in JVM") \
|
"Enable biased locking in JVM") \
|
||||||
\
|
\
|
||||||
|
|
|
@ -548,6 +548,10 @@ void before_exit(JavaThread * thread) {
|
||||||
BeforeExit_lock->notify_all();
|
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_NOT_RUN
|
||||||
#undef BEFORE_EXIT_RUNNING
|
#undef BEFORE_EXIT_RUNNING
|
||||||
#undef BEFORE_EXIT_DONE
|
#undef BEFORE_EXIT_DONE
|
||||||
|
|
|
@ -862,7 +862,15 @@ oop Reflection::new_field(fieldDescriptor* fd, bool intern_name, TRAPS) {
|
||||||
|
|
||||||
oop Reflection::new_parameter(Handle method, int index, Symbol* sym,
|
oop Reflection::new_parameter(Handle method, int index, Symbol* sym,
|
||||||
int flags, TRAPS) {
|
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);
|
Handle rh = java_lang_reflect_Parameter::create(CHECK_NULL);
|
||||||
java_lang_reflect_Parameter::set_name(rh(), name());
|
java_lang_reflect_Parameter::set_name(rh(), name());
|
||||||
java_lang_reflect_Parameter::set_modifiers(rh(), flags);
|
java_lang_reflect_Parameter::set_modifiers(rh(), flags);
|
||||||
|
|
|
@ -4011,10 +4011,6 @@ bool Threads::destroy_vm() {
|
||||||
Mutex::_as_suspend_equivalent_flag);
|
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.
|
// Hang forever on exit if we are reporting an error.
|
||||||
if (ShowMessageBoxOnError && is_error_reported()) {
|
if (ShowMessageBoxOnError && is_error_reported()) {
|
||||||
os::infinite_sleep();
|
os::infinite_sleep();
|
||||||
|
|
|
@ -257,8 +257,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
|
||||||
c1_nonstatic_field, \
|
c1_nonstatic_field, \
|
||||||
c2_nonstatic_field, \
|
c2_nonstatic_field, \
|
||||||
unchecked_c1_static_field, \
|
unchecked_c1_static_field, \
|
||||||
unchecked_c2_static_field, \
|
unchecked_c2_static_field) \
|
||||||
last_entry) \
|
|
||||||
\
|
\
|
||||||
/******************************************************************/ \
|
/******************************************************************/ \
|
||||||
/* OopDesc and Klass hierarchies (NOTE: MethodData* incomplete) */ \
|
/* OopDesc and Klass hierarchies (NOTE: MethodData* incomplete) */ \
|
||||||
|
@ -718,7 +717,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
|
||||||
nonstatic_field(ClassLoaderData, _next, ClassLoaderData*) \
|
nonstatic_field(ClassLoaderData, _next, ClassLoaderData*) \
|
||||||
\
|
\
|
||||||
static_field(ClassLoaderDataGraph, _head, ClassLoaderData*) \
|
static_field(ClassLoaderDataGraph, _head, ClassLoaderData*) \
|
||||||
nonstatic_field(ClassLoaderDataGraph, _unloading, ClassLoaderData*) \
|
|
||||||
\
|
\
|
||||||
/*******************/ \
|
/*******************/ \
|
||||||
/* GrowableArrays */ \
|
/* GrowableArrays */ \
|
||||||
|
@ -1238,9 +1236,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
|
||||||
nonstatic_field(FreeList<Metablock>, _count, ssize_t) \
|
nonstatic_field(FreeList<Metablock>, _count, ssize_t) \
|
||||||
nonstatic_field(MetablockTreeDictionary, _total_size, size_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
|
// VM_TYPES
|
||||||
|
@ -1280,8 +1275,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
|
||||||
declare_unsigned_integer_type, \
|
declare_unsigned_integer_type, \
|
||||||
declare_c1_toplevel_type, \
|
declare_c1_toplevel_type, \
|
||||||
declare_c2_type, \
|
declare_c2_type, \
|
||||||
declare_c2_toplevel_type, \
|
declare_c2_toplevel_type) \
|
||||||
last_entry) \
|
|
||||||
\
|
\
|
||||||
/*************************************************************/ \
|
/*************************************************************/ \
|
||||||
/* Java primitive types -- required by the SA implementation */ \
|
/* Java primitive types -- required by the SA implementation */ \
|
||||||
|
@ -2098,10 +2092,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
|
||||||
declare_type(MetablockTreeDictionary, FreeBlockDictionary<Metablock>)
|
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
|
// VM_INT_CONSTANTS
|
||||||
//
|
//
|
||||||
|
@ -2114,8 +2104,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
|
||||||
declare_preprocessor_constant, \
|
declare_preprocessor_constant, \
|
||||||
declare_c1_constant, \
|
declare_c1_constant, \
|
||||||
declare_c2_constant, \
|
declare_c2_constant, \
|
||||||
declare_c2_preprocessor_constant, \
|
declare_c2_preprocessor_constant) \
|
||||||
last_entry) \
|
|
||||||
\
|
\
|
||||||
/******************/ \
|
/******************/ \
|
||||||
/* Useful globals */ \
|
/* Useful globals */ \
|
||||||
|
@ -2294,10 +2283,17 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
|
||||||
declare_constant(FieldInfo::name_index_offset) \
|
declare_constant(FieldInfo::name_index_offset) \
|
||||||
declare_constant(FieldInfo::signature_index_offset) \
|
declare_constant(FieldInfo::signature_index_offset) \
|
||||||
declare_constant(FieldInfo::initval_index_offset) \
|
declare_constant(FieldInfo::initval_index_offset) \
|
||||||
declare_constant(FieldInfo::low_offset) \
|
declare_constant(FieldInfo::low_packed_offset) \
|
||||||
declare_constant(FieldInfo::high_offset) \
|
declare_constant(FieldInfo::high_packed_offset) \
|
||||||
declare_constant(FieldInfo::field_slots) \
|
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 */ \
|
/* 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("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)
|
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
|
// VM_LONG_CONSTANTS
|
||||||
|
@ -2495,7 +2488,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
|
||||||
// enums, etc., while "declare_preprocessor_constant" must be used for
|
// enums, etc., while "declare_preprocessor_constant" must be used for
|
||||||
// all #defined constants.
|
// 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 */ \
|
/* MarkOop constants */ \
|
||||||
|
@ -2541,11 +2534,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
|
||||||
/* Constants in markOop used by CMS. */ \
|
/* Constants in markOop used by CMS. */ \
|
||||||
declare_constant(markOopDesc::cms_shift) \
|
declare_constant(markOopDesc::cms_shift) \
|
||||||
declare_constant(markOopDesc::cms_mask) \
|
declare_constant(markOopDesc::cms_mask) \
|
||||||
declare_constant(markOopDesc::size_shift) \
|
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) */
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -2585,7 +2574,8 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
|
||||||
|
|
||||||
// This macro checks the type of a VMStructEntry by comparing pointer types
|
// This macro checks the type of a VMStructEntry by comparing pointer types
|
||||||
#define CHECK_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
|
#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
|
// This macro checks the type of a volatile VMStructEntry by comparing pointer types
|
||||||
#define CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
|
#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
|
// This is a no-op macro for unchecked fields
|
||||||
#define CHECK_NO_OP(a, b, c)
|
#define CHECK_NO_OP(a, b, c)
|
||||||
|
|
||||||
// This is a no-op macro for the sentinel value
|
|
||||||
#define CHECK_SENTINEL()
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Build-specific macros:
|
// Build-specific macros:
|
||||||
//
|
//
|
||||||
|
@ -2789,48 +2776,47 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
|
||||||
// as long as class VMStructs is a friend
|
// as long as class VMStructs is a friend
|
||||||
VMStructEntry VMStructs::localHotSpotVMStructs[] = {
|
VMStructEntry VMStructs::localHotSpotVMStructs[] = {
|
||||||
|
|
||||||
VM_STRUCTS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
|
VM_STRUCTS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_STATIC_VM_STRUCT_ENTRY, \
|
GENERATE_STATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY, \
|
GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
|
GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY, \
|
GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_C1_NONSTATIC_VM_STRUCT_ENTRY, \
|
GENERATE_C1_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY, \
|
GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \
|
GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \
|
GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY)
|
||||||
GENERATE_VM_STRUCT_LAST_ENTRY)
|
|
||||||
|
|
||||||
#ifndef SERIALGC
|
#ifndef SERIALGC
|
||||||
VM_STRUCTS_PARALLELGC(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
|
VM_STRUCTS_PARALLELGC(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_STATIC_VM_STRUCT_ENTRY)
|
GENERATE_STATIC_VM_STRUCT_ENTRY)
|
||||||
|
|
||||||
VM_STRUCTS_CMS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
|
VM_STRUCTS_CMS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
|
GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_STATIC_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)
|
GENERATE_STATIC_VM_STRUCT_ENTRY)
|
||||||
#endif // SERIALGC
|
#endif // SERIALGC
|
||||||
|
|
||||||
VM_STRUCTS_CPU(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
|
VM_STRUCTS_CPU(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_STATIC_VM_STRUCT_ENTRY, \
|
GENERATE_STATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY, \
|
GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
|
GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY, \
|
GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY, \
|
GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \
|
GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_C2_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, \
|
VM_STRUCTS_OS_CPU(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_STATIC_VM_STRUCT_ENTRY, \
|
GENERATE_STATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY, \
|
GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
|
GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY, \
|
GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY, \
|
GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \
|
GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY,
|
||||||
GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \
|
GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY)
|
||||||
GENERATE_VM_STRUCT_LAST_ENTRY)
|
|
||||||
|
GENERATE_VM_STRUCT_LAST_ENTRY()
|
||||||
};
|
};
|
||||||
|
|
||||||
VMTypeEntry VMStructs::localHotSpotVMTypes[] = {
|
VMTypeEntry VMStructs::localHotSpotVMTypes[] = {
|
||||||
|
@ -2842,8 +2828,7 @@ VMTypeEntry VMStructs::localHotSpotVMTypes[] = {
|
||||||
GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY,
|
GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY,
|
||||||
GENERATE_C1_TOPLEVEL_VM_TYPE_ENTRY,
|
GENERATE_C1_TOPLEVEL_VM_TYPE_ENTRY,
|
||||||
GENERATE_C2_VM_TYPE_ENTRY,
|
GENERATE_C2_VM_TYPE_ENTRY,
|
||||||
GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY,
|
GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY)
|
||||||
GENERATE_VM_TYPE_LAST_ENTRY)
|
|
||||||
|
|
||||||
#ifndef SERIALGC
|
#ifndef SERIALGC
|
||||||
VM_TYPES_PARALLELGC(GENERATE_VM_TYPE_ENTRY,
|
VM_TYPES_PARALLELGC(GENERATE_VM_TYPE_ENTRY,
|
||||||
|
@ -2865,8 +2850,7 @@ VMTypeEntry VMStructs::localHotSpotVMTypes[] = {
|
||||||
GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY,
|
GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY,
|
||||||
GENERATE_C1_TOPLEVEL_VM_TYPE_ENTRY,
|
GENERATE_C1_TOPLEVEL_VM_TYPE_ENTRY,
|
||||||
GENERATE_C2_VM_TYPE_ENTRY,
|
GENERATE_C2_VM_TYPE_ENTRY,
|
||||||
GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY,
|
GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY)
|
||||||
GENERATE_VM_TYPE_LAST_ENTRY)
|
|
||||||
|
|
||||||
VM_TYPES_OS_CPU(GENERATE_VM_TYPE_ENTRY,
|
VM_TYPES_OS_CPU(GENERATE_VM_TYPE_ENTRY,
|
||||||
GENERATE_TOPLEVEL_VM_TYPE_ENTRY,
|
GENERATE_TOPLEVEL_VM_TYPE_ENTRY,
|
||||||
|
@ -2875,8 +2859,9 @@ VMTypeEntry VMStructs::localHotSpotVMTypes[] = {
|
||||||
GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY,
|
GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY,
|
||||||
GENERATE_C1_TOPLEVEL_VM_TYPE_ENTRY,
|
GENERATE_C1_TOPLEVEL_VM_TYPE_ENTRY,
|
||||||
GENERATE_C2_VM_TYPE_ENTRY,
|
GENERATE_C2_VM_TYPE_ENTRY,
|
||||||
GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY,
|
GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY)
|
||||||
GENERATE_VM_TYPE_LAST_ENTRY)
|
|
||||||
|
GENERATE_VM_TYPE_LAST_ENTRY()
|
||||||
};
|
};
|
||||||
|
|
||||||
VMIntConstantEntry VMStructs::localHotSpotVMIntConstants[] = {
|
VMIntConstantEntry VMStructs::localHotSpotVMIntConstants[] = {
|
||||||
|
@ -2885,8 +2870,7 @@ VMIntConstantEntry VMStructs::localHotSpotVMIntConstants[] = {
|
||||||
GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
|
GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
|
||||||
GENERATE_C1_VM_INT_CONSTANT_ENTRY,
|
GENERATE_C1_VM_INT_CONSTANT_ENTRY,
|
||||||
GENERATE_C2_VM_INT_CONSTANT_ENTRY,
|
GENERATE_C2_VM_INT_CONSTANT_ENTRY,
|
||||||
GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
|
GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY)
|
||||||
GENERATE_VM_INT_CONSTANT_LAST_ENTRY)
|
|
||||||
|
|
||||||
#ifndef SERIALGC
|
#ifndef SERIALGC
|
||||||
VM_INT_CONSTANTS_CMS(GENERATE_VM_INT_CONSTANT_ENTRY)
|
VM_INT_CONSTANTS_CMS(GENERATE_VM_INT_CONSTANT_ENTRY)
|
||||||
|
@ -2898,15 +2882,15 @@ VMIntConstantEntry VMStructs::localHotSpotVMIntConstants[] = {
|
||||||
GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
|
GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
|
||||||
GENERATE_C1_VM_INT_CONSTANT_ENTRY,
|
GENERATE_C1_VM_INT_CONSTANT_ENTRY,
|
||||||
GENERATE_C2_VM_INT_CONSTANT_ENTRY,
|
GENERATE_C2_VM_INT_CONSTANT_ENTRY,
|
||||||
GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
|
GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY)
|
||||||
GENERATE_VM_INT_CONSTANT_LAST_ENTRY)
|
|
||||||
|
|
||||||
VM_INT_CONSTANTS_OS_CPU(GENERATE_VM_INT_CONSTANT_ENTRY,
|
VM_INT_CONSTANTS_OS_CPU(GENERATE_VM_INT_CONSTANT_ENTRY,
|
||||||
GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
|
GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
|
||||||
GENERATE_C1_VM_INT_CONSTANT_ENTRY,
|
GENERATE_C1_VM_INT_CONSTANT_ENTRY,
|
||||||
GENERATE_C2_VM_INT_CONSTANT_ENTRY,
|
GENERATE_C2_VM_INT_CONSTANT_ENTRY,
|
||||||
GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
|
GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY)
|
||||||
GENERATE_VM_INT_CONSTANT_LAST_ENTRY)
|
|
||||||
|
GENERATE_VM_INT_CONSTANT_LAST_ENTRY()
|
||||||
};
|
};
|
||||||
|
|
||||||
VMLongConstantEntry VMStructs::localHotSpotVMLongConstants[] = {
|
VMLongConstantEntry VMStructs::localHotSpotVMLongConstants[] = {
|
||||||
|
@ -2915,22 +2899,21 @@ VMLongConstantEntry VMStructs::localHotSpotVMLongConstants[] = {
|
||||||
GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
|
GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
|
||||||
GENERATE_C1_VM_LONG_CONSTANT_ENTRY,
|
GENERATE_C1_VM_LONG_CONSTANT_ENTRY,
|
||||||
GENERATE_C2_VM_LONG_CONSTANT_ENTRY,
|
GENERATE_C2_VM_LONG_CONSTANT_ENTRY,
|
||||||
GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
|
GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY)
|
||||||
GENERATE_VM_LONG_CONSTANT_LAST_ENTRY)
|
|
||||||
|
|
||||||
VM_LONG_CONSTANTS_CPU(GENERATE_VM_LONG_CONSTANT_ENTRY,
|
VM_LONG_CONSTANTS_CPU(GENERATE_VM_LONG_CONSTANT_ENTRY,
|
||||||
GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
|
GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
|
||||||
GENERATE_C1_VM_LONG_CONSTANT_ENTRY,
|
GENERATE_C1_VM_LONG_CONSTANT_ENTRY,
|
||||||
GENERATE_C2_VM_LONG_CONSTANT_ENTRY,
|
GENERATE_C2_VM_LONG_CONSTANT_ENTRY,
|
||||||
GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
|
GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY)
|
||||||
GENERATE_VM_LONG_CONSTANT_LAST_ENTRY)
|
|
||||||
|
|
||||||
VM_LONG_CONSTANTS_OS_CPU(GENERATE_VM_LONG_CONSTANT_ENTRY,
|
VM_LONG_CONSTANTS_OS_CPU(GENERATE_VM_LONG_CONSTANT_ENTRY,
|
||||||
GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
|
GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
|
||||||
GENERATE_C1_VM_LONG_CONSTANT_ENTRY,
|
GENERATE_C1_VM_LONG_CONSTANT_ENTRY,
|
||||||
GENERATE_C2_VM_LONG_CONSTANT_ENTRY,
|
GENERATE_C2_VM_LONG_CONSTANT_ENTRY,
|
||||||
GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
|
GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY)
|
||||||
GENERATE_VM_LONG_CONSTANT_LAST_ENTRY)
|
|
||||||
|
GENERATE_VM_LONG_CONSTANT_LAST_ENTRY()
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is used both to check the types of referenced fields and, in
|
// 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_C1_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
CHECK_C2_NONSTATIC_VM_STRUCT_ENTRY,
|
CHECK_C2_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
CHECK_NO_OP,
|
CHECK_NO_OP,
|
||||||
CHECK_NO_OP,
|
CHECK_NO_OP);
|
||||||
CHECK_SENTINEL);
|
|
||||||
|
|
||||||
#ifndef SERIALGC
|
#ifndef SERIALGC
|
||||||
VM_STRUCTS_PARALLELGC(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
|
VM_STRUCTS_PARALLELGC(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
|
@ -2967,8 +2949,7 @@ VMStructs::init() {
|
||||||
CHECK_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY,
|
CHECK_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
CHECK_C2_NONSTATIC_VM_STRUCT_ENTRY,
|
CHECK_C2_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
CHECK_NO_OP,
|
CHECK_NO_OP,
|
||||||
CHECK_NO_OP,
|
CHECK_NO_OP);
|
||||||
CHECK_SENTINEL);
|
|
||||||
|
|
||||||
VM_STRUCTS_OS_CPU(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
|
VM_STRUCTS_OS_CPU(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
CHECK_STATIC_VM_STRUCT_ENTRY,
|
CHECK_STATIC_VM_STRUCT_ENTRY,
|
||||||
|
@ -2977,8 +2958,7 @@ VMStructs::init() {
|
||||||
CHECK_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY,
|
CHECK_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
CHECK_C2_NONSTATIC_VM_STRUCT_ENTRY,
|
CHECK_C2_NONSTATIC_VM_STRUCT_ENTRY,
|
||||||
CHECK_NO_OP,
|
CHECK_NO_OP,
|
||||||
CHECK_NO_OP,
|
CHECK_NO_OP);
|
||||||
CHECK_SENTINEL);
|
|
||||||
|
|
||||||
VM_TYPES(CHECK_VM_TYPE_ENTRY,
|
VM_TYPES(CHECK_VM_TYPE_ENTRY,
|
||||||
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
|
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
|
||||||
|
@ -2987,8 +2967,7 @@ VMStructs::init() {
|
||||||
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
|
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
|
||||||
CHECK_C1_TOPLEVEL_VM_TYPE_ENTRY,
|
CHECK_C1_TOPLEVEL_VM_TYPE_ENTRY,
|
||||||
CHECK_C2_VM_TYPE_ENTRY,
|
CHECK_C2_VM_TYPE_ENTRY,
|
||||||
CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY,
|
CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY);
|
||||||
CHECK_SENTINEL);
|
|
||||||
|
|
||||||
#ifndef SERIALGC
|
#ifndef SERIALGC
|
||||||
VM_TYPES_PARALLELGC(CHECK_VM_TYPE_ENTRY,
|
VM_TYPES_PARALLELGC(CHECK_VM_TYPE_ENTRY,
|
||||||
|
@ -3010,8 +2989,7 @@ VMStructs::init() {
|
||||||
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
|
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
|
||||||
CHECK_C1_TOPLEVEL_VM_TYPE_ENTRY,
|
CHECK_C1_TOPLEVEL_VM_TYPE_ENTRY,
|
||||||
CHECK_C2_VM_TYPE_ENTRY,
|
CHECK_C2_VM_TYPE_ENTRY,
|
||||||
CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY,
|
CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY);
|
||||||
CHECK_SENTINEL);
|
|
||||||
|
|
||||||
VM_TYPES_OS_CPU(CHECK_VM_TYPE_ENTRY,
|
VM_TYPES_OS_CPU(CHECK_VM_TYPE_ENTRY,
|
||||||
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
|
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
|
||||||
|
@ -3020,8 +2998,7 @@ VMStructs::init() {
|
||||||
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
|
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
|
||||||
CHECK_C1_TOPLEVEL_VM_TYPE_ENTRY,
|
CHECK_C1_TOPLEVEL_VM_TYPE_ENTRY,
|
||||||
CHECK_C2_VM_TYPE_ENTRY,
|
CHECK_C2_VM_TYPE_ENTRY,
|
||||||
CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY,
|
CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY);
|
||||||
CHECK_SENTINEL);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Split VM_STRUCTS() invocation into two parts to allow MS VC++ 6.0
|
// 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
|
// Solstice NFS setup. If everyone switches to local workspaces on
|
||||||
// Win32, we can put this back in.
|
// Win32, we can put this back in.
|
||||||
#ifndef _WINDOWS
|
#ifndef _WINDOWS
|
||||||
debug_only(VM_STRUCTS(ENSURE_FIELD_TYPE_PRESENT, \
|
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_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,
|
||||||
debug_only(VM_STRUCTS(CHECK_NO_OP, \
|
ENSURE_FIELD_TYPE_PRESENT,
|
||||||
ENSURE_FIELD_TYPE_PRESENT, \
|
CHECK_NO_OP,
|
||||||
CHECK_NO_OP, \
|
ENSURE_FIELD_TYPE_PRESENT,
|
||||||
ENSURE_FIELD_TYPE_PRESENT, \
|
ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT,
|
||||||
ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT, \
|
ENSURE_C1_FIELD_TYPE_PRESENT,
|
||||||
ENSURE_C1_FIELD_TYPE_PRESENT, \
|
ENSURE_C2_FIELD_TYPE_PRESENT,
|
||||||
ENSURE_C2_FIELD_TYPE_PRESENT, \
|
CHECK_NO_OP,
|
||||||
CHECK_NO_OP, \
|
CHECK_NO_OP));
|
||||||
CHECK_NO_OP, \
|
|
||||||
CHECK_SENTINEL));
|
|
||||||
#ifndef SERIALGC
|
#ifndef SERIALGC
|
||||||
debug_only(VM_STRUCTS_PARALLELGC(ENSURE_FIELD_TYPE_PRESENT, \
|
debug_only(VM_STRUCTS_PARALLELGC(ENSURE_FIELD_TYPE_PRESENT,
|
||||||
ENSURE_FIELD_TYPE_PRESENT));
|
ENSURE_FIELD_TYPE_PRESENT));
|
||||||
debug_only(VM_STRUCTS_CMS(ENSURE_FIELD_TYPE_PRESENT, \
|
debug_only(VM_STRUCTS_CMS(ENSURE_FIELD_TYPE_PRESENT,
|
||||||
ENSURE_FIELD_TYPE_PRESENT, \
|
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));
|
ENSURE_FIELD_TYPE_PRESENT));
|
||||||
#endif // SERIALGC
|
#endif // SERIALGC
|
||||||
debug_only(VM_STRUCTS_CPU(ENSURE_FIELD_TYPE_PRESENT, \
|
debug_only(VM_STRUCTS_CPU(ENSURE_FIELD_TYPE_PRESENT,
|
||||||
ENSURE_FIELD_TYPE_PRESENT, \
|
ENSURE_FIELD_TYPE_PRESENT,
|
||||||
CHECK_NO_OP, \
|
CHECK_NO_OP,
|
||||||
ENSURE_FIELD_TYPE_PRESENT, \
|
ENSURE_FIELD_TYPE_PRESENT,
|
||||||
ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT, \
|
ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT,
|
||||||
ENSURE_C2_FIELD_TYPE_PRESENT, \
|
ENSURE_C2_FIELD_TYPE_PRESENT,
|
||||||
CHECK_NO_OP, \
|
CHECK_NO_OP,
|
||||||
CHECK_NO_OP, \
|
CHECK_NO_OP));
|
||||||
CHECK_SENTINEL));
|
debug_only(VM_STRUCTS_OS_CPU(ENSURE_FIELD_TYPE_PRESENT,
|
||||||
debug_only(VM_STRUCTS_OS_CPU(ENSURE_FIELD_TYPE_PRESENT, \
|
ENSURE_FIELD_TYPE_PRESENT,
|
||||||
ENSURE_FIELD_TYPE_PRESENT, \
|
CHECK_NO_OP,
|
||||||
CHECK_NO_OP, \
|
ENSURE_FIELD_TYPE_PRESENT,
|
||||||
ENSURE_FIELD_TYPE_PRESENT, \
|
ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT,
|
||||||
ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT, \
|
ENSURE_C2_FIELD_TYPE_PRESENT,
|
||||||
ENSURE_C2_FIELD_TYPE_PRESENT, \
|
CHECK_NO_OP,
|
||||||
CHECK_NO_OP, \
|
CHECK_NO_OP));
|
||||||
CHECK_NO_OP, \
|
|
||||||
CHECK_SENTINEL));
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3146,10 +3119,10 @@ static int recursiveFindType(VMTypeEntry* origtypes, const char* typeName, bool
|
||||||
s[len-1] = '\0';
|
s[len-1] = '\0';
|
||||||
// tty->print_cr("checking \"%s\" for \"%s\"", s, typeName);
|
// tty->print_cr("checking \"%s\" for \"%s\"", s, typeName);
|
||||||
if (recursiveFindType(origtypes, s, true) == 1) {
|
if (recursiveFindType(origtypes, s, true) == 1) {
|
||||||
delete s;
|
delete [] s;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
delete s;
|
delete [] s;
|
||||||
}
|
}
|
||||||
const char* start = NULL;
|
const char* start = NULL;
|
||||||
if (strstr(typeName, "GrowableArray<") == typeName) {
|
if (strstr(typeName, "GrowableArray<") == typeName) {
|
||||||
|
@ -3165,10 +3138,10 @@ static int recursiveFindType(VMTypeEntry* origtypes, const char* typeName, bool
|
||||||
s[len-1] = '\0';
|
s[len-1] = '\0';
|
||||||
// tty->print_cr("checking \"%s\" for \"%s\"", s, typeName);
|
// tty->print_cr("checking \"%s\" for \"%s\"", s, typeName);
|
||||||
if (recursiveFindType(origtypes, s, true) == 1) {
|
if (recursiveFindType(origtypes, s, true) == 1) {
|
||||||
delete s;
|
delete [] s;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
delete s;
|
delete [] s;
|
||||||
}
|
}
|
||||||
if (strstr(typeName, "const ") == typeName) {
|
if (strstr(typeName, "const ") == typeName) {
|
||||||
const char * s = typeName + strlen("const ");
|
const char * s = typeName + strlen("const ");
|
||||||
|
@ -3182,8 +3155,10 @@ static int recursiveFindType(VMTypeEntry* origtypes, const char* typeName, bool
|
||||||
s[len - 6] = '\0';
|
s[len - 6] = '\0';
|
||||||
// tty->print_cr("checking \"%s\" for \"%s\"", s, typeName);
|
// tty->print_cr("checking \"%s\" for \"%s\"", s, typeName);
|
||||||
if (recursiveFindType(origtypes, s, true) == 1) {
|
if (recursiveFindType(origtypes, s, true) == 1) {
|
||||||
|
free(s);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
free(s);
|
||||||
}
|
}
|
||||||
if (!isRecurse) {
|
if (!isRecurse) {
|
||||||
tty->print_cr("type \"%s\" not found", typeName);
|
tty->print_cr("type \"%s\" not found", typeName);
|
||||||
|
@ -3206,6 +3181,30 @@ void vmStructs_init() {
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
void VMStructs::test() {
|
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
|
// Check for duplicate entries in type array
|
||||||
for (int i = 0; localHotSpotVMTypes[i].typeName != NULL; i++) {
|
for (int i = 0; localHotSpotVMTypes[i].typeName != NULL; i++) {
|
||||||
for (int j = i + 1; localHotSpotVMTypes[j].typeName != NULL; j++) {
|
for (int j = i + 1; localHotSpotVMTypes[j].typeName != NULL; j++) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -267,6 +267,7 @@ class Exceptions {
|
||||||
#define THROW_WRAPPED_0(name, oop_to_wrap) THROW_WRAPPED_(name, oop_to_wrap, 0)
|
#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_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_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_NULL(name) THROW_(name, NULL)
|
||||||
#define THROW_MSG_NULL(name, message) THROW_MSG_(name, message, NULL)
|
#define THROW_MSG_NULL(name, message) THROW_MSG_(name, message, NULL)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue