提交 817c1633 编写于 作者: A acorn

Merge

......@@ -52,6 +52,8 @@ public class InstanceKlass extends Klass {
private static int LOW_OFFSET;
private static int HIGH_OFFSET;
private static int FIELD_SLOTS;
private static short FIELDINFO_TAG_SIZE;
private static short FIELDINFO_TAG_OFFSET;
// ClassState constants
private static int CLASS_STATE_ALLOCATED;
......@@ -96,9 +98,12 @@ public class InstanceKlass extends Klass {
NAME_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::name_index_offset").intValue();
SIGNATURE_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::signature_index_offset").intValue();
INITVAL_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::initval_index_offset").intValue();
LOW_OFFSET = db.lookupIntConstant("FieldInfo::low_offset").intValue();
HIGH_OFFSET = db.lookupIntConstant("FieldInfo::high_offset").intValue();
LOW_OFFSET = db.lookupIntConstant("FieldInfo::low_packed_offset").intValue();
HIGH_OFFSET = db.lookupIntConstant("FieldInfo::high_packed_offset").intValue();
FIELD_SLOTS = db.lookupIntConstant("FieldInfo::field_slots").intValue();
FIELDINFO_TAG_SIZE = db.lookupIntConstant("FIELDINFO_TAG_SIZE").shortValue();
FIELDINFO_TAG_OFFSET = db.lookupIntConstant("FIELDINFO_TAG_OFFSET").shortValue();
// read ClassState constants
CLASS_STATE_ALLOCATED = db.lookupIntConstant("InstanceKlass::allocated").intValue();
CLASS_STATE_LOADED = db.lookupIntConstant("InstanceKlass::loaded").intValue();
......@@ -314,8 +319,12 @@ public class InstanceKlass extends Klass {
public int getFieldOffset(int index) {
U2Array fields = getFields();
return VM.getVM().buildIntFromShorts(fields.at(index * FIELD_SLOTS + LOW_OFFSET),
fields.at(index * FIELD_SLOTS + HIGH_OFFSET));
short lo = fields.at(index * FIELD_SLOTS + LOW_OFFSET);
short hi = fields.at(index * FIELD_SLOTS + HIGH_OFFSET);
if ((lo & FIELDINFO_TAG_SIZE) == FIELDINFO_TAG_OFFSET) {
return VM.getVM().buildIntFromShorts(lo, hi) >> FIELDINFO_TAG_SIZE;
}
throw new RuntimeException("should not reach here");
}
// Accessors for declared fields
......
......@@ -29,7 +29,7 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/ \
/* JavaCallWrapper */ \
......@@ -37,22 +37,12 @@
/******************************/ \
/* JavaFrameAnchor */ \
/******************************/ \
volatile_nonstatic_field(JavaFrameAnchor, _flags, int) \
\
volatile_nonstatic_field(JavaFrameAnchor, _flags, int)
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_STRUCTS_OS_CPU macro (and must */
/* be present there) */
#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_TYPES_OS_CPU macro (and must */
/* be present there) */
#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
/******************************/ \
/* Register numbers (C2 only) */ \
/******************************/ \
......@@ -90,15 +80,6 @@
declare_c2_constant(R_G6_num) \
declare_c2_constant(R_G7_num)
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_INT_CONSTANTS_OS_CPU macro (and must */
/* be present there) */
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and must */
/* be present there) */
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // CPU_SPARC_VM_VMSTRUCTS_SPARC_HPP
......@@ -259,6 +259,10 @@ void VM_Version::initialize() {
if (!has_vis1()) // Drop to 0 if no VIS1 support
UseVIS = 0;
if (FLAG_IS_DEFAULT(ContendedPaddingWidth) &&
(cache_line_size > ContendedPaddingWidth))
ContendedPaddingWidth = cache_line_size;
#ifndef PRODUCT
if (PrintMiscellaneous && Verbose) {
tty->print("Allocation");
......@@ -286,6 +290,9 @@ void VM_Version::initialize() {
if (PrefetchFieldsAhead > 0) {
tty->print_cr("PrefetchFieldsAhead %d", PrefetchFieldsAhead);
}
if (ContendedPaddingWidth > 0) {
tty->print_cr("ContendedPaddingWidth %d", ContendedPaddingWidth);
}
}
#endif // PRODUCT
}
......
......@@ -29,7 +29,7 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/ \
/* JavaCallWrapper */ \
......@@ -37,31 +37,14 @@
/******************************/ \
/* JavaFrameAnchor */ \
/******************************/ \
volatile_nonstatic_field(JavaFrameAnchor, _last_Java_fp, intptr_t*) \
\
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_STRUCTS_OS_CPU macro (and must */
/* be present there) */
#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_TYPES_OS_CPU macro (and must */
/* be present there) */
volatile_nonstatic_field(JavaFrameAnchor, _last_Java_fp, intptr_t*)
#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_INT_CONSTANTS_OS_CPU macro (and must */
/* be present there) */
#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and must */
/* be present there) */
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // CPU_X86_VM_VMSTRUCTS_X86_HPP
......@@ -745,6 +745,10 @@ void VM_Version::get_processor_features() {
PrefetchFieldsAhead = prefetch_fields_ahead();
#endif
if (FLAG_IS_DEFAULT(ContendedPaddingWidth) &&
(cache_line_size > ContendedPaddingWidth))
ContendedPaddingWidth = cache_line_size;
#ifndef PRODUCT
if (PrintMiscellaneous && Verbose) {
tty->print_cr("Logical CPUs per core: %u",
......@@ -791,6 +795,9 @@ void VM_Version::get_processor_features() {
if (PrefetchFieldsAhead > 0) {
tty->print_cr("PrefetchFieldsAhead %d", PrefetchFieldsAhead);
}
if (ContendedPaddingWidth > 0) {
tty->print_cr("ContendedPaddingWidth %d", ContendedPaddingWidth);
}
}
#endif // !PRODUCT
}
......
......@@ -30,28 +30,12 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field)
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_STRUCTS_OS_CPU macro (and must */
/* be present there) */
#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_TYPES_OS_CPU macro (and must */
/* be present there) */
#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_INT_CONSTANTS_OS_CPU macro (and must */
/* be present there) */
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and must */
/* be present there) */
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // CPU_ZERO_VM_VMSTRUCTS_ZERO_HPP
......@@ -49,7 +49,7 @@ void WindowsDecoder::initialize() {
pfn_SymSetOptions _pfnSymSetOptions = (pfn_SymSetOptions)::GetProcAddress(handle, "SymSetOptions");
pfn_SymInitialize _pfnSymInitialize = (pfn_SymInitialize)::GetProcAddress(handle, "SymInitialize");
_pfnSymGetSymFromAddr64 = (pfn_SymGetSymFromAddr64)::GetProcAddress(handle, "SymGetSymFromAddr64");
_pfnUndecorateSymbolName = (pfn_UndecorateSymbolName)GetProcAddress(handle, "UnDecorateSymbolName");
_pfnUndecorateSymbolName = (pfn_UndecorateSymbolName)::GetProcAddress(handle, "UnDecorateSymbolName");
if (_pfnSymSetOptions == NULL || _pfnSymInitialize == NULL || _pfnSymGetSymFromAddr64 == NULL) {
_pfnSymGetSymFromAddr64 = NULL;
......@@ -60,8 +60,9 @@ void WindowsDecoder::initialize() {
return;
}
_pfnSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
if (!_pfnSymInitialize(GetCurrentProcess(), NULL, TRUE)) {
HANDLE hProcess = ::GetCurrentProcess();
_pfnSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_EXACT_SYMBOLS);
if (!_pfnSymInitialize(hProcess, NULL, TRUE)) {
_pfnSymGetSymFromAddr64 = NULL;
_pfnUndecorateSymbolName = NULL;
::FreeLibrary(handle);
......@@ -70,6 +71,77 @@ void WindowsDecoder::initialize() {
return;
}
// set pdb search paths
pfn_SymSetSearchPath _pfn_SymSetSearchPath =
(pfn_SymSetSearchPath)::GetProcAddress(handle, "SymSetSearchPath");
pfn_SymGetSearchPath _pfn_SymGetSearchPath =
(pfn_SymGetSearchPath)::GetProcAddress(handle, "SymGetSearchPath");
if (_pfn_SymSetSearchPath != NULL && _pfn_SymGetSearchPath != NULL) {
char paths[MAX_PATH];
int len = sizeof(paths);
if (!_pfn_SymGetSearchPath(hProcess, paths, len)) {
paths[0] = '\0';
} else {
// available spaces in path buffer
len -= (int)strlen(paths);
}
char tmp_path[MAX_PATH];
DWORD dwSize;
HMODULE hJVM = ::GetModuleHandle("jvm.dll");
tmp_path[0] = '\0';
// append the path where jvm.dll is located
if (hJVM != NULL && (dwSize = ::GetModuleFileName(hJVM, tmp_path, sizeof(tmp_path))) > 0) {
while (dwSize > 0 && tmp_path[dwSize] != '\\') {
dwSize --;
}
tmp_path[dwSize] = '\0';
if (dwSize > 0 && len > (int)dwSize + 1) {
strncat(paths, os::path_separator(), 1);
strncat(paths, tmp_path, dwSize);
len -= dwSize + 1;
}
}
// append $JRE/bin. Arguments::get_java_home actually returns $JRE
// path
char *p = Arguments::get_java_home();
assert(p != NULL, "empty java home");
size_t java_home_len = strlen(p);
if (len > (int)java_home_len + 5) {
strncat(paths, os::path_separator(), 1);
strncat(paths, p, java_home_len);
strncat(paths, "\\bin", 4);
len -= (int)(java_home_len + 5);
}
// append $JDK/bin path if it exists
assert(java_home_len < MAX_PATH, "Invalid path length");
// assume $JRE is under $JDK, construct $JDK/bin path and
// see if it exists or not
if (strncmp(&p[java_home_len - 3], "jre", 3) == 0) {
strncpy(tmp_path, p, java_home_len - 3);
tmp_path[java_home_len - 3] = '\0';
strncat(tmp_path, "bin", 3);
// if the directory exists
DWORD dwAttrib = GetFileAttributes(tmp_path);
if (dwAttrib != INVALID_FILE_ATTRIBUTES &&
(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) {
// tmp_path should have the same length as java_home_len, since we only
// replaced 'jre' with 'bin'
if (len > (int)java_home_len + 1) {
strncat(paths, os::path_separator(), 1);
strncat(paths, tmp_path, java_home_len);
}
}
}
_pfn_SymSetSearchPath(hProcess, paths);
}
// find out if jvm.dll contains private symbols, by decoding
// current function and comparing the result
address addr = (address)Decoder::demangle;
......
......@@ -35,6 +35,8 @@ typedef DWORD (WINAPI *pfn_SymSetOptions)(DWORD);
typedef BOOL (WINAPI *pfn_SymInitialize)(HANDLE, PCTSTR, BOOL);
typedef BOOL (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWORD);
typedef BOOL (WINAPI *pfn_SymSetSearchPath)(HANDLE, PCTSTR);
typedef BOOL (WINAPI *pfn_SymGetSearchPath)(HANDLE, PTSTR, int);
class WindowsDecoder : public AbstractDecoder {
......
......@@ -29,37 +29,26 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/ \
/* Threads (NOTE: incomplete) */ \
/******************************/ \
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
nonstatic_field(OSThread, _pthread_id, pthread_t) \
/* This must be the last entry, and must be present */ \
last_entry()
nonstatic_field(OSThread, _pthread_id, pthread_t)
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
\
/**********************/ \
/* Posix Thread IDs */ \
/**********************/ \
\
declare_unsigned_integer_type(OSThread::thread_id_t) \
declare_unsigned_integer_type(pthread_t) \
\
/* This must be the last entry, and must be present */ \
last_entry()
declare_unsigned_integer_type(pthread_t)
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
\
/* This must be the last entry, and must be present */ \
last_entry()
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
\
/* This must be the last entry, and must be present */ \
last_entry()
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_BSD_X86_VM_VMSTRUCTS_BSD_X86_HPP
......@@ -30,21 +30,13 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
/* This must be the last entry, and must be present */ \
last_entry()
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field)
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
/* This must be the last entry, and must be present */ \
last_entry()
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
/* This must be the last entry, and must be present */ \
last_entry()
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
/* This must be the last entry, and must be present */ \
last_entry()
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_BSD_ZERO_VM_VMSTRUCTS_BSD_ZERO_HPP
......@@ -29,7 +29,7 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/ \
/* Threads (NOTE: incomplete) */ \
......@@ -37,38 +37,27 @@
\
nonstatic_field(JavaThread, _base_of_stack_pointer, intptr_t*) \
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
nonstatic_field(OSThread, _pthread_id, pthread_t) \
/* This must be the last entry, and must be present */ \
last_entry()
nonstatic_field(OSThread, _pthread_id, pthread_t)
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
\
/**********************/ \
/* POSIX Thread IDs */ \
/**********************/ \
\
declare_integer_type(OSThread::thread_id_t) \
declare_unsigned_integer_type(pthread_t) \
\
/* This must be the last entry, and must be present */ \
last_entry()
declare_unsigned_integer_type(pthread_t)
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
\
/************************/ \
/* JavaThread constants */ \
/************************/ \
\
declare_constant(JavaFrameAnchor::flushed) \
\
/* This must be the last entry, and must be present */ \
last_entry()
declare_constant(JavaFrameAnchor::flushed)
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
\
/* This must be the last entry, and must be present */ \
last_entry()
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_LINUX_SPARC_VM_VMSTRUCTS_LINUX_SPARC_HPP
......@@ -29,37 +29,26 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/ \
/* Threads (NOTE: incomplete) */ \
/******************************/ \
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
nonstatic_field(OSThread, _pthread_id, pthread_t) \
/* This must be the last entry, and must be present */ \
last_entry()
nonstatic_field(OSThread, _pthread_id, pthread_t)
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
\
/**********************/ \
/* Posix Thread IDs */ \
/**********************/ \
\
declare_integer_type(OSThread::thread_id_t) \
declare_unsigned_integer_type(pthread_t) \
\
/* This must be the last entry, and must be present */ \
last_entry()
declare_unsigned_integer_type(pthread_t)
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
\
/* This must be the last entry, and must be present */ \
last_entry()
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
\
/* This must be the last entry, and must be present */ \
last_entry()
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_LINUX_X86_VM_VMSTRUCTS_LINUX_X86_HPP
......@@ -30,21 +30,12 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
/* This must be the last entry, and must be present */ \
last_entry()
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field)
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
/* This must be the last entry, and must be present */ \
last_entry()
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
/* This must be the last entry, and must be present */ \
last_entry()
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
/* This must be the last entry, and must be present */ \
last_entry()
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_LINUX_ZERO_VM_VMSTRUCTS_LINUX_ZERO_HPP
......@@ -29,44 +29,32 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/ \
/* Threads (NOTE: incomplete) */ \
/******************************/ \
\
nonstatic_field(JavaThread, _base_of_stack_pointer, intptr_t*) \
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
/* This must be the last entry, and must be present */ \
last_entry()
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t)
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
\
/**********************/ \
/* Solaris Thread IDs */ \
/**********************/ \
\
declare_unsigned_integer_type(OSThread::thread_id_t) \
\
/* This must be the last entry, and must be present */ \
last_entry()
declare_unsigned_integer_type(OSThread::thread_id_t)
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
\
/************************/ \
/* JavaThread constants */ \
/************************/ \
\
declare_constant(JavaFrameAnchor::flushed) \
\
/* This must be the last entry, and must be present */ \
last_entry()
declare_constant(JavaFrameAnchor::flushed)
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
\
/* This must be the last entry, and must be present */ \
last_entry()
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_SOLARIS_SPARC_VM_VMSTRUCTS_SOLARIS_SPARC_HPP
......@@ -29,36 +29,24 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/ \
/* Threads (NOTE: incomplete) */ \
/******************************/ \
\
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
\
/* This must be the last entry, and must be present */ \
last_entry()
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t)
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
\
/**********************/ \
/* Solaris Thread IDs */ \
/**********************/ \
\
declare_unsigned_integer_type(OSThread::thread_id_t) \
\
/* This must be the last entry, and must be present */ \
last_entry()
declare_unsigned_integer_type(OSThread::thread_id_t)
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
\
/* This must be the last entry, and must be present */ \
last_entry()
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
\
/* This must be the last entry, and must be present */ \
last_entry()
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_SOLARIS_X86_VM_VMSTRUCTS_SOLARIS_X86_HPP
......@@ -29,32 +29,21 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/ \
/* Threads (NOTE: incomplete) */ \
/******************************/ \
\
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
unchecked_nonstatic_field(OSThread, _thread_handle, sizeof(HANDLE)) /* NOTE: no type */ \
\
/* This must be the last entry, and must be present */ \
last_entry()
unchecked_nonstatic_field(OSThread, _thread_handle, sizeof(HANDLE)) /* NOTE: no type */
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
\
declare_unsigned_integer_type(OSThread::thread_id_t) \
/* This must be the last entry, and must be present */ \
last_entry()
declare_unsigned_integer_type(OSThread::thread_id_t)
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
\
/* This must be the last entry, and must be present */ \
last_entry()
#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
\
/* This must be the last entry, and must be present */ \
last_entry()
#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_WINDOWS_X86_VM_VMSTRUCTS_WINDOWS_X86_HPP
......@@ -95,17 +95,20 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
_method_DontInline,
_method_LambdaForm_Compiled,
_method_LambdaForm_Hidden,
_sun_misc_Contended,
_annotation_LIMIT
};
const Location _location;
int _annotations_present;
u2 _contended_group;
AnnotationCollector(Location location)
: _location(location), _annotations_present(0)
{
assert((int)_annotation_LIMIT <= (int)sizeof(_annotations_present) * BitsPerByte, "");
}
// If this annotation name has an ID, report it (or _none).
ID annotation_index(Symbol* name);
ID annotation_index(ClassLoaderData* loader_data, Symbol* name);
// Set the annotation name:
void set_annotation(ID id) {
assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob");
......@@ -114,6 +117,12 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
// Report if the annotation is present.
bool has_any_annotations() { return _annotations_present != 0; }
bool has_annotation(ID id) { return (nth_bit((int)id) & _annotations_present) != 0; }
void set_contended_group(u2 group) { _contended_group = group; }
u2 contended_group() { return _contended_group; }
void set_contended(bool contended) { set_annotation(_sun_misc_Contended); }
bool is_contended() { return has_annotation(_sun_misc_Contended); }
};
class FieldAnnotationCollector: public AnnotationCollector {
public:
......@@ -177,6 +186,14 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
Array<AnnotationArray*>** fields_type_annotations,
u2* java_fields_count_ptr, TRAPS);
void print_field_layout(Symbol* name,
Array<u2>* fields,
constantPoolHandle cp,
int instance_size,
int instance_fields_start,
int instance_fields_end,
int static_fields_end);
// Method parsing
methodHandle parse_method(ClassLoaderData* loader_data,
constantPoolHandle cp,
......@@ -247,7 +264,8 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
int runtime_invisible_annotations_length, TRAPS);
int skip_annotation(u1* buffer, int limit, int index);
int skip_annotation_value(u1* buffer, int limit, int index);
void parse_annotations(u1* buffer, int limit, constantPoolHandle cp,
void parse_annotations(ClassLoaderData* loader_data,
u1* buffer, int limit, constantPoolHandle cp,
/* Results (currently, only one result is supported): */
AnnotationCollector* result,
TRAPS);
......
/*
* 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -142,7 +142,7 @@ PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash,
}
// placeholder used to track class loading internal states
// placeholder is used to track class loading internal states
// placeholder existence now for loading superclass/superinterface
// superthreadQ tracks class circularity, while loading superclass/superinterface
// loadInstanceThreadQ tracks load_instance_class calls
......@@ -153,15 +153,17 @@ PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash,
// All claimants remove SeenThread after completing action
// On removal: if definer and all queues empty, remove entry
// Note: you can be in both placeholders and systemDictionary
// see parse_stream for redefine classes
// Therefore - must always check SD first
// Ignores the case where entry is not found
void PlaceholderTable::find_and_remove(int index, unsigned int hash,
Symbol* name, ClassLoaderData* loader_data, Thread* thread) {
Symbol* name, ClassLoaderData* loader_data,
classloadAction action,
Thread* thread) {
assert_locked_or_safepoint(SystemDictionary_lock);
PlaceholderEntry *probe = get_entry(index, hash, name, loader_data);
if (probe != NULL) {
// No other threads using this entry
probe->remove_seen_thread(thread, action);
// If no other threads using this entry, and this thread is not using this entry for other states
if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL)
&& (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)) {
remove_entry(index, hash, name, loader_data);
......
/*
* 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -82,7 +82,7 @@ public:
};
// find_and_add returns probe pointer - old or new
// If no entry exists, add a placeholder entry and push SeenThread
// If no entry exists, add a placeholder entry and push SeenThread for classloadAction
// If entry exists, reuse entry and push SeenThread for classloadAction
PlaceholderEntry* find_and_add(int index, unsigned int hash,
Symbol* name, ClassLoaderData* loader_data,
......@@ -92,9 +92,11 @@ public:
void remove_entry(int index, unsigned int hash,
Symbol* name, ClassLoaderData* loader_data);
// Remove placeholder information
// find_and_remove first removes SeenThread for classloadAction
// If all queues are empty and definer is null, remove the PlacheholderEntry completely
void find_and_remove(int index, unsigned int hash,
Symbol* name, ClassLoaderData* loader_data, Thread* thread);
Symbol* name, ClassLoaderData* loader_data,
classloadAction action, Thread* thread);
// GC support.
void classes_do(KlassClosure* f);
......
/*
* 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -172,7 +172,7 @@ Klass* SystemDictionary::handle_resolution_exception(Symbol* class_name, Handle
assert(klass_h() == NULL, "Should not have result with exception pending");
Handle e(THREAD, PENDING_EXCEPTION);
CLEAR_PENDING_EXCEPTION;
THROW_MSG_CAUSE_0(vmSymbols::java_lang_NoClassDefFoundError(), class_name->as_C_string(), e);
THROW_MSG_CAUSE_NULL(vmSymbols::java_lang_NoClassDefFoundError(), class_name->as_C_string(), e);
} else {
return NULL;
}
......@@ -181,9 +181,9 @@ Klass* SystemDictionary::handle_resolution_exception(Symbol* class_name, Handle
if (klass_h() == NULL) {
ResourceMark rm(THREAD);
if (throw_error) {
THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), class_name->as_C_string());
THROW_MSG_NULL(vmSymbols::java_lang_NoClassDefFoundError(), class_name->as_C_string());
} else {
THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), class_name->as_C_string());
THROW_MSG_NULL(vmSymbols::java_lang_ClassNotFoundException(), class_name->as_C_string());
}
}
return (Klass*)klass_h();
......@@ -343,29 +343,29 @@ Klass* SystemDictionary::resolve_super_or_fail(Symbol* child_name,
}
if (throw_circularity_error) {
ResourceMark rm(THREAD);
THROW_MSG_0(vmSymbols::java_lang_ClassCircularityError(), child_name->as_C_string());
THROW_MSG_NULL(vmSymbols::java_lang_ClassCircularityError(), child_name->as_C_string());
}
// java.lang.Object should have been found above
assert(class_name != NULL, "null super class for resolving");
// Resolve the super class or interface, check results on return
Klass* superk = NULL;
superk = SystemDictionary::resolve_or_null(class_name,
Klass* superk = SystemDictionary::resolve_or_null(class_name,
class_loader,
protection_domain,
THREAD);
KlassHandle superk_h(THREAD, superk);
// Note: clean up of placeholders currently in callers of
// resolve_super_or_fail - either at update_dictionary time
// or on error
// Clean up of placeholders moved so that each classloadAction registrar self-cleans up
// It is no longer necessary to keep the placeholder table alive until update_dictionary
// or error. GC used to walk the placeholder table as strong roots.
// The instanceKlass is kept alive because the class loader is on the stack,
// which keeps the loader_data alive, as well as all instanceKlasses in
// the loader_data. parseClassFile adds the instanceKlass to loader_data.
{
MutexLocker mu(SystemDictionary_lock, THREAD);
PlaceholderEntry* probe = placeholders()->get_entry(p_index, p_hash, child_name, loader_data);
if (probe != NULL) {
probe->remove_seen_thread(THREAD, PlaceholderTable::LOAD_SUPER);
}
MutexLocker mu(SystemDictionary_lock, THREAD);
placeholders()->find_and_remove(p_index, p_hash, child_name, loader_data, PlaceholderTable::LOAD_SUPER, THREAD);
SystemDictionary_lock->notify_all();
}
if (HAS_PENDING_EXCEPTION || superk_h() == NULL) {
// can null superk
......@@ -430,8 +430,8 @@ void SystemDictionary::validate_protection_domain(instanceKlassHandle klass,
// We're using a No_Safepoint_Verifier to catch any place where we
// might potentially do a GC at all.
// SystemDictionary::do_unloading() asserts that classes are only
// unloaded at a safepoint.
// Dictionary::do_unloading() asserts that classes in SD are only
// unloaded at a safepoint. Anonymous classes are not in SD.
No_Safepoint_Verifier nosafepoint;
dictionary()->add_protection_domain(d_index, d_hash, klass, loader_data,
protection_domain, THREAD);
......@@ -486,7 +486,6 @@ void SystemDictionary::double_lock_wait(Handle lockObject, TRAPS) {
// super class loading here.
// This also is critical in cases where the original thread gets stalled
// even in non-circularity situations.
// Note: only one thread can define the class, but multiple can resolve
// Note: must call resolve_super_or_fail even if null super -
// to force placeholder entry creation for this class for circularity detection
// Caller must check for pending exception
......@@ -518,14 +517,6 @@ instanceKlassHandle SystemDictionary::handle_parallel_super_load(
protection_domain,
true,
CHECK_(nh));
// We don't redefine the class, so we just need to clean up if there
// was not an error (don't want to modify any system dictionary
// data structures).
{
MutexLocker mu(SystemDictionary_lock, THREAD);
placeholders()->find_and_remove(p_index, p_hash, name, loader_data, THREAD);
SystemDictionary_lock->notify_all();
}
// parallelCapable class loaders do NOT wait for parallel superclass loads to complete
// Serial class loaders and bootstrap classloader do wait for superclass loads
......@@ -595,6 +586,10 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
// Do lookup to see if class already exist and the protection domain
// has the right access
// This call uses find which checks protection domain already matches
// All subsequent calls use find_class, and set has_loaded_class so that
// before we return a result we call out to java to check for valid protection domain
// to allow returning the Klass* and add it to the pd_set if it is valid
unsigned int d_hash = dictionary()->compute_hash(name, loader_data);
int d_index = dictionary()->hash_to_index(d_hash);
Klass* probe = dictionary()->find(d_index, d_hash, name, loader_data,
......@@ -652,7 +647,7 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
}
}
// If the class 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) {
k = SystemDictionary::handle_parallel_super_load(name, superclassname,
class_loader, protection_domain, lockObject, THREAD);
......@@ -664,7 +659,9 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
}
}
bool throw_circularity_error = false;
if (!class_has_been_loaded) {
bool load_instance_added = false;
// add placeholder entry to record loading instance class
// Five cases:
......@@ -690,7 +687,7 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
// No performance benefit and no deadlock issues.
// case 5. parallelCapable user level classloaders - without objectLocker
// Allow parallel classloading of a class/classloader pair
bool throw_circularity_error = false;
{
MutexLocker mu(SystemDictionary_lock, THREAD);
if (class_loader.is_null() || !is_parallelCapable(class_loader)) {
......@@ -726,12 +723,13 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
}
}
}
// All cases: add LOAD_INSTANCE
// All cases: add LOAD_INSTANCE holding SystemDictionary_lock
// case 3: UnsyncloadClass || case 5: parallelCapable: allow competing threads to try
// LOAD_INSTANCE in parallel
// add placeholder entry even if error - callers will remove on error
if (!throw_circularity_error && !class_has_been_loaded) {
PlaceholderEntry* newprobe = placeholders()->find_and_add(p_index, p_hash, name, loader_data, PlaceholderTable::LOAD_INSTANCE, NULL, THREAD);
load_instance_added = true;
// For class loaders that do not acquire the classloader object lock,
// if they did not catch another thread holding LOAD_INSTANCE,
// need a check analogous to the acquire ObjectLocker/find_class
......@@ -740,19 +738,18 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
// class loaders holding the ObjectLock shouldn't find the class here
Klass* check = find_class(d_index, d_hash, name, loader_data);
if (check != NULL) {
// Klass is already loaded, so just return it
// Klass is already loaded, so return it after checking/adding protection domain
k = instanceKlassHandle(THREAD, check);
class_has_been_loaded = true;
newprobe->remove_seen_thread(THREAD, PlaceholderTable::LOAD_INSTANCE);
placeholders()->find_and_remove(p_index, p_hash, name, loader_data, THREAD);
SystemDictionary_lock->notify_all();
}
}
}
// must throw error outside of owning lock
if (throw_circularity_error) {
assert(!HAS_PENDING_EXCEPTION && load_instance_added == false,"circularity error cleanup");
ResourceMark rm(THREAD);
THROW_MSG_0(vmSymbols::java_lang_ClassCircularityError(), name->as_C_string());
THROW_MSG_NULL(vmSymbols::java_lang_ClassCircularityError(), name->as_C_string());
}
if (!class_has_been_loaded) {
......@@ -782,20 +779,6 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
}
}
// clean up placeholder entries for success or error
// This cleans up LOAD_INSTANCE entries
// It also cleans up LOAD_SUPER entries on errors from
// calling load_instance_class
{
MutexLocker mu(SystemDictionary_lock, THREAD);
PlaceholderEntry* probe = placeholders()->get_entry(p_index, p_hash, name, loader_data);
if (probe != NULL) {
probe->remove_seen_thread(THREAD, PlaceholderTable::LOAD_INSTANCE);
placeholders()->find_and_remove(p_index, p_hash, name, loader_data, THREAD);
SystemDictionary_lock->notify_all();
}
}
// If everything was OK (no exceptions, no null return value), and
// class_loader is NOT the defining loader, do a little more bookkeeping.
if (!HAS_PENDING_EXCEPTION && !k.is_null() &&
......@@ -819,18 +802,22 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
}
}
}
if (HAS_PENDING_EXCEPTION || k.is_null()) {
// On error, clean up placeholders
{
MutexLocker mu(SystemDictionary_lock, THREAD);
placeholders()->find_and_remove(p_index, p_hash, name, loader_data, THREAD);
SystemDictionary_lock->notify_all();
}
return NULL;
}
} // load_instance_class loop
if (load_instance_added == true) {
// clean up placeholder entries for LOAD_INSTANCE success or error
// This brackets the SystemDictionary updates for both defining
// and initiating loaders
MutexLocker mu(SystemDictionary_lock, THREAD);
placeholders()->find_and_remove(p_index, p_hash, name, loader_data, PlaceholderTable::LOAD_INSTANCE, THREAD);
SystemDictionary_lock->notify_all();
}
}
if (HAS_PENDING_EXCEPTION || k.is_null()) {
return NULL;
}
#ifdef ASSERT
{
ClassLoaderData* loader_data = k->class_loader_data();
......@@ -850,8 +837,8 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle cla
// so we cannot allow GC to occur while we're holding this entry.
// We're using a No_Safepoint_Verifier to catch any place where we
// might potentially do a GC at all.
// SystemDictionary::do_unloading() asserts that classes are only
// unloaded at a safepoint.
// Dictionary::do_unloading() asserts that classes in SD are only
// unloaded at a safepoint. Anonymous classes are not in SD.
No_Safepoint_Verifier nosafepoint;
if (dictionary()->is_valid_protection_domain(d_index, d_hash, name,
loader_data,
......@@ -898,8 +885,8 @@ Klass* SystemDictionary::find(Symbol* class_name,
// so we cannot allow GC to occur while we're holding this entry.
// We're using a No_Safepoint_Verifier to catch any place where we
// might potentially do a GC at all.
// SystemDictionary::do_unloading() asserts that classes are only
// unloaded at a safepoint.
// Dictionary::do_unloading() asserts that classes in SD are only
// unloaded at a safepoint. Anonymous classes are not in SD.
No_Safepoint_Verifier nosafepoint;
return dictionary()->find(d_index, d_hash, class_name, loader_data,
protection_domain, THREAD);
......@@ -965,10 +952,6 @@ Klass* SystemDictionary::parse_stream(Symbol* class_name,
// throw potential ClassFormatErrors.
//
// Note: "name" is updated.
// Further note: a placeholder will be added for this class when
// super classes are loaded (resolve_super_or_fail). We expect this
// to be called for all classes but java.lang.Object; and we preload
// java.lang.Object through resolve_or_fail, not this path.
instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
loader_data,
......@@ -979,21 +962,6 @@ Klass* SystemDictionary::parse_stream(Symbol* class_name,
true,
THREAD);
// We don't redefine the class, so we just need to clean up whether there
// was an error or not (don't want to modify any system dictionary
// data structures).
// Parsed name could be null if we threw an error before we got far
// enough along to parse it -- in that case, there is nothing to clean up.
if (parsed_name != NULL) {
unsigned int p_hash = placeholders()->compute_hash(parsed_name,
loader_data);
int p_index = placeholders()->hash_to_index(p_hash);
{
MutexLocker mu(SystemDictionary_lock, THREAD);
placeholders()->find_and_remove(p_index, p_hash, parsed_name, loader_data, THREAD);
SystemDictionary_lock->notify_all();
}
}
if (host_klass.not_null() && k.not_null()) {
assert(EnableInvokeDynamic, "");
......@@ -1062,10 +1030,6 @@ Klass* SystemDictionary::resolve_from_stream(Symbol* class_name,
// throw potential ClassFormatErrors.
//
// Note: "name" is updated.
// Further note: a placeholder will be added for this class when
// super classes are loaded (resolve_super_or_fail). We expect this
// to be called for all classes but java.lang.Object; and we preload
// java.lang.Object through resolve_or_fail, not this path.
instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
loader_data,
......@@ -1114,25 +1078,7 @@ Klass* SystemDictionary::resolve_from_stream(Symbol* class_name,
}
}
// If parsing the class file or define_instance_class failed, we
// need to remove the placeholder added on our behalf. But we
// must make sure parsed_name is valid first (it won't be if we had
// a format error before the class was parsed far enough to
// find the name).
if (HAS_PENDING_EXCEPTION && parsed_name != NULL) {
unsigned int p_hash = placeholders()->compute_hash(parsed_name,
loader_data);
int p_index = placeholders()->hash_to_index(p_hash);
{
MutexLocker mu(SystemDictionary_lock, THREAD);
placeholders()->find_and_remove(p_index, p_hash, parsed_name, loader_data, THREAD);
SystemDictionary_lock->notify_all();
}
return NULL;
}
// Make sure that we didn't leave a place holder in the
// SystemDictionary; this is only done on success
// Make sure we have an entry in the SystemDictionary on success
debug_only( {
if (!HAS_PENDING_EXCEPTION) {
assert(parsed_name != NULL, "parsed_name is still null?");
......@@ -1547,8 +1493,7 @@ instanceKlassHandle SystemDictionary::find_or_define_instance_class(Symbol* clas
// Other cases fall through, and may run into duplicate defines
// caught by finding an entry in the SystemDictionary
if ((UnsyncloadClass || is_parallelDefine(class_loader)) && (probe->instance_klass() != NULL)) {
probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS);
placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, THREAD);
placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, THREAD);
SystemDictionary_lock->notify_all();
#ifdef ASSERT
Klass* check = find_class(d_index, d_hash, name_h, loader_data);
......@@ -1578,8 +1523,7 @@ instanceKlassHandle SystemDictionary::find_or_define_instance_class(Symbol* clas
probe->set_instance_klass(k());
}
probe->set_definer(NULL);
probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS);
placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, THREAD);
placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, THREAD);
SystemDictionary_lock->notify_all();
}
}
......@@ -1736,6 +1680,8 @@ int SystemDictionary::calculate_systemdictionary_size(int classcount) {
}
return newsize;
}
// Assumes classes in the SystemDictionary are only unloaded at a safepoint
// Note: anonymous classes are not in the SD.
bool SystemDictionary::do_unloading(BoolObjectClosure* is_alive) {
// First, mark for unload all ClassLoaderData referencing a dead class loader.
bool has_dead_loaders = ClassLoaderDataGraph::do_unloading(is_alive);
......@@ -2105,9 +2051,7 @@ void SystemDictionary::update_dictionary(int d_index, unsigned int d_hash,
// All loaded classes get a unique ID.
TRACE_INIT_ID(k);
// Check for a placeholder. If there, remove it and make a
// new system dictionary entry.
placeholders()->find_and_remove(p_index, p_hash, name, loader_data, THREAD);
// Make a new system dictionary entry.
Klass* sd_check = find_class(d_index, d_hash, name, loader_data);
if (sd_check == NULL) {
dictionary()->add_klass(name, loader_data, k);
......@@ -2116,12 +2060,8 @@ void SystemDictionary::update_dictionary(int d_index, unsigned int d_hash,
#ifdef ASSERT
sd_check = find_class(d_index, d_hash, name, loader_data);
assert (sd_check != NULL, "should have entry in system dictionary");
// Changed to allow PH to remain to complete class circularity checking
// while only one thread can define a class at one time, multiple
// classes can resolve the superclass for a class at one time,
// and the placeholder is used to track that
// Symbol* ph_check = find_placeholder(name, class_loader);
// assert (ph_check == NULL, "should not have a placeholder entry");
// Note: there may be a placeholder entry: for circularity testing
// or for parallel defines
#endif
SystemDictionary_lock->notify_all();
}
......
......@@ -194,7 +194,10 @@
template(java_lang_VirtualMachineError, "java/lang/VirtualMachineError") \
template(java_lang_StackOverflowError, "java/lang/StackOverflowError") \
template(java_lang_StackTraceElement, "java/lang/StackTraceElement") \
\
/* Concurrency support */ \
template(java_util_concurrent_locks_AbstractOwnableSynchronizer, "java/util/concurrent/locks/AbstractOwnableSynchronizer") \
template(sun_misc_Contended_signature, "Lsun/misc/Contended;") \
\
/* class symbols needed by intrinsics */ \
VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, template, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE) \
......@@ -284,7 +287,7 @@
NOT_LP64( do_alias(intptr_signature, int_signature) ) \
LP64_ONLY( do_alias(intptr_signature, long_signature) ) \
template(selectAlternative_signature, "(ZLjava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;") \
\
\
/* common method and field names */ \
template(object_initializer_name, "<init>") \
template(class_initializer_name, "<clinit>") \
......
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -373,17 +373,44 @@ void VM_PopulateDumpSharedSpace::doit() {
md_top = wc.get_top();
// Print shared spaces all the time
const char* fmt = "%s space: " PTR_FORMAT " out of " PTR_FORMAT " words allocated at " PTR_FORMAT ".";
const char* fmt = "%s space: %9d [ %4.1f%% of total] out of %9d bytes [%4.1f%% used] at " PTR_FORMAT;
Metaspace* ro_space = _loader_data->ro_metaspace();
Metaspace* rw_space = _loader_data->rw_metaspace();
tty->print_cr(fmt, "ro", ro_space->used_words(Metaspace::NonClassType),
ro_space->capacity_words(Metaspace::NonClassType),
ro_space->bottom());
tty->print_cr(fmt, "rw", rw_space->used_words(Metaspace::NonClassType),
rw_space->capacity_words(Metaspace::NonClassType),
rw_space->bottom());
tty->print_cr(fmt, "md", md_top - md_low, md_end-md_low, md_low);
tty->print_cr(fmt, "mc", mc_top - mc_low, mc_end-mc_low, mc_low);
const size_t BPW = BytesPerWord;
// Allocated size of each space (may not be all occupied)
const size_t ro_alloced = ro_space->capacity_words(Metaspace::NonClassType) * BPW;
const size_t rw_alloced = rw_space->capacity_words(Metaspace::NonClassType) * BPW;
const size_t md_alloced = md_end-md_low;
const size_t mc_alloced = mc_end-mc_low;
const size_t total_alloced = ro_alloced + rw_alloced + md_alloced + mc_alloced;
// Occupied size of each space.
const size_t ro_bytes = ro_space->used_words(Metaspace::NonClassType) * BPW;
const size_t rw_bytes = rw_space->used_words(Metaspace::NonClassType) * BPW;
const size_t md_bytes = size_t(md_top - md_low);
const size_t mc_bytes = size_t(mc_top - mc_low);
// Percent of total size
const size_t total_bytes = ro_bytes + rw_bytes + md_bytes + mc_bytes;
const double ro_t_perc = ro_bytes / double(total_bytes) * 100.0;
const double rw_t_perc = rw_bytes / double(total_bytes) * 100.0;
const double md_t_perc = md_bytes / double(total_bytes) * 100.0;
const double mc_t_perc = mc_bytes / double(total_bytes) * 100.0;
// Percent of fullness of each space
const double ro_u_perc = ro_bytes / double(ro_alloced) * 100.0;
const double rw_u_perc = rw_bytes / double(rw_alloced) * 100.0;
const double md_u_perc = md_bytes / double(md_alloced) * 100.0;
const double mc_u_perc = mc_bytes / double(mc_alloced) * 100.0;
const double total_u_perc = total_bytes / double(total_alloced) * 100.0;
tty->print_cr(fmt, "ro", ro_bytes, ro_t_perc, ro_alloced, ro_u_perc, ro_space->bottom());
tty->print_cr(fmt, "rw", rw_bytes, rw_t_perc, rw_alloced, rw_u_perc, rw_space->bottom());
tty->print_cr(fmt, "md", md_bytes, md_t_perc, md_alloced, md_u_perc, md_low);
tty->print_cr(fmt, "mc", mc_bytes, mc_t_perc, mc_alloced, mc_u_perc, mc_low);
tty->print_cr("total : %9d [100.0%% of total] out of %9d bytes [%4.1f%% used]",
total_bytes, total_alloced, total_u_perc);
// Update the vtable pointers in all of the Klass objects in the
// heap. They should point to newly generated vtable.
......
......@@ -122,7 +122,12 @@ class ExceptionTableElement VALUE_OBJ_CLASS_SPEC {
class MethodParametersElement VALUE_OBJ_CLASS_SPEC {
public:
u2 name_cp_index;
u4 flags;
// This has to happen, otherwise it will cause SIGBUS from a
// misaligned u4 on some architectures (ie SPARC)
// because MethodParametersElements are only aligned mod 2
// within the ConstMethod container u2 flags_hi;
u2 flags_hi;
u2 flags_lo;
};
......
......@@ -43,14 +43,29 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC {
public:
// fields
// Field info extracted from the class file and stored
// as an array of 7 shorts
// as an array of 6 shorts.
#define FIELDINFO_TAG_SIZE 2
#define FIELDINFO_TAG_BLANK 0
#define FIELDINFO_TAG_OFFSET 1
#define FIELDINFO_TAG_TYPE_PLAIN 2
#define FIELDINFO_TAG_TYPE_CONTENDED 3
#define FIELDINFO_TAG_MASK 3
// Packed field has the tag, and can be either of:
// hi bits <--------------------------- lo bits
// |---------high---------|---------low---------|
// ..........................................00 - blank
// [------------------offset----------------]01 - real field offset
// ......................[-------type-------]10 - plain field with type
// [--contention_group--][-------type-------]11 - contended field with type and contention group
enum FieldOffset {
access_flags_offset = 0,
name_index_offset = 1,
signature_index_offset = 2,
initval_index_offset = 3,
low_offset = 4,
high_offset = 5,
low_packed_offset = 4,
high_packed_offset = 5,
field_slots = 6
};
......@@ -76,17 +91,90 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC {
void initialize(u2 access_flags,
u2 name_index,
u2 signature_index,
u2 initval_index,
u4 offset) {
u2 initval_index) {
_shorts[access_flags_offset] = access_flags;
_shorts[name_index_offset] = name_index;
_shorts[signature_index_offset] = signature_index;
_shorts[initval_index_offset] = initval_index;
set_offset(offset);
_shorts[low_packed_offset] = 0;
_shorts[high_packed_offset] = 0;
}
u2 access_flags() const { return _shorts[access_flags_offset]; }
u4 offset() const { return build_int_from_shorts(_shorts[low_offset], _shorts[high_offset]); }
u4 offset() const {
u2 lo = _shorts[low_packed_offset];
switch(lo & FIELDINFO_TAG_MASK) {
case FIELDINFO_TAG_OFFSET:
return build_int_from_shorts(_shorts[low_packed_offset], _shorts[high_packed_offset]) >> FIELDINFO_TAG_SIZE;
#ifndef PRODUCT
case FIELDINFO_TAG_TYPE_PLAIN:
ShouldNotReachHere2("Asking offset for the plain type field");
case FIELDINFO_TAG_TYPE_CONTENDED:
ShouldNotReachHere2("Asking offset for the contended type field");
case FIELDINFO_TAG_BLANK:
ShouldNotReachHere2("Asking offset for the blank field");
#endif
}
ShouldNotReachHere();
return 0;
}
bool is_contended() const {
u2 lo = _shorts[low_packed_offset];
switch(lo & FIELDINFO_TAG_MASK) {
case FIELDINFO_TAG_TYPE_PLAIN:
return false;
case FIELDINFO_TAG_TYPE_CONTENDED:
return true;
#ifndef PRODUCT
case FIELDINFO_TAG_OFFSET:
ShouldNotReachHere2("Asking contended flag for the field with offset");
case FIELDINFO_TAG_BLANK:
ShouldNotReachHere2("Asking contended flag for the blank field");
#endif
}
ShouldNotReachHere();
return false;
}
u2 contended_group() const {
u2 lo = _shorts[low_packed_offset];
switch(lo & FIELDINFO_TAG_MASK) {
case FIELDINFO_TAG_TYPE_PLAIN:
return 0;
case FIELDINFO_TAG_TYPE_CONTENDED:
return _shorts[high_packed_offset];
#ifndef PRODUCT
case FIELDINFO_TAG_OFFSET:
ShouldNotReachHere2("Asking the contended group for the field with offset");
case FIELDINFO_TAG_BLANK:
ShouldNotReachHere2("Asking the contended group for the blank field");
#endif
}
ShouldNotReachHere();
return 0;
}
u2 allocation_type() const {
u2 lo = _shorts[low_packed_offset];
switch(lo & FIELDINFO_TAG_MASK) {
case FIELDINFO_TAG_TYPE_PLAIN:
case FIELDINFO_TAG_TYPE_CONTENDED:
return (lo >> FIELDINFO_TAG_SIZE);
#ifndef PRODUCT
case FIELDINFO_TAG_OFFSET:
ShouldNotReachHere2("Asking the field type for field with offset");
case FIELDINFO_TAG_BLANK:
ShouldNotReachHere2("Asking the field type for the blank field");
#endif
}
ShouldNotReachHere();
return 0;
}
bool is_offset_set() const {
return (_shorts[low_packed_offset] & FIELDINFO_TAG_MASK) == FIELDINFO_TAG_OFFSET;
}
Symbol* name(constantPoolHandle cp) const {
int index = name_index();
......@@ -106,8 +194,46 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC {
void set_access_flags(u2 val) { _shorts[access_flags_offset] = val; }
void set_offset(u4 val) {
_shorts[low_offset] = extract_low_short_from_int(val);
_shorts[high_offset] = extract_high_short_from_int(val);
val = val << FIELDINFO_TAG_SIZE; // make room for tag
_shorts[low_packed_offset] = extract_low_short_from_int(val) | FIELDINFO_TAG_OFFSET;
_shorts[high_packed_offset] = extract_high_short_from_int(val);
}
void set_allocation_type(int type) {
u2 lo = _shorts[low_packed_offset];
switch(lo & FIELDINFO_TAG_MASK) {
case FIELDINFO_TAG_BLANK:
_shorts[low_packed_offset] = ((type << FIELDINFO_TAG_SIZE)) & 0xFFFF;
_shorts[low_packed_offset] &= ~FIELDINFO_TAG_MASK;
_shorts[low_packed_offset] |= FIELDINFO_TAG_TYPE_PLAIN;
return;
#ifndef PRODUCT
case FIELDINFO_TAG_TYPE_PLAIN:
case FIELDINFO_TAG_TYPE_CONTENDED:
case FIELDINFO_TAG_OFFSET:
ShouldNotReachHere2("Setting the field type with overwriting");
#endif
}
ShouldNotReachHere();
}
void set_contended_group(u2 val) {
u2 lo = _shorts[low_packed_offset];
switch(lo & FIELDINFO_TAG_MASK) {
case FIELDINFO_TAG_TYPE_PLAIN:
_shorts[low_packed_offset] |= FIELDINFO_TAG_TYPE_CONTENDED;
_shorts[high_packed_offset] = val;
return;
#ifndef PRODUCT
case FIELDINFO_TAG_TYPE_CONTENDED:
ShouldNotReachHere2("Overwriting contended group");
case FIELDINFO_TAG_BLANK:
ShouldNotReachHere2("Setting contended group for the blank field");
case FIELDINFO_TAG_OFFSET:
ShouldNotReachHere2("Setting contended group for field with offset");
#endif
}
ShouldNotReachHere();
}
bool is_internal() const {
......
......@@ -160,9 +160,26 @@ class FieldStreamBase : public StackObj {
return field()->offset();
}
int allocation_type() const {
return field()->allocation_type();
}
void set_offset(int offset) {
field()->set_offset(offset);
}
bool is_offset_set() const {
return field()->is_offset_set();
}
bool is_contended() const {
return field()->is_contended();
}
int contended_group() const {
return field()->contended_group();
}
};
// Iterate over only the internal fields
......
......@@ -230,7 +230,8 @@ class InstanceKlass: public Klass {
_misc_rewritten = 1 << 0, // methods rewritten.
_misc_has_nonstatic_fields = 1 << 1, // for sizing with UseCompressedOops
_misc_should_verify_class = 1 << 2, // allow caching of preverification
_misc_is_anonymous = 1 << 3 // has embedded _inner_classes field
_misc_is_anonymous = 1 << 3, // has embedded _inner_classes field
_misc_is_contended = 1 << 4 // marked with contended annotation
};
u2 _misc_flags;
u2 _minor_version; // minor version number of class file
......@@ -550,6 +551,17 @@ class InstanceKlass: public Klass {
return is_anonymous() ? java_mirror() : class_loader();
}
bool is_contended() const {
return (_misc_flags & _misc_is_contended) != 0;
}
void set_is_contended(bool value) {
if (value) {
_misc_flags |= _misc_is_contended;
} else {
_misc_flags &= ~_misc_is_contended;
}
}
// signers
objArrayOop signers() const { return _signers; }
void set_signers(objArrayOop s) { klass_oop_store((oop*)&_signers, s); }
......
......@@ -1589,6 +1589,12 @@ JVM_ENTRY(jbyteArray, JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls))
return NULL;
JVM_END
static void bounds_check(constantPoolHandle cp, jint index, TRAPS) {
if (!cp->is_within_bounds(index)) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Constant pool index out of bounds");
}
}
JVM_ENTRY(jobjectArray, JVM_GetMethodParameters(JNIEnv *env, jobject method))
{
JVMWrapper("JVM_GetMethodParameters");
......@@ -1598,15 +1604,31 @@ JVM_ENTRY(jobjectArray, JVM_GetMethodParameters(JNIEnv *env, jobject method))
Handle reflected_method (THREAD, JNIHandles::resolve_non_null(method));
const int num_params = mh->method_parameters_length();
if(0 != num_params) {
if (0 != num_params) {
// make sure all the symbols are properly formatted
for (int i = 0; i < num_params; i++) {
MethodParametersElement* params = mh->method_parameters_start();
int index = params[i].name_cp_index;
bounds_check(mh->constants(), index, CHECK_NULL);
if (0 != index && !mh->constants()->tag_at(index).is_utf8()) {
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
"Wrong type at constant pool index");
}
}
objArrayOop result_oop = oopFactory::new_objArray(SystemDictionary::reflect_Parameter_klass(), num_params, CHECK_NULL);
objArrayHandle result (THREAD, result_oop);
for(int i = 0; i < num_params; i++) {
for (int i = 0; i < num_params; i++) {
MethodParametersElement* params = mh->method_parameters_start();
Symbol* const sym = mh->constants()->symbol_at(params[i].name_cp_index);
// For a 0 index, give a NULL symbol
Symbol* const sym = 0 != params[i].name_cp_index ?
mh->constants()->symbol_at(params[i].name_cp_index) : NULL;
int flags = build_int_from_shorts(params[i].flags_lo, params[i].flags_hi);
oop param = Reflection::new_parameter(reflected_method, i, sym,
params[i].flags, CHECK_NULL);
flags, CHECK_NULL);
result->obj_at_put(i, param);
}
return (jobjectArray)JNIHandles::make_local(env, result());
......@@ -1830,13 +1852,6 @@ JVM_ENTRY(jint, JVM_ConstantPoolGetSize(JNIEnv *env, jobject obj, jobject unused
JVM_END
static void bounds_check(constantPoolHandle cp, jint index, TRAPS) {
if (!cp->is_within_bounds(index)) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Constant pool index out of bounds");
}
}
JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject obj, jobject unused, jint index))
{
JVMWrapper("JVM_ConstantPoolGetClassAt");
......@@ -1851,7 +1866,6 @@ JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject obj, jobject u
}
JVM_END
JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAtIfLoaded(JNIEnv *env, jobject obj, jobject unused, jint index))
{
JVMWrapper("JVM_ConstantPoolGetClassAtIfLoaded");
......
......@@ -1075,7 +1075,7 @@ class CommandLineFlags {
\
product(intx, ClearFPUAtPark, 0, "(Unsafe,Unstable)" ) \
\
product(intx, hashCode, 0, \
product(intx, hashCode, 5, \
"(Unstable) select hashCode generation algorithm" ) \
\
product(intx, WorkAroundNPTLTimedWaitHang, 1, \
......@@ -1166,6 +1166,18 @@ class CommandLineFlags {
notproduct(bool, PrintCompactFieldsSavings, false, \
"Print how many words were saved with CompactFields") \
\
notproduct(bool, PrintFieldLayout, false, \
"Print field layout for each class") \
\
product(intx, ContendedPaddingWidth, 128, \
"How many bytes to pad the fields/classes marked @Contended with")\
\
product(bool, EnableContended, true, \
"Enable @Contended annotation support") \
\
product(bool, RestrictContended, true, \
"Restrict @Contended to trusted classes") \
\
product(bool, UseBiasedLocking, true, \
"Enable biased locking in JVM") \
\
......
......@@ -542,6 +542,10 @@ void before_exit(JavaThread * thread) {
BeforeExit_lock->notify_all();
}
// Shutdown NMT before exit. Otherwise,
// it will run into trouble when system destroys static variables.
MemTracker::shutdown(MemTracker::NMT_normal);
#undef BEFORE_EXIT_NOT_RUN
#undef BEFORE_EXIT_RUNNING
#undef BEFORE_EXIT_DONE
......
......@@ -862,7 +862,15 @@ oop Reflection::new_field(fieldDescriptor* fd, bool intern_name, TRAPS) {
oop Reflection::new_parameter(Handle method, int index, Symbol* sym,
int flags, TRAPS) {
Handle name = java_lang_String::create_from_symbol(sym, CHECK_NULL);
Handle name;
// A null symbol here translates to the empty string
if(NULL != sym) {
name = java_lang_String::create_from_symbol(sym, CHECK_NULL);
} else {
name = java_lang_String::create_from_str("", CHECK_NULL);
}
Handle rh = java_lang_reflect_Parameter::create(CHECK_NULL);
java_lang_reflect_Parameter::set_name(rh(), name());
java_lang_reflect_Parameter::set_modifiers(rh(), flags);
......
......@@ -4011,10 +4011,6 @@ bool Threads::destroy_vm() {
Mutex::_as_suspend_equivalent_flag);
}
// Shutdown NMT before exit. Otherwise,
// it will run into trouble when system destroys static variables.
MemTracker::shutdown(MemTracker::NMT_normal);
// Hang forever on exit if we are reporting an error.
if (ShowMessageBoxOnError && is_error_reported()) {
os::infinite_sleep();
......
此差异已折叠。
/*
* 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -267,6 +267,7 @@ class Exceptions {
#define THROW_WRAPPED_0(name, oop_to_wrap) THROW_WRAPPED_(name, oop_to_wrap, 0)
#define THROW_ARG_0(name, signature, arg) THROW_ARG_(name, signature, arg, 0)
#define THROW_MSG_CAUSE_0(name, message, cause) THROW_MSG_CAUSE_(name, message, cause, 0)
#define THROW_MSG_CAUSE_NULL(name, message, cause) THROW_MSG_CAUSE_(name, message, cause, NULL)
#define THROW_NULL(name) THROW_(name, NULL)
#define THROW_MSG_NULL(name, message) THROW_MSG_(name, message, NULL)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册