This commit is contained in:
Alejandro Murillo 2013-01-18 05:19:06 -08:00
commit 6e59c39db8
70 changed files with 1422 additions and 791 deletions

View File

@ -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

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2006, 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
@ -31,11 +31,11 @@
#
# Don't put quotes (fail windows build).
HOTSPOT_VM_COPYRIGHT=Copyright 2012
HOTSPOT_VM_COPYRIGHT=Copyright 2013
HS_MAJOR_VER=25
HS_MINOR_VER=0
HS_BUILD_NUMBER=15
HS_BUILD_NUMBER=16
JDK_MAJOR_VER=1
JDK_MINOR_VER=8

View File

@ -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

View File

@ -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
}

View File

@ -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) */
volatile_nonstatic_field(JavaFrameAnchor, _last_Java_fp, intptr_t*)
#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_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_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) \
/* 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_X86_VM_VMSTRUCTS_X86_HPP

View File

@ -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
}

View File

@ -98,10 +98,20 @@ BasicObjectLock* frame::interpreter_frame_monitor_end() const {
#endif // CC_INTERP
void frame::patch_pc(Thread* thread, address pc) {
// We borrow this call to set the thread pointer in the interpreter
// state; the hook to set up deoptimized frames isn't supplied it.
assert(pc == NULL, "should be");
get_interpreterState()->set_thread((JavaThread *) thread);
if (pc != NULL) {
_cb = CodeCache::find_blob(pc);
SharkFrame* sharkframe = zeroframe()->as_shark_frame();
sharkframe->set_pc(pc);
_pc = pc;
_deopt_state = is_deoptimized;
} else {
// We borrow this call to set the thread pointer in the interpreter
// state; the hook to set up deoptimized frames isn't supplied it.
assert(pc == NULL, "should be");
get_interpreterState()->set_thread((JavaThread *) thread);
}
}
bool frame::safe_for_sender(JavaThread *thread) {

View File

@ -45,27 +45,36 @@ inline frame::frame(ZeroFrame* zf, intptr_t* sp) {
case ZeroFrame::ENTRY_FRAME:
_pc = StubRoutines::call_stub_return_pc();
_cb = NULL;
_deopt_state = not_deoptimized;
break;
case ZeroFrame::INTERPRETER_FRAME:
_pc = NULL;
_cb = NULL;
_deopt_state = not_deoptimized;
break;
case ZeroFrame::SHARK_FRAME:
case ZeroFrame::SHARK_FRAME: {
_pc = zero_sharkframe()->pc();
_cb = CodeCache::find_blob_unsafe(pc());
address original_pc = nmethod::get_deopt_original_pc(this);
if (original_pc != NULL) {
_pc = original_pc;
_deopt_state = is_deoptimized;
} else {
_deopt_state = not_deoptimized;
}
break;
}
case ZeroFrame::FAKE_STUB_FRAME:
_pc = NULL;
_cb = NULL;
_deopt_state = not_deoptimized;
break;
default:
ShouldNotReachHere();
}
_deopt_state = not_deoptimized;
}
// Accessors

View File

@ -68,6 +68,10 @@ class SharkFrame : public ZeroFrame {
return (address) value_of_word(pc_off);
}
void set_pc(address pc) const {
*((address*) addr_of_word(pc_off)) = pc;
}
intptr_t* unextended_sp() const {
return (intptr_t *) value_of_word(unextended_sp_off);
}

View File

@ -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

View File

@ -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;

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -3223,7 +3223,12 @@ bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known, Bytecodes::Co
}
if (try_inline_full(callee, holder_known, bc, receiver))
return true;
print_inlining(callee, _inline_bailout_msg, /*success*/ false);
// Entire compilation could fail during try_inline_full call.
// In that case printing inlining decision info is useless.
if (!bailed_out())
print_inlining(callee, _inline_bailout_msg, /*success*/ false);
return false;
}
@ -3753,7 +3758,8 @@ bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, Bytecode
push_scope(callee, cont);
// the BlockListBuilder for the callee could have bailed out
CHECK_BAILOUT_(false);
if (bailed_out())
return false;
// Temporarily set up bytecode stream so we can append instructions
// (only using the bci of this stream)
@ -3819,7 +3825,8 @@ bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, Bytecode
iterate_all_blocks(callee_start_block == NULL);
// If we bailed out during parsing, return immediately (this is bad news)
if (bailed_out()) return false;
if (bailed_out())
return false;
// iterate_all_blocks theoretically traverses in random order; in
// practice, we have only traversed the continuation if we are
@ -3828,9 +3835,6 @@ bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, Bytecode
!continuation()->is_set(BlockBegin::was_visited_flag),
"continuation should not have been parsed yet if we created it");
// If we bailed out during parsing, return immediately (this is bad news)
CHECK_BAILOUT_(false);
// At this point we are almost ready to return and resume parsing of
// the caller back in the GraphBuilder. The only thing we want to do
// first is an optimization: during parsing of the callee we
@ -4171,7 +4175,10 @@ void GraphBuilder::print_inlining(ciMethod* callee, const char* msg, bool succes
else
log->inline_success("receiver is statically known");
} else {
log->inline_fail(msg);
if (msg != NULL)
log->inline_fail(msg);
else
log->inline_fail("reason unknown");
}
}

View File

@ -147,7 +147,7 @@
"Inline methods containing exception handlers " \
"(NOTE: does not work with current backend)") \
\
develop(bool, InlineSynchronizedMethods, true, \
product(bool, InlineSynchronizedMethods, true, \
"Inline synchronized methods") \
\
develop(bool, InlineNIOCheckIndex, true, \

View File

@ -59,6 +59,19 @@ bool ciType::is_subtype_of(ciType* type) {
return false;
}
// ------------------------------------------------------------------
// ciType::name
//
// Return the name of this type
const char* ciType::name() {
if (is_primitive_type()) {
return type2name(basic_type());
} else {
assert(is_klass(), "must be");
return as_klass()->name()->as_utf8();
}
}
// ------------------------------------------------------------------
// ciType::print_impl
//
@ -73,7 +86,8 @@ void ciType::print_impl(outputStream* st) {
//
// Print the name of this type
void ciType::print_name_on(outputStream* st) {
st->print(type2name(basic_type()));
ResourceMark rm;
st->print(name());
}

View File

@ -77,6 +77,7 @@ public:
bool is_type() const { return true; }
bool is_classless() const { return is_primitive_type(); }
const char* name();
virtual void print_name_on(outputStream* st);
void print_name() {
print_name_on(tty);

View File

@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@ -59,6 +59,7 @@
#include "services/classLoadingService.hpp"
#include "services/threadService.hpp"
#include "utilities/array.hpp"
#include "utilities/globalDefinitions.hpp"
// We generally try to create the oops directly when parsing, rather than
// allocating temporary data structures and copying the bytes twice. A
@ -970,6 +971,12 @@ void ClassFileParser::parse_field_attributes(ClassLoaderData* loader_data,
runtime_visible_annotations_length = attribute_length;
runtime_visible_annotations = cfs->get_u1_buffer();
assert(runtime_visible_annotations != NULL, "null visible annotations");
parse_annotations(loader_data,
runtime_visible_annotations,
runtime_visible_annotations_length,
cp,
parsed_annotations,
CHECK);
cfs->skip_u1(runtime_visible_annotations_length, CHECK);
} else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
runtime_invisible_annotations_length = attribute_length;
@ -1216,19 +1223,16 @@ Array<u2>* ClassFileParser::parse_fields(ClassLoaderData* loader_data,
field->initialize(access_flags.as_short(),
name_index,
signature_index,
constantvalue_index,
0);
if (parsed_annotations.has_any_annotations())
parsed_annotations.apply_to(field);
constantvalue_index);
BasicType type = cp->basic_type_for_signature_at(signature_index);
// Remember how many oops we encountered and compute allocation type
FieldAllocationType atype = fac->update(is_static, type);
field->set_allocation_type(atype);
// The correct offset is computed later (all oop fields will be located together)
// We temporarily store the allocation type in the offset field
field->set_offset(atype);
// After field is initialized with type, we can augment it with aux info
if (parsed_annotations.has_any_annotations())
parsed_annotations.apply_to(field);
}
int index = length;
@ -1259,17 +1263,13 @@ Array<u2>* ClassFileParser::parse_fields(ClassLoaderData* loader_data,
field->initialize(JVM_ACC_FIELD_INTERNAL,
injected[n].name_index,
injected[n].signature_index,
0,
0);
BasicType type = FieldType::basic_type(injected[n].signature());
// Remember how many oops we encountered and compute allocation type
FieldAllocationType atype = fac->update(false, type);
// The correct offset is computed later (all oop fields will be located together)
// We temporarily store the allocation type in the offset field
field->set_offset(atype);
field->set_allocation_type(atype);
index++;
}
}
@ -1735,7 +1735,8 @@ int ClassFileParser::skip_annotation_value(u1* buffer, int limit, int index) {
}
// Sift through annotations, looking for those significant to the VM:
void ClassFileParser::parse_annotations(u1* buffer, int limit,
void ClassFileParser::parse_annotations(ClassLoaderData* loader_data,
u1* buffer, int limit,
constantPoolHandle cp,
ClassFileParser::AnnotationCollector* coll,
TRAPS) {
@ -1752,9 +1753,12 @@ void ClassFileParser::parse_annotations(u1* buffer, int limit,
e_type_off = 7, // utf8 such as 'Ljava/lang/annotation/RetentionPolicy;'
e_con_off = 9, // utf8 payload, such as 'SOURCE', 'CLASS', 'RUNTIME'
e_size = 11, // end of 'e' annotation
c_tag_val = 'c',
c_con_off = 7, // utf8 payload, such as 'I' or 'Ljava/lang/String;'
c_tag_val = 'c', // payload is type
c_con_off = 7, // utf8 payload, such as 'I'
c_size = 9, // end of 'c' annotation
s_tag_val = 's', // payload is String
s_con_off = 7, // utf8 payload, such as 'Ljava/lang/String;'
s_size = 9,
min_size = 6 // smallest possible size (zero members)
};
while ((--nann) >= 0 && (index-2 + min_size <= limit)) {
@ -1773,57 +1777,65 @@ void ClassFileParser::parse_annotations(u1* buffer, int limit,
}
// Here is where parsing particular annotations will take place.
AnnotationCollector::ID id = coll->annotation_index(aname);
AnnotationCollector::ID id = coll->annotation_index(loader_data, aname);
if (id == AnnotationCollector::_unknown) continue;
coll->set_annotation(id);
// If there are no values, just set the bit and move on:
if (count == 0) continue;
// For the record, here is how annotation payloads can be collected.
// Suppose we want to capture @Retention.value. Here is how:
//if (id == AnnotationCollector::_class_Retention) {
// Symbol* payload = NULL;
// if (count == 1
// && e_size == (index0 - index) // match size
// && e_tag_val == *(abase + tag_off)
// && (check_symbol_at(cp, Bytes::get_Java_u2(abase + e_type_off))
// == vmSymbols::RetentionPolicy_signature())
// && member == vmSymbols::value_name()) {
// payload = check_symbol_at(cp, Bytes::get_Java_u2(abase + e_con_off));
// }
// check_property(payload != NULL,
// "Invalid @Retention annotation at offset %u in class file %s",
// index0, CHECK);
// if (payload != NULL) {
// payload->increment_refcount();
// coll->_class_RetentionPolicy = payload;
// }
//}
if (id == AnnotationCollector::_sun_misc_Contended) {
if (count == 1
&& s_size == (index - index0) // match size
&& s_tag_val == *(abase + tag_off)
&& member == vmSymbols::value_name()) {
u2 group_index = Bytes::get_Java_u2(abase + s_con_off);
coll->set_contended_group(group_index);
} else {
coll->set_contended_group(0); // default contended group
}
coll->set_contended(true);
} else {
coll->set_contended(false);
}
}
}
ClassFileParser::AnnotationCollector::ID ClassFileParser::AnnotationCollector::annotation_index(Symbol* name) {
ClassFileParser::AnnotationCollector::ID
ClassFileParser::AnnotationCollector::annotation_index(ClassLoaderData* loader_data,
Symbol* name) {
vmSymbols::SID sid = vmSymbols::find_sid(name);
bool privileged = false;
if (loader_data->is_the_null_class_loader_data()) {
// Privileged code can use all annotations. Other code silently drops some.
privileged = true;
}
switch (sid) {
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_ForceInline_signature):
if (_location != _in_method) break; // only allow for methods
if (!privileged) break; // only allow in privileged code
return _method_ForceInline;
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_DontInline_signature):
if (_location != _in_method) break; // only allow for methods
if (!privileged) break; // only allow in privileged code
return _method_DontInline;
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Compiled_signature):
if (_location != _in_method) break; // only allow for methods
if (!privileged) break; // only allow in privileged code
return _method_LambdaForm_Compiled;
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Hidden_signature):
if (_location != _in_method) break; // only allow for methods
if (!privileged) break; // only allow in privileged code
return _method_LambdaForm_Hidden;
case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_misc_Contended_signature):
if (_location != _in_field && _location != _in_class) break; // only allow for fields and classes
if (!EnableContended || (RestrictContended && !privileged)) break; // honor privileges
return _sun_misc_Contended;
default: break;
}
return AnnotationCollector::_unknown;
}
void ClassFileParser::FieldAnnotationCollector::apply_to(FieldInfo* f) {
fatal("no field annotations yet");
if (is_contended())
f->set_contended_group(contended_group());
}
void ClassFileParser::MethodAnnotationCollector::apply_to(methodHandle m) {
@ -1838,7 +1850,7 @@ void ClassFileParser::MethodAnnotationCollector::apply_to(methodHandle m) {
}
void ClassFileParser::ClassAnnotationCollector::apply_to(instanceKlassHandle k) {
fatal("no class annotations yet");
k->set_is_contended(is_contended());
}
@ -2148,9 +2160,21 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
cp, CHECK_(nullHandle));
} else if (method_attribute_name == vmSymbols::tag_method_parameters()) {
method_parameters_length = cfs->get_u1_fast();
// Track the actual size (note: this is written for clarity; a
// decent compiler will CSE and constant-fold this into a single
// expression)
u2 actual_size = 1;
method_parameters_data = cfs->get_u1_buffer();
actual_size += 2 * method_parameters_length;
cfs->skip_u2_fast(method_parameters_length);
actual_size += 4 * method_parameters_length;
cfs->skip_u4_fast(method_parameters_length);
// Enforce attribute length
if (method_attribute_length != actual_size) {
classfile_parse_error(
"Invalid MethodParameters method attribute length %u in class file %s",
method_attribute_length, CHECK_(nullHandle));
}
// ignore this attribute if it cannot be reflected
if (!SystemDictionary::Parameter_klass_loaded())
method_parameters_length = 0;
@ -2181,7 +2205,8 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
runtime_visible_annotations_length = method_attribute_length;
runtime_visible_annotations = cfs->get_u1_buffer();
assert(runtime_visible_annotations != NULL, "null visible annotations");
parse_annotations(runtime_visible_annotations,
parse_annotations(loader_data,
runtime_visible_annotations,
runtime_visible_annotations_length, cp, &parsed_annotations,
CHECK_(nullHandle));
cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle));
@ -2297,7 +2322,10 @@ methodHandle ClassFileParser::parse_method(ClassLoaderData* loader_data,
elem[i].name_cp_index =
Bytes::get_Java_u2(method_parameters_data);
method_parameters_data += 2;
elem[i].flags = Bytes::get_Java_u4(method_parameters_data);
u4 flags = Bytes::get_Java_u4(method_parameters_data);
// This caused an alignment fault on Sparc, if flags was a u4
elem[i].flags_lo = extract_low_short_from_int(flags);
elem[i].flags_hi = extract_high_short_from_int(flags);
method_parameters_data += 4;
}
}
@ -2475,26 +2503,38 @@ Array<Method*>* ClassFileParser::parse_methods(ClassLoaderData* loader_data,
*has_default_methods = true;
}
methods->at_put(index, method());
if (*methods_annotations == NULL) {
*methods_annotations =
MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
if (method_annotations != NULL) {
if (*methods_annotations == NULL) {
*methods_annotations =
MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
}
(*methods_annotations)->at_put(index, method_annotations);
}
(*methods_annotations)->at_put(index, method_annotations);
if (*methods_parameter_annotations == NULL) {
*methods_parameter_annotations =
MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
if (method_parameter_annotations != NULL) {
if (*methods_parameter_annotations == NULL) {
*methods_parameter_annotations =
MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
}
(*methods_parameter_annotations)->at_put(index, method_parameter_annotations);
}
(*methods_parameter_annotations)->at_put(index, method_parameter_annotations);
if (*methods_default_annotations == NULL) {
*methods_default_annotations =
MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
if (method_default_annotations != NULL) {
if (*methods_default_annotations == NULL) {
*methods_default_annotations =
MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
}
(*methods_default_annotations)->at_put(index, method_default_annotations);
}
(*methods_default_annotations)->at_put(index, method_default_annotations);
if (*methods_type_annotations == NULL) {
*methods_type_annotations =
MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
if (method_type_annotations != NULL) {
if (*methods_type_annotations == NULL) {
*methods_type_annotations =
MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
}
(*methods_type_annotations)->at_put(index, method_type_annotations);
}
(*methods_type_annotations)->at_put(index, method_type_annotations);
}
if (_need_verify && length > 1) {
@ -2886,7 +2926,8 @@ void ClassFileParser::parse_classfile_attributes(ClassLoaderData* loader_data,
runtime_visible_annotations_length = attribute_length;
runtime_visible_annotations = cfs->get_u1_buffer();
assert(runtime_visible_annotations != NULL, "null visible annotations");
parse_annotations(runtime_visible_annotations,
parse_annotations(loader_data,
runtime_visible_annotations,
runtime_visible_annotations_length,
cp,
parsed_annotations,
@ -3309,8 +3350,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
bool has_final_method = false;
AccessFlags promoted_flags;
promoted_flags.set_flags(0);
// These need to be oop pointers because they are allocated lazily
// inside parse_methods inside a nested HandleMark
Array<AnnotationArray*>* methods_annotations = NULL;
Array<AnnotationArray*>* methods_parameter_annotations = NULL;
Array<AnnotationArray*>* methods_default_annotations = NULL;
@ -3405,18 +3445,21 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
// Size of Java itable (in words)
itable_size = access_flags.is_interface() ? 0 : klassItable::compute_itable_size(transitive_interfaces);
// get the padding width from the option
// TODO: Ask VM about specific CPU we are running on
int pad_size = ContendedPaddingWidth;
// Field size and offset computation
int nonstatic_field_size = super_klass() == NULL ? 0 : super_klass->nonstatic_field_size();
#ifndef PRODUCT
int orig_nonstatic_field_size = 0;
#endif
int static_field_size = 0;
int next_static_oop_offset;
int next_static_double_offset;
int next_static_word_offset;
int next_static_short_offset;
int next_static_byte_offset;
int next_static_type_offset;
int next_static_padded_offset;
int next_nonstatic_oop_offset;
int next_nonstatic_double_offset;
int next_nonstatic_word_offset;
@ -3426,11 +3469,36 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
int first_nonstatic_oop_offset;
int first_nonstatic_field_offset;
int next_nonstatic_field_offset;
int next_nonstatic_padded_offset;
// Count the contended fields by type.
int static_contended_count = 0;
int nonstatic_contended_count = 0;
FieldAllocationCount fac_contended;
for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) {
FieldAllocationType atype = (FieldAllocationType) fs.allocation_type();
if (fs.is_contended()) {
fac_contended.count[atype]++;
if (fs.access_flags().is_static()) {
static_contended_count++;
} else {
nonstatic_contended_count++;
}
}
}
int contended_count = static_contended_count + nonstatic_contended_count;
// Calculate the starting byte offsets
next_static_oop_offset = InstanceMirrorKlass::offset_of_static_fields();
// class is contended, pad before all the fields
if (parsed_annotations.is_contended()) {
next_static_oop_offset += pad_size;
}
next_static_double_offset = next_static_oop_offset +
(fac.count[STATIC_OOP] * heapOopSize);
((fac.count[STATIC_OOP] - fac_contended.count[STATIC_OOP]) * heapOopSize);
if ( fac.count[STATIC_DOUBLE] &&
(Universe::field_type_should_be_aligned(T_DOUBLE) ||
Universe::field_type_should_be_aligned(T_LONG)) ) {
@ -3438,25 +3506,29 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
}
next_static_word_offset = next_static_double_offset +
(fac.count[STATIC_DOUBLE] * BytesPerLong);
((fac.count[STATIC_DOUBLE] - fac_contended.count[STATIC_DOUBLE]) * BytesPerLong);
next_static_short_offset = next_static_word_offset +
(fac.count[STATIC_WORD] * BytesPerInt);
((fac.count[STATIC_WORD] - fac_contended.count[STATIC_WORD]) * BytesPerInt);
next_static_byte_offset = next_static_short_offset +
(fac.count[STATIC_SHORT] * BytesPerShort);
next_static_type_offset = align_size_up((next_static_byte_offset +
fac.count[STATIC_BYTE] ), wordSize );
static_field_size = (next_static_type_offset -
next_static_oop_offset) / wordSize;
((fac.count[STATIC_SHORT] - fac_contended.count[STATIC_SHORT]) * BytesPerShort);
next_static_padded_offset = next_static_byte_offset +
((fac.count[STATIC_BYTE] - fac_contended.count[STATIC_BYTE]) * 1);
first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() +
nonstatic_field_size * heapOopSize;
// class is contended, pad before all the fields
if (parsed_annotations.is_contended()) {
first_nonstatic_field_offset += pad_size;
}
next_nonstatic_field_offset = first_nonstatic_field_offset;
unsigned int nonstatic_double_count = fac.count[NONSTATIC_DOUBLE];
unsigned int nonstatic_word_count = fac.count[NONSTATIC_WORD];
unsigned int nonstatic_short_count = fac.count[NONSTATIC_SHORT];
unsigned int nonstatic_byte_count = fac.count[NONSTATIC_BYTE];
unsigned int nonstatic_oop_count = fac.count[NONSTATIC_OOP];
unsigned int nonstatic_double_count = fac.count[NONSTATIC_DOUBLE] - fac_contended.count[NONSTATIC_DOUBLE];
unsigned int nonstatic_word_count = fac.count[NONSTATIC_WORD] - fac_contended.count[NONSTATIC_WORD];
unsigned int nonstatic_short_count = fac.count[NONSTATIC_SHORT] - fac_contended.count[NONSTATIC_SHORT];
unsigned int nonstatic_byte_count = fac.count[NONSTATIC_BYTE] - fac_contended.count[NONSTATIC_BYTE];
unsigned int nonstatic_oop_count = fac.count[NONSTATIC_OOP] - fac_contended.count[NONSTATIC_OOP];
bool super_has_nonstatic_fields =
(super_klass() != NULL && super_klass->has_nonstatic_fields());
@ -3529,12 +3601,12 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
}
if( allocation_style == 0 ) {
// Fields order: oops, longs/doubles, ints, shorts/chars, bytes
// Fields order: oops, longs/doubles, ints, shorts/chars, bytes, padded fields
next_nonstatic_oop_offset = next_nonstatic_field_offset;
next_nonstatic_double_offset = next_nonstatic_oop_offset +
(nonstatic_oop_count * heapOopSize);
} else if( allocation_style == 1 ) {
// Fields order: longs/doubles, ints, shorts/chars, bytes, oops
// Fields order: longs/doubles, ints, shorts/chars, bytes, oops, padded fields
next_nonstatic_double_offset = next_nonstatic_field_offset;
} else if( allocation_style == 2 ) {
// Fields allocation: oops fields in super and sub classes are together.
@ -3613,27 +3685,33 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
(nonstatic_word_count * BytesPerInt);
next_nonstatic_byte_offset = next_nonstatic_short_offset +
(nonstatic_short_count * BytesPerShort);
next_nonstatic_padded_offset = next_nonstatic_byte_offset +
nonstatic_byte_count;
int notaligned_offset;
if( allocation_style == 0 ) {
notaligned_offset = next_nonstatic_byte_offset + nonstatic_byte_count;
} else { // allocation_style == 1
next_nonstatic_oop_offset = next_nonstatic_byte_offset + nonstatic_byte_count;
// let oops jump before padding with this allocation style
if( allocation_style == 1 ) {
next_nonstatic_oop_offset = next_nonstatic_padded_offset;
if( nonstatic_oop_count > 0 ) {
next_nonstatic_oop_offset = align_size_up(next_nonstatic_oop_offset, heapOopSize);
}
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.
// The field allocation type was temporarily stored in the offset slot.
// oop fields are located before non-oop fields (static and non-static).
for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) {
// skip already laid out fields
if (fs.is_offset_set()) continue;
// contended fields are handled below
if (fs.is_contended()) continue;
int real_offset;
FieldAllocationType atype = (FieldAllocationType) fs.offset();
FieldAllocationType atype = (FieldAllocationType) fs.allocation_type();
// pack the rest of the fields
switch (atype) {
case STATIC_OOP:
real_offset = next_static_oop_offset;
@ -3722,13 +3800,225 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
fs.set_offset(real_offset);
}
// Handle the contended cases.
//
// Each contended field should not intersect the cache line with another contended field.
// In the absence of alignment information, we end up with pessimistically separating
// the fields with full-width padding.
//
// Additionally, this should not break alignment for the fields, so we round the alignment up
// for each field.
if (contended_count > 0) {
// if there is at least one contended field, we need to have pre-padding for them
if (nonstatic_contended_count > 0) {
next_nonstatic_padded_offset += pad_size;
}
// collect all contended groups
BitMap bm(cp->size());
for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) {
// skip already laid out fields
if (fs.is_offset_set()) continue;
if (fs.is_contended()) {
bm.set_bit(fs.contended_group());
}
}
int current_group = -1;
while ((current_group = (int)bm.get_next_one_offset(current_group + 1)) != (int)bm.size()) {
for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) {
// skip already laid out fields
if (fs.is_offset_set()) continue;
// skip non-contended fields and fields from different group
if (!fs.is_contended() || (fs.contended_group() != current_group)) continue;
// handle statics below
if (fs.access_flags().is_static()) continue;
int real_offset;
FieldAllocationType atype = (FieldAllocationType) fs.allocation_type();
switch (atype) {
case NONSTATIC_BYTE:
next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, 1);
real_offset = next_nonstatic_padded_offset;
next_nonstatic_padded_offset += 1;
break;
case NONSTATIC_SHORT:
next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, BytesPerShort);
real_offset = next_nonstatic_padded_offset;
next_nonstatic_padded_offset += BytesPerShort;
break;
case NONSTATIC_WORD:
next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, BytesPerInt);
real_offset = next_nonstatic_padded_offset;
next_nonstatic_padded_offset += BytesPerInt;
break;
case NONSTATIC_DOUBLE:
next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, BytesPerLong);
real_offset = next_nonstatic_padded_offset;
next_nonstatic_padded_offset += BytesPerLong;
break;
case NONSTATIC_OOP:
next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, heapOopSize);
real_offset = next_nonstatic_padded_offset;
next_nonstatic_padded_offset += heapOopSize;
// Create new oop map
nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
nonstatic_oop_map_count += 1;
if( first_nonstatic_oop_offset == 0 ) { // Undefined
first_nonstatic_oop_offset = real_offset;
}
break;
default:
ShouldNotReachHere();
}
if (fs.contended_group() == 0) {
// Contended group defines the equivalence class over the fields:
// the fields within the same contended group are not inter-padded.
// The only exception is default group, which does not incur the
// equivalence, and so requires intra-padding.
next_nonstatic_padded_offset += pad_size;
}
fs.set_offset(real_offset);
} // for
// Start laying out the next group.
// Note that this will effectively pad the last group in the back;
// this is expected to alleviate memory contention effects for
// subclass fields and/or adjacent object.
// If this was the default group, the padding is already in place.
if (current_group != 0) {
next_nonstatic_padded_offset += pad_size;
}
}
// handle static fields
// if there is at least one contended field, we need to have pre-padding for them
if (static_contended_count > 0) {
next_static_padded_offset += pad_size;
}
current_group = -1;
while ((current_group = (int)bm.get_next_one_offset(current_group + 1)) != (int)bm.size()) {
for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) {
// skip already laid out fields
if (fs.is_offset_set()) continue;
// skip non-contended fields and fields from different group
if (!fs.is_contended() || (fs.contended_group() != current_group)) continue;
// non-statics already handled above
if (!fs.access_flags().is_static()) continue;
int real_offset;
FieldAllocationType atype = (FieldAllocationType) fs.allocation_type();
switch (atype) {
case STATIC_BYTE:
next_static_padded_offset = align_size_up(next_static_padded_offset, 1);
real_offset = next_static_padded_offset;
next_static_padded_offset += 1;
break;
case STATIC_SHORT:
next_static_padded_offset = align_size_up(next_static_padded_offset, BytesPerShort);
real_offset = next_static_padded_offset;
next_static_padded_offset += BytesPerShort;
break;
case STATIC_WORD:
next_static_padded_offset = align_size_up(next_static_padded_offset, BytesPerInt);
real_offset = next_static_padded_offset;
next_static_padded_offset += BytesPerInt;
break;
case STATIC_DOUBLE:
next_static_padded_offset = align_size_up(next_static_padded_offset, BytesPerLong);
real_offset = next_static_padded_offset;
next_static_padded_offset += BytesPerLong;
break;
case STATIC_OOP:
next_static_padded_offset = align_size_up(next_static_padded_offset, heapOopSize);
real_offset = next_static_padded_offset;
next_static_padded_offset += heapOopSize;
break;
default:
ShouldNotReachHere();
}
if (fs.contended_group() == 0) {
// Contended group defines the equivalence class over the fields:
// the fields within the same contended group are not inter-padded.
// The only exception is default group, which does not incur the
// equivalence, and so requires intra-padding.
next_static_padded_offset += pad_size;
}
fs.set_offset(real_offset);
} // for
// Start laying out the next group.
// Note that this will effectively pad the last group in the back;
// this is expected to alleviate memory contention effects for
// subclass fields and/or adjacent object.
// If this was the default group, the padding is already in place.
if (current_group != 0) {
next_static_padded_offset += pad_size;
}
}
} // handle contended
// Size of instances
int instance_size;
int notaligned_offset = next_nonstatic_padded_offset;
// Entire class is contended, pad in the back.
// This helps to alleviate memory contention effects for subclass fields
// and/or adjacent object.
if (parsed_annotations.is_contended()) {
notaligned_offset += pad_size;
next_static_padded_offset += pad_size;
}
int next_static_type_offset = align_size_up(next_static_padded_offset, wordSize);
int static_field_size = (next_static_type_offset -
InstanceMirrorKlass::offset_of_static_fields()) / wordSize;
next_nonstatic_type_offset = align_size_up(notaligned_offset, heapOopSize );
nonstatic_field_size = nonstatic_field_size + ((next_nonstatic_type_offset
- first_nonstatic_field_offset)/heapOopSize);
next_nonstatic_type_offset = align_size_up(notaligned_offset, wordSize );
instance_size = align_object_size(next_nonstatic_type_offset / wordSize);
assert(instance_size == align_object_size(align_size_up((instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize), wordSize) / wordSize), "consistent layout helper value");
assert(instance_size == align_object_size(align_size_up(
(instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize + ((parsed_annotations.is_contended()) ? pad_size : 0)),
wordSize) / wordSize), "consistent layout helper value");
// Number of non-static oop map blocks allocated at end of klass.
const unsigned int total_oop_map_count =
@ -3912,7 +4202,10 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
// check that if this class is an interface then it doesn't have static methods
if (this_klass->is_interface()) {
check_illegal_static_method(this_klass, CHECK_(nullHandle));
/* An interface in a JAVA 8 classfile can be static */
if (_major_version < JAVA_8_VERSION) {
check_illegal_static_method(this_klass, CHECK_(nullHandle));
}
}
@ -4005,6 +4298,18 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
}
#endif
#ifndef PRODUCT
if (PrintFieldLayout) {
print_field_layout(name,
fields,
cp,
instance_size,
first_nonstatic_field_offset,
next_nonstatic_field_offset,
next_static_type_offset);
}
#endif
// preserve result across HandleMark
preserve_this_klass = this_klass();
}
@ -4017,6 +4322,38 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
return this_klass;
}
void ClassFileParser::print_field_layout(Symbol* name,
Array<u2>* fields,
constantPoolHandle cp,
int instance_size,
int instance_fields_start,
int instance_fields_end,
int static_fields_end) {
tty->print("%s: field layout\n", name->as_klass_external_name());
tty->print(" @%3d %s\n", instance_fields_start, "--- instance fields start ---");
for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) {
if (!fs.access_flags().is_static()) {
tty->print(" @%3d \"%s\" %s\n",
fs.offset(),
fs.name()->as_klass_external_name(),
fs.signature()->as_klass_external_name());
}
}
tty->print(" @%3d %s\n", instance_fields_end, "--- instance fields end ---");
tty->print(" @%3d %s\n", instance_size * wordSize, "--- instance ends ---");
tty->print(" @%3d %s\n", InstanceMirrorKlass::offset_of_static_fields(), "--- static fields start ---");
for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) {
if (fs.access_flags().is_static()) {
tty->print(" @%3d \"%s\" %s\n",
fs.offset(),
fs.name()->as_klass_external_name(),
fs.signature()->as_klass_external_name());
}
}
tty->print(" @%3d %s\n", static_fields_end, "--- static fields end ---");
tty->print("\n");
}
unsigned int
ClassFileParser::compute_oop_map_count(instanceKlassHandle super,
unsigned int nonstatic_oop_map_count,
@ -4466,6 +4803,7 @@ void ClassFileParser::verify_legal_method_modifiers(
const bool is_bridge = (flags & JVM_ACC_BRIDGE) != 0;
const bool is_strict = (flags & JVM_ACC_STRICT) != 0;
const bool is_synchronized = (flags & JVM_ACC_SYNCHRONIZED) != 0;
const bool is_protected = (flags & JVM_ACC_PROTECTED) != 0;
const bool major_gte_15 = _major_version >= JAVA_1_5_VERSION;
const bool major_gte_8 = _major_version >= JAVA_8_VERSION;
const bool is_initializer = (name == vmSymbols::object_initializer_name());
@ -4473,11 +4811,33 @@ void ClassFileParser::verify_legal_method_modifiers(
bool is_illegal = false;
if (is_interface) {
if (!is_public || is_static || is_final || is_native ||
((is_synchronized || is_strict) && major_gte_15 &&
(!major_gte_8 || is_abstract)) ||
(!major_gte_8 && !is_abstract)) {
is_illegal = true;
if (major_gte_8) {
// Class file version is JAVA_8_VERSION or later Methods of
// interfaces may set any of the flags except ACC_PROTECTED,
// ACC_FINAL, ACC_NATIVE, and ACC_SYNCHRONIZED; they must
// have exactly one of the ACC_PUBLIC or ACC_PRIVATE flags set.
if ((is_public == is_private) || /* Only one of private and public should be true - XNOR */
(is_native || is_protected || is_final || is_synchronized) ||
// If a specific method of a class or interface has its
// ACC_ABSTRACT flag set, it must not have any of its
// ACC_FINAL, ACC_NATIVE, ACC_PRIVATE, ACC_STATIC,
// ACC_STRICT, or ACC_SYNCHRONIZED flags set. No need to
// check for ACC_FINAL, ACC_NATIVE or ACC_SYNCHRONIZED as
// those flags are illegal irrespective of ACC_ABSTRACT being set or not.
(is_abstract && (is_private || is_static || is_strict))) {
is_illegal = true;
}
} else if (major_gte_15) {
// Class file version in the interval [JAVA_1_5_VERSION, JAVA_8_VERSION)
if (!is_public || is_static || is_final || is_synchronized ||
is_native || !is_abstract || is_strict) {
is_illegal = true;
}
} else {
// Class file version is pre-JAVA_1_5_VERSION
if (!is_public || is_static || is_final || is_native || !is_abstract) {
is_illegal = true;
}
}
} else { // not interface
if (is_initializer) {

View File

@ -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);

View File

@ -318,6 +318,7 @@ ClassLoaderData::~ClassLoaderData() {
}
Metaspace* ClassLoaderData::metaspace_non_null() {
assert(!DumpSharedSpaces, "wrong metaspace!");
// If the metaspace has not been allocated, create a new one. Might want
// to create smaller arena for Reflection class loaders also.
// The reason for the delayed allocation is because some class loaders are

View File

@ -1285,13 +1285,15 @@ static void merge_in_new_methods(InstanceKlass* klass,
enum { ANNOTATIONS, PARAMETERS, DEFAULTS, NUM_ARRAYS };
Array<AnnotationArray*>* original_annots[NUM_ARRAYS];
Array<AnnotationArray*>* original_annots[NUM_ARRAYS] = { NULL };
Array<Method*>* original_methods = klass->methods();
Annotations* annots = klass->annotations();
original_annots[ANNOTATIONS] = annots->methods_annotations();
original_annots[PARAMETERS] = annots->methods_parameter_annotations();
original_annots[DEFAULTS] = annots->methods_default_annotations();
if (annots != NULL) {
original_annots[ANNOTATIONS] = annots->methods_annotations();
original_annots[PARAMETERS] = annots->methods_parameter_annotations();
original_annots[DEFAULTS] = annots->methods_default_annotations();
}
Array<int>* original_ordering = klass->method_ordering();
Array<int>* merged_ordering = Universe::the_empty_int_array();
@ -1370,9 +1372,15 @@ static void merge_in_new_methods(InstanceKlass* klass,
// Replace klass methods with new merged lists
klass->set_methods(merged_methods);
annots->set_methods_annotations(merged_annots[ANNOTATIONS]);
annots->set_methods_parameter_annotations(merged_annots[PARAMETERS]);
annots->set_methods_default_annotations(merged_annots[DEFAULTS]);
if (annots != NULL) {
annots->set_methods_annotations(merged_annots[ANNOTATIONS]);
annots->set_methods_parameter_annotations(merged_annots[PARAMETERS]);
annots->set_methods_default_annotations(merged_annots[DEFAULTS]);
} else {
assert(merged_annots[ANNOTATIONS] == NULL, "Must be");
assert(merged_annots[PARAMETERS] == NULL, "Must be");
assert(merged_annots[DEFAULTS] == NULL, "Must be");
}
ClassLoaderData* cld = klass->class_loader_data();
MetadataFactory::free_array(cld, original_methods);

View File

@ -687,19 +687,6 @@ void java_lang_Class::set_array_klass(oop java_class, Klass* klass) {
}
Method* java_lang_Class::resolved_constructor(oop java_class) {
Metadata* constructor = java_class->metadata_field(_resolved_constructor_offset);
assert(constructor == NULL || constructor->is_method(), "should be method");
return ((Method*)constructor);
}
void java_lang_Class::set_resolved_constructor(oop java_class, Method* constructor) {
assert(constructor->is_method(), "should be method");
java_class->metadata_field_put(_resolved_constructor_offset, constructor);
}
bool java_lang_Class::is_primitive(oop java_class) {
// should assert:
//assert(java_lang_Class::is_instance(java_class), "must be a Class object");
@ -2949,7 +2936,6 @@ int java_lang_System::err_offset_in_bytes() {
int java_lang_Class::_klass_offset;
int java_lang_Class::_array_klass_offset;
int java_lang_Class::_resolved_constructor_offset;
int java_lang_Class::_oop_size_offset;
int java_lang_Class::_static_oop_field_count_offset;
GrowableArray<Klass*>* java_lang_Class::_fixup_mirror_list = NULL;
@ -3303,7 +3289,6 @@ void JavaClasses::check_offsets() {
// Fake fields
// CHECK_OFFSET("java/lang/Class", java_lang_Class, klass); // %%% this needs to be checked
// CHECK_OFFSET("java/lang/Class", java_lang_Class, array_klass); // %%% this needs to be checked
// CHECK_OFFSET("java/lang/Class", java_lang_Class, resolved_constructor); // %%% this needs to be checked
// java.lang.Throwable

View File

@ -206,7 +206,6 @@ class java_lang_String : AllStatic {
#define CLASS_INJECTED_FIELDS(macro) \
macro(java_lang_Class, klass, intptr_signature, false) \
macro(java_lang_Class, resolved_constructor, intptr_signature, false) \
macro(java_lang_Class, array_klass, intptr_signature, false) \
macro(java_lang_Class, oop_size, int_signature, false) \
macro(java_lang_Class, static_oop_field_count, int_signature, false)
@ -218,7 +217,6 @@ class java_lang_Class : AllStatic {
// The fake offsets are added by the class loader when java.lang.Class is loaded
static int _klass_offset;
static int _resolved_constructor_offset;
static int _array_klass_offset;
static int _oop_size_offset;
@ -254,15 +252,11 @@ class java_lang_Class : AllStatic {
static bool is_primitive(oop java_class);
static BasicType primitive_type(oop java_class);
static oop primitive_mirror(BasicType t);
// JVM_NewInstance support
static Method* resolved_constructor(oop java_class);
static void set_resolved_constructor(oop java_class, Method* constructor);
// JVM_NewArray support
static Klass* array_klass(oop java_class);
static void set_array_klass(oop java_class, Klass* klass);
// compiler support for class operations
static int klass_offset_in_bytes() { return _klass_offset; }
static int resolved_constructor_offset_in_bytes() { return _resolved_constructor_offset; }
static int array_klass_offset_in_bytes() { return _array_klass_offset; }
// Support for classRedefinedCount field
static int classRedefinedCount(oop the_class_mirror);

View File

@ -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.
*
* 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);

View File

@ -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.
*
* 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);

View File

@ -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.
*
* 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();
}

View File

@ -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>") \
@ -383,7 +386,6 @@
template(basicType_name, "basicType") \
template(append_name, "append") \
template(klass_name, "klass") \
template(resolved_constructor_name, "resolved_constructor") \
template(array_klass_name, "array_klass") \
template(oop_size_name, "oop_size") \
template(static_oop_field_count_name, "static_oop_field_count") \

View File

@ -30,6 +30,7 @@
#include "code/icBuffer.hpp"
#include "code/nmethod.hpp"
#include "code/pcDesc.hpp"
#include "compiler/compileBroker.hpp"
#include "gc_implementation/shared/markSweep.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/gcLocker.hpp"
@ -39,6 +40,7 @@
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/arguments.hpp"
#include "runtime/icache.hpp"
#include "runtime/java.hpp"
#include "runtime/mutexLocker.hpp"
@ -168,6 +170,8 @@ nmethod* CodeCache::next_nmethod (CodeBlob* cb) {
return (nmethod*)cb;
}
static size_t maxCodeCacheUsed = 0;
CodeBlob* CodeCache::allocate(int size) {
// Do not seize the CodeCache lock here--if the caller has not
// already done so, we are going to lose bigtime, since the code
@ -192,6 +196,8 @@ CodeBlob* CodeCache::allocate(int size) {
(address)_heap->end() - (address)_heap->begin());
}
}
maxCodeCacheUsed = MAX2(maxCodeCacheUsed, ((address)_heap->high_boundary() -
(address)_heap->low_boundary()) - unallocated_capacity());
verify_if_often();
print_trace("allocation", cb, size);
return cb;
@ -928,7 +934,14 @@ void CodeCache::print_internals() {
FREE_C_HEAP_ARRAY(int, buckets, mtCode);
}
#endif // !PRODUCT
void CodeCache::print() {
print_summary(tty);
#ifndef PRODUCT
if (!Verbose) return;
CodeBlob_sizes live;
CodeBlob_sizes dead;
@ -953,7 +966,7 @@ void CodeCache::print() {
}
if (Verbose) {
if (WizardMode) {
// print the oop_map usage
int code_size = 0;
int number_of_blobs = 0;
@ -977,20 +990,30 @@ void CodeCache::print() {
tty->print_cr(" map size = %d", map_size);
}
#endif // !PRODUCT
}
#endif // PRODUCT
void CodeCache::print_summary(outputStream* st, bool detailed) {
size_t total = (_heap->high_boundary() - _heap->low_boundary());
st->print_cr("CodeCache: size=" SIZE_FORMAT "Kb used=" SIZE_FORMAT
"Kb max_used=" SIZE_FORMAT "Kb free=" SIZE_FORMAT
"Kb max_free_chunk=" SIZE_FORMAT "Kb",
total/K, (total - unallocated_capacity())/K,
maxCodeCacheUsed/K, unallocated_capacity()/K, largest_free_block()/K);
void CodeCache::print_bounds(outputStream* st) {
st->print_cr("Code Cache [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")",
_heap->low_boundary(),
_heap->high(),
_heap->high_boundary());
st->print_cr(" total_blobs=" UINT32_FORMAT " nmethods=" UINT32_FORMAT
" adapters=" UINT32_FORMAT " free_code_cache=" SIZE_FORMAT "Kb"
" largest_free_block=" SIZE_FORMAT,
nof_blobs(), nof_nmethods(), nof_adapters(),
unallocated_capacity()/K, largest_free_block());
if (detailed) {
st->print_cr(" bounds [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT "]",
_heap->low_boundary(),
_heap->high(),
_heap->high_boundary());
st->print_cr(" total_blobs=" UINT32_FORMAT " nmethods=" UINT32_FORMAT
" adapters=" UINT32_FORMAT,
nof_blobs(), nof_nmethods(), nof_adapters());
st->print_cr(" compilation: %s", CompileBroker::should_compile_new_jobs() ?
"enabled" : Arguments::mode() == Arguments::_int ?
"disabled (interpreter mode)" :
"disabled (not enough contiguous free space left)");
}
}
void CodeCache::log_state(outputStream* st) {

View File

@ -145,11 +145,11 @@ class CodeCache : AllStatic {
static void prune_scavenge_root_nmethods();
// Printing/debugging
static void print() PRODUCT_RETURN; // prints summary
static void print(); // prints summary
static void print_internals();
static void verify(); // verifies the code cache
static void print_trace(const char* event, CodeBlob* cb, int size = 0) PRODUCT_RETURN;
static void print_bounds(outputStream* st); // Prints a summary of the bounds of the code cache
static void print_summary(outputStream* st, bool detailed = true); // Prints a summary of the code cache usage
static void log_state(outputStream* st);
// The full limits of the codeCache

View File

@ -50,6 +50,7 @@ class AbstractCompiler : public CHeapObj<mtCompiler> {
// Missing feature tests
virtual bool supports_native() { return true; }
virtual bool supports_osr () { return true; }
virtual bool can_compile_method(methodHandle method) { return true; }
#if defined(TIERED) || ( !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK))
virtual bool is_c1 () { return false; }
virtual bool is_c2 () { return false; }

View File

@ -1218,7 +1218,7 @@ nmethod* CompileBroker::compile_method(methodHandle method, int osr_bci,
// lock, make sure that the compilation
// isn't prohibited in a straightforward way.
if (compiler(comp_level) == NULL || compilation_is_prohibited(method, osr_bci, comp_level)) {
if (compiler(comp_level) == NULL || !compiler(comp_level)->can_compile_method(method) || compilation_is_prohibited(method, osr_bci, comp_level)) {
return NULL;
}
@ -1714,6 +1714,20 @@ void CompileBroker::maybe_block() {
}
}
// wrapper for CodeCache::print_summary()
static void codecache_print(bool detailed)
{
ResourceMark rm;
stringStream s;
// Dump code cache into a buffer before locking the tty,
{
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
CodeCache::print_summary(&s, detailed);
}
ttyLocker ttyl;
tty->print_cr(s.as_string());
}
// ------------------------------------------------------------------
// CompileBroker::invoke_compiler_on_method
//
@ -1841,6 +1855,9 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
tty->print_cr("size: %d time: %d inlined: %d bytes", code_size, (int)time.milliseconds(), task->num_inlined_bytecodes());
}
if (PrintCodeCacheOnCompilation)
codecache_print(/* detailed= */ false);
// Disable compilation, if required.
switch (compilable) {
case ciEnv::MethodCompilable_never:
@ -1885,6 +1902,7 @@ void CompileBroker::handle_full_code_cache() {
UseInterpreter = true;
if (UseCompiler || AlwaysCompileLoopMethods ) {
if (xtty != NULL) {
ResourceMark rm;
stringStream s;
// Dump code cache state into a buffer before locking the tty,
// because log_state() will use locks causing lock conflicts.
@ -1898,9 +1916,9 @@ void CompileBroker::handle_full_code_cache() {
}
warning("CodeCache is full. Compiler has been disabled.");
warning("Try increasing the code cache size using -XX:ReservedCodeCacheSize=");
CodeCache::print_bounds(tty);
#ifndef PRODUCT
if (CompileTheWorld || ExitOnFullCodeCache) {
codecache_print(/* detailed= */ true);
before_exit(JavaThread::current());
exit_globals(); // will delete tty
vm_direct_exit(CompileTheWorld ? 0 : 1);
@ -1913,6 +1931,7 @@ void CompileBroker::handle_full_code_cache() {
AlwaysCompileLoopMethods = false;
}
}
codecache_print(/* detailed= */ true);
}
// ------------------------------------------------------------------

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 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
@ -287,24 +287,24 @@
"The number of times we'll force an overflow during " \
"concurrent marking") \
\
experimental(uintx, G1NewSizePercent, 20, \
experimental(uintx, G1NewSizePercent, 5, \
"Percentage (0-100) of the heap size to use as default " \
"minimum young gen size.") \
\
experimental(uintx, G1MaxNewSizePercent, 80, \
experimental(uintx, G1MaxNewSizePercent, 60, \
"Percentage (0-100) of the heap size to use as default " \
" maximum young gen size.") \
\
experimental(uintx, G1MixedGCLiveThresholdPercent, 90, \
experimental(uintx, G1MixedGCLiveThresholdPercent, 65, \
"Threshold for regions to be considered for inclusion in the " \
"collection set of mixed GCs. " \
"Regions with live bytes exceeding this will not be collected.") \
\
product(uintx, G1HeapWastePercent, 5, \
product(uintx, G1HeapWastePercent, 10, \
"Amount of space, expressed as a percentage of the heap size, " \
"that G1 is willing not to collect to avoid expensive GCs.") \
\
product(uintx, G1MixedGCCountTarget, 4, \
product(uintx, G1MixedGCCountTarget, 8, \
"The target number of mixed GCs after a marking cycle.") \
\
experimental(uintx, G1OldCSetRegionThresholdPercent, 10, \

View File

@ -878,12 +878,6 @@ void EvacuateFollowersClosureGeneral::do_void() {
bool ParNewGeneration::_avoid_promotion_undo = false;
void ParNewGeneration::adjust_desired_tenuring_threshold() {
// Set the desired survivor size to half the real survivor space
_tenuring_threshold =
age_table()->compute_tenuring_threshold(to()->capacity()/HeapWordSize);
}
// A Generation that does parallel young-gen collection.
void ParNewGeneration::collect(bool full,
@ -1013,6 +1007,8 @@ void ParNewGeneration::collect(bool full,
size_policy->reset_gc_overhead_limit_count();
assert(to()->is_empty(), "to space should be empty now");
adjust_desired_tenuring_threshold();
} else {
assert(_promo_failure_scan_stack.is_empty(), "post condition");
_promo_failure_scan_stack.clear(true); // Clear cached segments.
@ -1035,7 +1031,6 @@ void ParNewGeneration::collect(bool full,
from()->set_concurrent_iteration_safe_limit(from()->top());
to()->set_concurrent_iteration_safe_limit(to()->top());
adjust_desired_tenuring_threshold();
if (ResizePLAB) {
plab_stats()->adjust_desired_plab_sz(n_workers);
}

View File

@ -347,10 +347,6 @@ class ParNewGeneration: public DefNewGeneration {
bool survivor_overflow() { return _survivor_overflow; }
void set_survivor_overflow(bool v) { _survivor_overflow = v; }
// Adjust the tenuring threshold. See the implementation for
// the details of the policy.
virtual void adjust_desired_tenuring_threshold();
public:
ParNewGeneration(ReservedSpace rs, size_t initial_byte_size, int level);

View File

@ -550,6 +550,11 @@ HeapWord* DefNewGeneration::expand_and_allocate(size_t size,
return allocate(size, is_tlab);
}
void DefNewGeneration::adjust_desired_tenuring_threshold() {
// Set the desired survivor size to half the real survivor space
_tenuring_threshold =
age_table()->compute_tenuring_threshold(to()->capacity()/HeapWordSize);
}
void DefNewGeneration::collect(bool full,
bool clear_all_soft_refs,
@ -649,9 +654,7 @@ void DefNewGeneration::collect(bool full,
assert(to()->is_empty(), "to space should be empty now");
// Set the desired survivor size to half the real survivor space
_tenuring_threshold =
age_table()->compute_tenuring_threshold(to()->capacity()/HeapWordSize);
adjust_desired_tenuring_threshold();
// A successful scavenge should restart the GC time limit count which is
// for full GC's.

View File

@ -124,7 +124,9 @@ protected:
_should_allocate_from_space = true;
}
protected:
// Tenuring
void adjust_desired_tenuring_threshold();
// Spaces
EdenSpace* _eden_space;
ContiguousSpace* _from_space;

View File

@ -66,7 +66,11 @@ class MetadataFactory : AllStatic {
if (data != NULL) {
assert(loader_data != NULL, "shouldn't pass null");
int size = data->size();
loader_data->metaspace_non_null()->deallocate((MetaWord*)data, size, false);
if (DumpSharedSpaces) {
loader_data->ro_metaspace()->deallocate((MetaWord*)data, size, false);
} else {
loader_data->metaspace_non_null()->deallocate((MetaWord*)data, size, false);
}
}
}
@ -77,6 +81,7 @@ class MetadataFactory : AllStatic {
assert(loader_data != NULL, "shouldn't pass null");
int size = md->size();
// Call metadata's deallocate function which will call deallocate fields
assert(!DumpSharedSpaces, "cannot deallocate metadata when dumping CDS archive");
assert(!md->on_stack(), "can't deallocate things on stack");
md->deallocate_contents(loader_data);
loader_data->metaspace_non_null()->deallocate((MetaWord*)md, size, md->is_klass());

View File

@ -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.
*
* 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.

View File

@ -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;
};

View File

@ -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 {

View File

@ -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

View File

@ -2890,11 +2890,7 @@ void InstanceKlass::oop_print_on(oop obj, outputStream* st) {
st->print(BULLET"fake entry for mirror: ");
mirrored_klass->print_value_on_maybe_null(st);
st->cr();
st->print(BULLET"fake entry resolved_constructor: ");
Method* ctor = java_lang_Class::resolved_constructor(obj);
ctor->print_value_on_maybe_null(st);
Klass* array_klass = java_lang_Class::array_klass(obj);
st->cr();
st->print(BULLET"fake entry for array: ");
array_klass->print_value_on_maybe_null(st);
st->cr();

View File

@ -225,12 +225,17 @@ class InstanceKlass: public Klass {
u2 _java_fields_count; // The number of declared Java fields
int _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks
// _is_marked_dependent can be set concurrently, thus cannot be part of the
// _misc_flags.
bool _is_marked_dependent; // used for marking during flushing and deoptimization
enum {
_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
_misc_has_default_methods = 1 << 5 // class/superclass/implemented interfaces has default methods
};
u2 _misc_flags;
u2 _minor_version; // minor version number of class file
@ -253,10 +258,6 @@ class InstanceKlass: public Klass {
jint _cached_class_file_len; // JVMTI: length of above
JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration
// true if class, superclass, or implemented interfaces have default methods
bool _has_default_methods;
volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change
// Method array.
Array<Method*>* _methods;
// Interface (Klass*s) this class declares locally to implement.
@ -280,6 +281,8 @@ class InstanceKlass: public Klass {
// ...
Array<u2>* _fields;
volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change
// Class states are defined as ClassState (see above).
// Place the _init_state here to utilize the unused 2-byte after
// _idnum_allocated_count.
@ -550,6 +553,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); }
@ -616,8 +630,16 @@ class InstanceKlass: public Klass {
return _jvmti_cached_class_field_map;
}
bool has_default_methods() const { return _has_default_methods; }
void set_has_default_methods(bool b) { _has_default_methods = b; }
bool has_default_methods() const {
return (_misc_flags & _misc_has_default_methods) != 0;
}
void set_has_default_methods(bool b) {
if (b) {
_misc_flags |= _misc_has_default_methods;
} else {
_misc_flags &= ~_misc_has_default_methods;
}
}
// for adding methods, ConstMethod::UNSET_IDNUM means no more ids available
inline u2 next_method_idnum();

View File

@ -692,7 +692,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
PhaseGVN gvn(node_arena(), estimated_size);
set_initial_gvn(&gvn);
if (PrintInlining) {
if (PrintInlining || PrintIntrinsics NOT_PRODUCT( || PrintOptoInlining)) {
_print_inlining_list = new (comp_arena())GrowableArray<PrintInliningBuffer>(comp_arena(), 1, 1, PrintInliningBuffer());
}
{ // Scope for timing the parser
@ -2049,7 +2049,7 @@ void Compile::Optimize() {
} // (End scope of igvn; run destructor if necessary for asserts.)
dump_inlining();
dump_inlining();
// A method with only infinite loops has no edges entering loops from root
{
NOT_PRODUCT( TracePhase t2("graphReshape", &_t_graphReshaping, TimeCompiler); )
@ -3497,7 +3497,7 @@ void Compile::ConstantTable::fill_jump_table(CodeBuffer& cb, MachConstantNode* n
}
void Compile::dump_inlining() {
if (PrintInlining) {
if (PrintInlining || PrintIntrinsics NOT_PRODUCT( || PrintOptoInlining)) {
// Print inlining message for candidates that we couldn't inline
// for lack of space or non constant receiver
for (int i = 0; i < _late_inlines.length(); i++) {

View File

@ -553,7 +553,13 @@ void Parse::do_call() {
rtype = ctype;
}
} else {
assert(rtype == ctype, "mismatched return types"); // symbolic resolution enforces this
// Symbolic resolution enforces the types to be the same.
// NOTE: We must relax the assert for unloaded types because two
// different ciType instances of the same unloaded class type
// can appear to be "loaded" by different loaders (depending on
// the accessing class).
assert(!rtype->is_loaded() || !ctype->is_loaded() || rtype == ctype,
err_msg_res("mismatched return types: rtype=%s, ctype=%s", rtype->name(), ctype->name()));
}
// If the return type of the method is not loaded, assert that the

View File

@ -3559,7 +3559,6 @@ bool LibraryCallKit::inline_native_getLength() {
// public static <T,U> T[] java.util.Arrays.copyOf( U[] original, int newLength, Class<? extends T[]> newType);
// public static <T,U> T[] java.util.Arrays.copyOfRange(U[] original, int from, int to, Class<? extends T[]> newType);
bool LibraryCallKit::inline_array_copyOf(bool is_copyOfRange) {
return false;
if (too_many_traps(Deoptimization::Reason_intrinsic)) return false;
// Get the arguments.

View File

@ -1582,13 +1582,22 @@ JVM_ENTRY(jbyteArray, JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls))
if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) {
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));
if (k->oop_is_instance()) {
typeArrayOop a = Annotations::make_java_array(InstanceKlass::cast(k)->type_annotations()->class_annotations(), CHECK_NULL);
return (jbyteArray) JNIHandles::make_local(env, a);
Annotations* type_annotations = InstanceKlass::cast(k)->type_annotations();
if (type_annotations != NULL) {
typeArrayOop a = Annotations::make_java_array(type_annotations->class_annotations(), CHECK_NULL);
return (jbyteArray) JNIHandles::make_local(env, a);
}
}
}
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 +1607,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 +1855,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 +1869,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");

View File

@ -929,11 +929,14 @@ class CommandLineFlags {
"Starts debugger when an implicit OS (e.g., NULL) " \
"exception happens") \
\
notproduct(bool, PrintCodeCache, false, \
"Print the compiled_code cache when exiting") \
product(bool, PrintCodeCache, false, \
"Print the code cache memory usage when exiting") \
\
develop(bool, PrintCodeCache2, false, \
"Print detailed info on the compiled_code cache when exiting") \
"Print detailed usage info on the code cache when exiting") \
\
product(bool, PrintCodeCacheOnCompilation, false, \
"Print the code cache memory usage each time a method is compiled") \
\
diagnostic(bool, PrintStubCode, false, \
"Print generated stub code") \
@ -969,18 +972,6 @@ class CommandLineFlags {
notproduct(uintx, WarnOnStalledSpinLock, 0, \
"Prints warnings for stalled SpinLocks") \
\
develop(bool, InitializeJavaLangSystem, true, \
"Initialize java.lang.System - turn off for individual " \
"method debugging") \
\
develop(bool, InitializeJavaLangString, true, \
"Initialize java.lang.String - turn off for individual " \
"method debugging") \
\
develop(bool, InitializeJavaLangExceptionsErrors, true, \
"Initialize various error and exception classes - turn off for " \
"individual method debugging") \
\
product(bool, RegisterFinalizersAtInit, true, \
"Register finalizable objects at end of Object.<init> or " \
"after allocation") \
@ -1075,7 +1066,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 +1157,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") \
\

View File

@ -368,6 +368,12 @@ void print_statistics() {
if (CITime) {
CompileBroker::print_times();
}
if (PrintCodeCache) {
MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
CodeCache::print();
}
#ifdef COMPILER2
if (PrintPreciseBiasedLockingStatistics) {
OptoRuntime::print_named_counters();
@ -542,6 +548,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

View File

@ -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);

View File

@ -1716,7 +1716,6 @@ static void ensure_join(JavaThread* thread) {
// cleanup_failed_attach_current_thread as well.
void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
assert(this == JavaThread::current(), "thread consistency check");
if (!InitializeJavaLangSystem) return;
HandleMark hm(this);
Handle uncaught_exception(this, this->pending_exception());
@ -3469,11 +3468,7 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
create_vm_init_libraries();
}
if (InitializeJavaLangString) {
initialize_class(vmSymbols::java_lang_String(), CHECK_0);
} else {
warning("java.lang.String not initialized");
}
initialize_class(vmSymbols::java_lang_String(), CHECK_0);
if (AggressiveOpts) {
{
@ -3514,53 +3509,39 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
}
// Initialize java_lang.System (needed before creating the thread)
if (InitializeJavaLangSystem) {
initialize_class(vmSymbols::java_lang_System(), CHECK_0);
initialize_class(vmSymbols::java_lang_ThreadGroup(), CHECK_0);
Handle thread_group = create_initial_thread_group(CHECK_0);
Universe::set_main_thread_group(thread_group());
initialize_class(vmSymbols::java_lang_Thread(), CHECK_0);
oop thread_object = create_initial_thread(thread_group, main_thread, CHECK_0);
main_thread->set_threadObj(thread_object);
// Set thread status to running since main thread has
// been started and running.
java_lang_Thread::set_thread_status(thread_object,
java_lang_Thread::RUNNABLE);
initialize_class(vmSymbols::java_lang_System(), CHECK_0);
initialize_class(vmSymbols::java_lang_ThreadGroup(), CHECK_0);
Handle thread_group = create_initial_thread_group(CHECK_0);
Universe::set_main_thread_group(thread_group());
initialize_class(vmSymbols::java_lang_Thread(), CHECK_0);
oop thread_object = create_initial_thread(thread_group, main_thread, CHECK_0);
main_thread->set_threadObj(thread_object);
// Set thread status to running since main thread has
// been started and running.
java_lang_Thread::set_thread_status(thread_object,
java_lang_Thread::RUNNABLE);
// The VM creates & returns objects of this class. Make sure it's initialized.
initialize_class(vmSymbols::java_lang_Class(), CHECK_0);
// The VM creates & returns objects of this class. Make sure it's initialized.
initialize_class(vmSymbols::java_lang_Class(), CHECK_0);
// The VM preresolves methods to these classes. Make sure that they get initialized
initialize_class(vmSymbols::java_lang_reflect_Method(), CHECK_0);
initialize_class(vmSymbols::java_lang_ref_Finalizer(), CHECK_0);
call_initializeSystemClass(CHECK_0);
// The VM preresolves methods to these classes. Make sure that they get initialized
initialize_class(vmSymbols::java_lang_reflect_Method(), CHECK_0);
initialize_class(vmSymbols::java_lang_ref_Finalizer(), CHECK_0);
call_initializeSystemClass(CHECK_0);
// get the Java runtime name after java.lang.System is initialized
JDK_Version::set_runtime_name(get_java_runtime_name(THREAD));
JDK_Version::set_runtime_version(get_java_runtime_version(THREAD));
} else {
warning("java.lang.System not initialized");
}
// get the Java runtime name after java.lang.System is initialized
JDK_Version::set_runtime_name(get_java_runtime_name(THREAD));
JDK_Version::set_runtime_version(get_java_runtime_version(THREAD));
// an instance of OutOfMemory exception has been allocated earlier
if (InitializeJavaLangExceptionsErrors) {
initialize_class(vmSymbols::java_lang_OutOfMemoryError(), CHECK_0);
initialize_class(vmSymbols::java_lang_NullPointerException(), CHECK_0);
initialize_class(vmSymbols::java_lang_ClassCastException(), CHECK_0);
initialize_class(vmSymbols::java_lang_ArrayStoreException(), CHECK_0);
initialize_class(vmSymbols::java_lang_ArithmeticException(), CHECK_0);
initialize_class(vmSymbols::java_lang_StackOverflowError(), CHECK_0);
initialize_class(vmSymbols::java_lang_IllegalMonitorStateException(), CHECK_0);
initialize_class(vmSymbols::java_lang_IllegalArgumentException(), CHECK_0);
} else {
warning("java.lang.OutOfMemoryError has not been initialized");
warning("java.lang.NullPointerException has not been initialized");
warning("java.lang.ClassCastException has not been initialized");
warning("java.lang.ArrayStoreException has not been initialized");
warning("java.lang.ArithmeticException has not been initialized");
warning("java.lang.StackOverflowError has not been initialized");
warning("java.lang.IllegalArgumentException has not been initialized");
}
initialize_class(vmSymbols::java_lang_OutOfMemoryError(), CHECK_0);
initialize_class(vmSymbols::java_lang_NullPointerException(), CHECK_0);
initialize_class(vmSymbols::java_lang_ClassCastException(), CHECK_0);
initialize_class(vmSymbols::java_lang_ArrayStoreException(), CHECK_0);
initialize_class(vmSymbols::java_lang_ArithmeticException(), CHECK_0);
initialize_class(vmSymbols::java_lang_StackOverflowError(), CHECK_0);
initialize_class(vmSymbols::java_lang_IllegalMonitorStateException(), CHECK_0);
initialize_class(vmSymbols::java_lang_IllegalArgumentException(), CHECK_0);
}
// See : bugid 4211085.
@ -4011,10 +3992,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();

View File

@ -257,8 +257,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
c1_nonstatic_field, \
c2_nonstatic_field, \
unchecked_c1_static_field, \
unchecked_c2_static_field, \
last_entry) \
unchecked_c2_static_field) \
\
/******************************************************************/ \
/* OopDesc and Klass hierarchies (NOTE: MethodData* incomplete) */ \
@ -718,7 +717,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
nonstatic_field(ClassLoaderData, _next, ClassLoaderData*) \
\
static_field(ClassLoaderDataGraph, _head, ClassLoaderData*) \
nonstatic_field(ClassLoaderDataGraph, _unloading, ClassLoaderData*) \
\
/*******************/ \
/* GrowableArrays */ \
@ -1200,7 +1198,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
/*********************************/ \
\
static_field(java_lang_Class, _klass_offset, int) \
static_field(java_lang_Class, _resolved_constructor_offset, int) \
static_field(java_lang_Class, _array_klass_offset, int) \
static_field(java_lang_Class, _oop_size_offset, int) \
static_field(java_lang_Class, _static_oop_field_count_offset, int) \
@ -1238,9 +1235,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
nonstatic_field(FreeList<Metablock>, _count, ssize_t) \
nonstatic_field(MetablockTreeDictionary, _total_size, size_t)
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_STRUCTS_OS_CPU macro (and must */
/* be present there) */
//--------------------------------------------------------------------------------
// VM_TYPES
@ -1280,8 +1274,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
declare_unsigned_integer_type, \
declare_c1_toplevel_type, \
declare_c2_type, \
declare_c2_toplevel_type, \
last_entry) \
declare_c2_toplevel_type) \
\
/*************************************************************/ \
/* Java primitive types -- required by the SA implementation */ \
@ -2098,10 +2091,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
declare_type(MetablockTreeDictionary, FreeBlockDictionary<Metablock>)
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_TYPES_OS_CPU macro (and must be */
/* present there) */
//--------------------------------------------------------------------------------
// VM_INT_CONSTANTS
//
@ -2114,8 +2103,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
declare_preprocessor_constant, \
declare_c1_constant, \
declare_c2_constant, \
declare_c2_preprocessor_constant, \
last_entry) \
declare_c2_preprocessor_constant) \
\
/******************/ \
/* Useful globals */ \
@ -2294,10 +2282,17 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
declare_constant(FieldInfo::name_index_offset) \
declare_constant(FieldInfo::signature_index_offset) \
declare_constant(FieldInfo::initval_index_offset) \
declare_constant(FieldInfo::low_offset) \
declare_constant(FieldInfo::high_offset) \
declare_constant(FieldInfo::low_packed_offset) \
declare_constant(FieldInfo::high_packed_offset) \
declare_constant(FieldInfo::field_slots) \
\
/*************************************/ \
/* FieldInfo tag constants */ \
/*************************************/ \
\
declare_preprocessor_constant("FIELDINFO_TAG_SIZE", FIELDINFO_TAG_SIZE) \
declare_preprocessor_constant("FIELDINFO_TAG_OFFSET", FIELDINFO_TAG_OFFSET) \
\
/************************************************/ \
/* InstanceKlass InnerClassAttributeOffset enum */ \
/************************************************/ \
@ -2483,9 +2478,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
declare_c2_preprocessor_constant("SAVED_ON_ENTRY_REG_COUNT", SAVED_ON_ENTRY_REG_COUNT) \
declare_c2_preprocessor_constant("C_SAVED_ON_ENTRY_REG_COUNT", C_SAVED_ON_ENTRY_REG_COUNT)
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_INT_CONSTANTS_OS_CPU macro (and */
/* must be present there) */
//--------------------------------------------------------------------------------
// VM_LONG_CONSTANTS
@ -2495,7 +2487,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
// enums, etc., while "declare_preprocessor_constant" must be used for
// all #defined constants.
#define VM_LONG_CONSTANTS(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
#define VM_LONG_CONSTANTS(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
\
/*********************/ \
/* MarkOop constants */ \
@ -2541,11 +2533,7 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
/* Constants in markOop used by CMS. */ \
declare_constant(markOopDesc::cms_shift) \
declare_constant(markOopDesc::cms_mask) \
declare_constant(markOopDesc::size_shift) \
/* NOTE that we do not use the last_entry() macro here; it is used */
/* in vmStructs_<os>_<cpu>.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and */
/* must be present there) */
declare_constant(markOopDesc::size_shift)
//--------------------------------------------------------------------------------
@ -2585,7 +2573,8 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
// This macro checks the type of a VMStructEntry by comparing pointer types
#define CHECK_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
{typeName *dummyObj = NULL; type* dummy = &dummyObj->fieldName; }
{typeName *dummyObj = NULL; type* dummy = &dummyObj->fieldName; \
assert(offset_of(typeName, fieldName) < sizeof(typeName), "Illegal nonstatic struct entry, field offset too large"); }
// This macro checks the type of a volatile VMStructEntry by comparing pointer types
#define CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
@ -2608,9 +2597,6 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
// This is a no-op macro for unchecked fields
#define CHECK_NO_OP(a, b, c)
// This is a no-op macro for the sentinel value
#define CHECK_SENTINEL()
//
// Build-specific macros:
//
@ -2789,48 +2775,47 @@ typedef BinaryTreeDictionary<Metablock, FreeList> MetablockTreeDictionary;
// as long as class VMStructs is a friend
VMStructEntry VMStructs::localHotSpotVMStructs[] = {
VM_STRUCTS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
GENERATE_STATIC_VM_STRUCT_ENTRY, \
GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY, \
GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY, \
GENERATE_C1_NONSTATIC_VM_STRUCT_ENTRY, \
GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY, \
GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \
GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \
GENERATE_VM_STRUCT_LAST_ENTRY)
VM_STRUCTS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_STATIC_VM_STRUCT_ENTRY,
GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_C1_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY,
GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY)
#ifndef SERIALGC
VM_STRUCTS_PARALLELGC(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
VM_STRUCTS_PARALLELGC(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_STATIC_VM_STRUCT_ENTRY)
VM_STRUCTS_CMS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
VM_STRUCTS_CMS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_STATIC_VM_STRUCT_ENTRY)
VM_STRUCTS_G1(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
VM_STRUCTS_G1(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_STATIC_VM_STRUCT_ENTRY)
#endif // SERIALGC
VM_STRUCTS_CPU(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
GENERATE_STATIC_VM_STRUCT_ENTRY, \
GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY, \
GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY, \
GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY, \
GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \
GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \
GENERATE_VM_STRUCT_LAST_ENTRY)
VM_STRUCTS_CPU(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_STATIC_VM_STRUCT_ENTRY,
GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY,
GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY)
VM_STRUCTS_OS_CPU(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
GENERATE_STATIC_VM_STRUCT_ENTRY, \
GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY, \
GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY, \
GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY, \
GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \
GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \
GENERATE_VM_STRUCT_LAST_ENTRY)
VM_STRUCTS_OS_CPU(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_STATIC_VM_STRUCT_ENTRY,
GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY,
GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY)
GENERATE_VM_STRUCT_LAST_ENTRY()
};
VMTypeEntry VMStructs::localHotSpotVMTypes[] = {
@ -2842,8 +2827,7 @@ VMTypeEntry VMStructs::localHotSpotVMTypes[] = {
GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY,
GENERATE_C1_TOPLEVEL_VM_TYPE_ENTRY,
GENERATE_C2_VM_TYPE_ENTRY,
GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY,
GENERATE_VM_TYPE_LAST_ENTRY)
GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY)
#ifndef SERIALGC
VM_TYPES_PARALLELGC(GENERATE_VM_TYPE_ENTRY,
@ -2865,8 +2849,7 @@ VMTypeEntry VMStructs::localHotSpotVMTypes[] = {
GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY,
GENERATE_C1_TOPLEVEL_VM_TYPE_ENTRY,
GENERATE_C2_VM_TYPE_ENTRY,
GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY,
GENERATE_VM_TYPE_LAST_ENTRY)
GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY)
VM_TYPES_OS_CPU(GENERATE_VM_TYPE_ENTRY,
GENERATE_TOPLEVEL_VM_TYPE_ENTRY,
@ -2875,8 +2858,9 @@ VMTypeEntry VMStructs::localHotSpotVMTypes[] = {
GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY,
GENERATE_C1_TOPLEVEL_VM_TYPE_ENTRY,
GENERATE_C2_VM_TYPE_ENTRY,
GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY,
GENERATE_VM_TYPE_LAST_ENTRY)
GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY)
GENERATE_VM_TYPE_LAST_ENTRY()
};
VMIntConstantEntry VMStructs::localHotSpotVMIntConstants[] = {
@ -2885,8 +2869,7 @@ VMIntConstantEntry VMStructs::localHotSpotVMIntConstants[] = {
GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
GENERATE_C1_VM_INT_CONSTANT_ENTRY,
GENERATE_C2_VM_INT_CONSTANT_ENTRY,
GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
GENERATE_VM_INT_CONSTANT_LAST_ENTRY)
GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY)
#ifndef SERIALGC
VM_INT_CONSTANTS_CMS(GENERATE_VM_INT_CONSTANT_ENTRY)
@ -2898,15 +2881,15 @@ VMIntConstantEntry VMStructs::localHotSpotVMIntConstants[] = {
GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
GENERATE_C1_VM_INT_CONSTANT_ENTRY,
GENERATE_C2_VM_INT_CONSTANT_ENTRY,
GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
GENERATE_VM_INT_CONSTANT_LAST_ENTRY)
GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY)
VM_INT_CONSTANTS_OS_CPU(GENERATE_VM_INT_CONSTANT_ENTRY,
GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
GENERATE_C1_VM_INT_CONSTANT_ENTRY,
GENERATE_C2_VM_INT_CONSTANT_ENTRY,
GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
GENERATE_VM_INT_CONSTANT_LAST_ENTRY)
GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY)
GENERATE_VM_INT_CONSTANT_LAST_ENTRY()
};
VMLongConstantEntry VMStructs::localHotSpotVMLongConstants[] = {
@ -2915,22 +2898,21 @@ VMLongConstantEntry VMStructs::localHotSpotVMLongConstants[] = {
GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
GENERATE_C1_VM_LONG_CONSTANT_ENTRY,
GENERATE_C2_VM_LONG_CONSTANT_ENTRY,
GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
GENERATE_VM_LONG_CONSTANT_LAST_ENTRY)
GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY)
VM_LONG_CONSTANTS_CPU(GENERATE_VM_LONG_CONSTANT_ENTRY,
GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
GENERATE_C1_VM_LONG_CONSTANT_ENTRY,
GENERATE_C2_VM_LONG_CONSTANT_ENTRY,
GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
GENERATE_VM_LONG_CONSTANT_LAST_ENTRY)
GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY)
VM_LONG_CONSTANTS_OS_CPU(GENERATE_VM_LONG_CONSTANT_ENTRY,
GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
GENERATE_C1_VM_LONG_CONSTANT_ENTRY,
GENERATE_C2_VM_LONG_CONSTANT_ENTRY,
GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
GENERATE_VM_LONG_CONSTANT_LAST_ENTRY)
GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY)
GENERATE_VM_LONG_CONSTANT_LAST_ENTRY()
};
// This is used both to check the types of referenced fields and, in
@ -2945,8 +2927,7 @@ VMStructs::init() {
CHECK_C1_NONSTATIC_VM_STRUCT_ENTRY,
CHECK_C2_NONSTATIC_VM_STRUCT_ENTRY,
CHECK_NO_OP,
CHECK_NO_OP,
CHECK_SENTINEL);
CHECK_NO_OP);
#ifndef SERIALGC
VM_STRUCTS_PARALLELGC(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
@ -2967,8 +2948,7 @@ VMStructs::init() {
CHECK_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY,
CHECK_C2_NONSTATIC_VM_STRUCT_ENTRY,
CHECK_NO_OP,
CHECK_NO_OP,
CHECK_SENTINEL);
CHECK_NO_OP);
VM_STRUCTS_OS_CPU(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
CHECK_STATIC_VM_STRUCT_ENTRY,
@ -2977,8 +2957,7 @@ VMStructs::init() {
CHECK_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY,
CHECK_C2_NONSTATIC_VM_STRUCT_ENTRY,
CHECK_NO_OP,
CHECK_NO_OP,
CHECK_SENTINEL);
CHECK_NO_OP);
VM_TYPES(CHECK_VM_TYPE_ENTRY,
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
@ -2987,8 +2966,7 @@ VMStructs::init() {
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
CHECK_C1_TOPLEVEL_VM_TYPE_ENTRY,
CHECK_C2_VM_TYPE_ENTRY,
CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY,
CHECK_SENTINEL);
CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY);
#ifndef SERIALGC
VM_TYPES_PARALLELGC(CHECK_VM_TYPE_ENTRY,
@ -3010,8 +2988,7 @@ VMStructs::init() {
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
CHECK_C1_TOPLEVEL_VM_TYPE_ENTRY,
CHECK_C2_VM_TYPE_ENTRY,
CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY,
CHECK_SENTINEL);
CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY);
VM_TYPES_OS_CPU(CHECK_VM_TYPE_ENTRY,
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
@ -3020,8 +2997,7 @@ VMStructs::init() {
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
CHECK_C1_TOPLEVEL_VM_TYPE_ENTRY,
CHECK_C2_VM_TYPE_ENTRY,
CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY,
CHECK_SENTINEL);
CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY);
//
// Split VM_STRUCTS() invocation into two parts to allow MS VC++ 6.0
@ -3040,53 +3016,49 @@ VMStructs::init() {
// Solstice NFS setup. If everyone switches to local workspaces on
// Win32, we can put this back in.
#ifndef _WINDOWS
debug_only(VM_STRUCTS(ENSURE_FIELD_TYPE_PRESENT, \
CHECK_NO_OP, \
CHECK_NO_OP, \
CHECK_NO_OP, \
CHECK_NO_OP, \
CHECK_NO_OP, \
CHECK_NO_OP, \
CHECK_NO_OP, \
CHECK_NO_OP, \
CHECK_SENTINEL));
debug_only(VM_STRUCTS(CHECK_NO_OP, \
ENSURE_FIELD_TYPE_PRESENT, \
CHECK_NO_OP, \
ENSURE_FIELD_TYPE_PRESENT, \
ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT, \
ENSURE_C1_FIELD_TYPE_PRESENT, \
ENSURE_C2_FIELD_TYPE_PRESENT, \
CHECK_NO_OP, \
CHECK_NO_OP, \
CHECK_SENTINEL));
debug_only(VM_STRUCTS(ENSURE_FIELD_TYPE_PRESENT,
CHECK_NO_OP,
CHECK_NO_OP,
CHECK_NO_OP,
CHECK_NO_OP,
CHECK_NO_OP,
CHECK_NO_OP,
CHECK_NO_OP,
CHECK_NO_OP));
debug_only(VM_STRUCTS(CHECK_NO_OP,
ENSURE_FIELD_TYPE_PRESENT,
CHECK_NO_OP,
ENSURE_FIELD_TYPE_PRESENT,
ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT,
ENSURE_C1_FIELD_TYPE_PRESENT,
ENSURE_C2_FIELD_TYPE_PRESENT,
CHECK_NO_OP,
CHECK_NO_OP));
#ifndef SERIALGC
debug_only(VM_STRUCTS_PARALLELGC(ENSURE_FIELD_TYPE_PRESENT, \
debug_only(VM_STRUCTS_PARALLELGC(ENSURE_FIELD_TYPE_PRESENT,
ENSURE_FIELD_TYPE_PRESENT));
debug_only(VM_STRUCTS_CMS(ENSURE_FIELD_TYPE_PRESENT, \
ENSURE_FIELD_TYPE_PRESENT, \
debug_only(VM_STRUCTS_CMS(ENSURE_FIELD_TYPE_PRESENT,
ENSURE_FIELD_TYPE_PRESENT,
ENSURE_FIELD_TYPE_PRESENT));
debug_only(VM_STRUCTS_G1(ENSURE_FIELD_TYPE_PRESENT, \
debug_only(VM_STRUCTS_G1(ENSURE_FIELD_TYPE_PRESENT,
ENSURE_FIELD_TYPE_PRESENT));
#endif // SERIALGC
debug_only(VM_STRUCTS_CPU(ENSURE_FIELD_TYPE_PRESENT, \
ENSURE_FIELD_TYPE_PRESENT, \
CHECK_NO_OP, \
ENSURE_FIELD_TYPE_PRESENT, \
ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT, \
ENSURE_C2_FIELD_TYPE_PRESENT, \
CHECK_NO_OP, \
CHECK_NO_OP, \
CHECK_SENTINEL));
debug_only(VM_STRUCTS_OS_CPU(ENSURE_FIELD_TYPE_PRESENT, \
ENSURE_FIELD_TYPE_PRESENT, \
CHECK_NO_OP, \
ENSURE_FIELD_TYPE_PRESENT, \
ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT, \
ENSURE_C2_FIELD_TYPE_PRESENT, \
CHECK_NO_OP, \
CHECK_NO_OP, \
CHECK_SENTINEL));
debug_only(VM_STRUCTS_CPU(ENSURE_FIELD_TYPE_PRESENT,
ENSURE_FIELD_TYPE_PRESENT,
CHECK_NO_OP,
ENSURE_FIELD_TYPE_PRESENT,
ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT,
ENSURE_C2_FIELD_TYPE_PRESENT,
CHECK_NO_OP,
CHECK_NO_OP));
debug_only(VM_STRUCTS_OS_CPU(ENSURE_FIELD_TYPE_PRESENT,
ENSURE_FIELD_TYPE_PRESENT,
CHECK_NO_OP,
ENSURE_FIELD_TYPE_PRESENT,
ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT,
ENSURE_C2_FIELD_TYPE_PRESENT,
CHECK_NO_OP,
CHECK_NO_OP));
#endif
}
@ -3146,10 +3118,10 @@ static int recursiveFindType(VMTypeEntry* origtypes, const char* typeName, bool
s[len-1] = '\0';
// tty->print_cr("checking \"%s\" for \"%s\"", s, typeName);
if (recursiveFindType(origtypes, s, true) == 1) {
delete s;
delete [] s;
return 1;
}
delete s;
delete [] s;
}
const char* start = NULL;
if (strstr(typeName, "GrowableArray<") == typeName) {
@ -3165,10 +3137,10 @@ static int recursiveFindType(VMTypeEntry* origtypes, const char* typeName, bool
s[len-1] = '\0';
// tty->print_cr("checking \"%s\" for \"%s\"", s, typeName);
if (recursiveFindType(origtypes, s, true) == 1) {
delete s;
delete [] s;
return 1;
}
delete s;
delete [] s;
}
if (strstr(typeName, "const ") == typeName) {
const char * s = typeName + strlen("const ");
@ -3182,8 +3154,10 @@ static int recursiveFindType(VMTypeEntry* origtypes, const char* typeName, bool
s[len - 6] = '\0';
// tty->print_cr("checking \"%s\" for \"%s\"", s, typeName);
if (recursiveFindType(origtypes, s, true) == 1) {
free(s);
return 1;
}
free(s);
}
if (!isRecurse) {
tty->print_cr("type \"%s\" not found", typeName);
@ -3206,6 +3180,30 @@ void vmStructs_init() {
#ifndef PRODUCT
void VMStructs::test() {
// Make sure last entry in the each array is indeed the correct end marker.
// The reason why these are static is to make sure they are zero initialized.
// Putting them on the stack will leave some garbage in the padding of some fields.
static VMStructEntry struct_last_entry = GENERATE_VM_STRUCT_LAST_ENTRY();
assert(memcmp(&localHotSpotVMStructs[(sizeof(localHotSpotVMStructs) / sizeof(VMStructEntry)) - 1],
&struct_last_entry,
sizeof(VMStructEntry)) == 0, "Incorrect last entry in localHotSpotVMStructs");
static VMTypeEntry type_last_entry = GENERATE_VM_TYPE_LAST_ENTRY();
assert(memcmp(&localHotSpotVMTypes[sizeof(localHotSpotVMTypes) / sizeof(VMTypeEntry) - 1],
&type_last_entry,
sizeof(VMTypeEntry)) == 0, "Incorrect last entry in localHotSpotVMTypes");
static VMIntConstantEntry int_last_entry = GENERATE_VM_INT_CONSTANT_LAST_ENTRY();
assert(memcmp(&localHotSpotVMIntConstants[sizeof(localHotSpotVMIntConstants) / sizeof(VMIntConstantEntry) - 1],
&int_last_entry,
sizeof(VMIntConstantEntry)) == 0, "Incorrect last entry in localHotSpotVMIntConstants");
static VMLongConstantEntry long_last_entry = GENERATE_VM_LONG_CONSTANT_LAST_ENTRY();
assert(memcmp(&localHotSpotVMLongConstants[sizeof(localHotSpotVMLongConstants) / sizeof(VMLongConstantEntry) - 1],
&long_last_entry,
sizeof(VMLongConstantEntry)) == 0, "Incorrect last entry in localHotSpotVMLongConstants");
// Check for duplicate entries in type array
for (int i = 0; localHotSpotVMTypes[i].typeName != NULL; i++) {
for (int j = i + 1; localHotSpotVMTypes[j].typeName != NULL; j++) {

View File

@ -1032,7 +1032,7 @@ void SharkBlock::do_field_access(bool is_get, bool is_field) {
check_null(value);
object = value->generic_value();
}
if (is_get && field->is_constant()) {
if (is_get && field->is_constant() && field->is_static()) {
SharkConstant *constant = SharkConstant::for_field(iter());
if (constant->is_loaded())
value = constant->value(builder());
@ -1044,10 +1044,17 @@ void SharkBlock::do_field_access(bool is_get, bool is_field) {
BasicType basic_type = field->type()->basic_type();
Type *stack_type = SharkType::to_stackType(basic_type);
Type *field_type = SharkType::to_arrayType(basic_type);
Type *type = field_type;
if (field->is_volatile()) {
if (field_type == SharkType::jfloat_type()) {
type = SharkType::jint_type();
} else if (field_type == SharkType::jdouble_type()) {
type = SharkType::jlong_type();
}
}
Value *addr = builder()->CreateAddressOfStructEntry(
object, in_ByteSize(field->offset_in_bytes()),
PointerType::getUnqual(field_type),
PointerType::getUnqual(type),
"addr");
// Do the access
@ -1055,6 +1062,7 @@ void SharkBlock::do_field_access(bool is_get, bool is_field) {
Value* field_value;
if (field->is_volatile()) {
field_value = builder()->CreateAtomicLoad(addr);
field_value = builder()->CreateBitCast(field_value, field_type);
} else {
field_value = builder()->CreateLoad(addr);
}
@ -1074,6 +1082,7 @@ void SharkBlock::do_field_access(bool is_get, bool is_field) {
}
if (field->is_volatile()) {
field_value = builder()->CreateBitCast(field_value, type);
builder()->CreateAtomicStore(field_value, addr);
} else {
builder()->CreateStore(field_value, addr);

View File

@ -185,6 +185,9 @@ void SharkCompiler::compile_method(ciEnv* env,
// Build the LLVM IR for the method
Function *function = SharkFunction::build(env, &builder, flow, name);
if (env->failing()) {
return;
}
// Generate native code. It's unpleasant that we have to drop into
// the VM to do this -- it blocks safepoints -- but I can't see any

View File

@ -46,6 +46,9 @@ class SharkCompiler : public AbstractCompiler {
// Missing feature tests
bool supports_native() { return true; }
bool supports_osr() { return true; }
bool can_compile_method(methodHandle method) {
return ! (method->is_method_handle_intrinsic() || method->is_compiled_lambda_form());
}
// Customization
bool needs_adapters() { return false; }

View File

@ -37,7 +37,12 @@ SharkConstant* SharkConstant::for_ldc(ciBytecodeStream *iter) {
ciType *type = NULL;
if (constant.basic_type() == T_OBJECT) {
ciEnv *env = ciEnv::current();
assert(constant.as_object()->klass() == env->String_klass() || constant.as_object()->klass() == env->Class_klass(), "should be");
assert(constant.as_object()->klass() == env->String_klass()
|| constant.as_object()->klass() == env->Class_klass()
|| constant.as_object()->klass()->is_subtype_of(env->MethodType_klass())
|| constant.as_object()->klass()->is_subtype_of(env->MethodHandle_klass()), "should be");
type = constant.as_object()->klass();
}
return new SharkConstant(constant, type);

View File

@ -77,6 +77,10 @@ void SharkFunction::initialize(const char *name) {
// Walk the tree from the start block to determine which
// blocks are entered and which blocks require phis
SharkTopLevelBlock *start_block = block(flow()->start_block_num());
if (is_osr() && start_block->stack_depth_at_entry() != 0) {
env()->record_method_not_compilable("can't compile OSR block with incoming stack-depth > 0");
return;
}
assert(start_block->start() == flow()->start_bci(), "blocks out of order");
start_block->enter();

View File

@ -725,7 +725,7 @@ bool SharkInlinerHelper::do_field_access(bool is_get, bool is_field) {
// Push the result if necessary
if (is_get) {
bool result_pushed = false;
if (field->is_constant()) {
if (field->is_constant() && field->is_static()) {
SharkConstant *sc = SharkConstant::for_field(iter());
if (sc->is_loaded()) {
push(sc->is_nonzero());

View File

@ -68,7 +68,7 @@ class SharkCompileInvariants : public ResourceObj {
//
// Accessing this directly is kind of ugly, so it's private. Add
// new accessors below if you need something from it.
private:
protected:
ciEnv* env() const {
assert(_env != NULL, "env not available");
return _env;
@ -99,13 +99,15 @@ class SharkCompileInvariants : public ResourceObj {
DebugInformationRecorder* debug_info() const {
return env()->debug_info();
}
Dependencies* dependencies() const {
return env()->dependencies();
}
SharkCodeBuffer* code_buffer() const {
return builder()->code_buffer();
}
public:
Dependencies* dependencies() const {
return env()->dependencies();
}
// Commonly used classes
protected:
ciInstanceKlass* java_lang_Object_klass() const {

View File

@ -113,7 +113,19 @@ void SharkTopLevelBlock::scan_for_traps() {
ciSignature* sig;
method = iter()->get_method(will_link, &sig);
assert(will_link, "typeflow responsibility");
// We can't compile calls to method handle intrinsics, because we use
// the interpreter entry points and they expect the top frame to be an
// interpreter frame. We need to implement the intrinsics for Shark.
if (method->is_method_handle_intrinsic() || method->is_compiled_lambda_form()) {
if (SharkPerformanceWarnings) {
warning("JSR292 optimization not yet implemented in Shark");
}
set_trap(
Deoptimization::make_trap_request(
Deoptimization::Reason_unhandled,
Deoptimization::Action_make_not_compilable), bci());
return;
}
if (!method->holder()->is_linked()) {
set_trap(
Deoptimization::make_trap_request(
@ -158,6 +170,16 @@ void SharkTopLevelBlock::scan_for_traps() {
return;
}
break;
case Bytecodes::_invokedynamic:
case Bytecodes::_invokehandle:
if (SharkPerformanceWarnings) {
warning("JSR292 optimization not yet implemented in Shark");
}
set_trap(
Deoptimization::make_trap_request(
Deoptimization::Reason_unhandled,
Deoptimization::Action_make_not_compilable), bci());
return;
}
}
@ -1030,7 +1052,6 @@ ciMethod* SharkTopLevelBlock::improve_virtual_call(ciMethod* caller,
dest_method->holder() == java_lang_Object_klass())
return dest_method;
#ifdef SHARK_CAN_DEOPTIMIZE_ANYWHERE
// This code can replace a virtual call with a direct call if this
// class is the only one in the entire set of loaded classes that
// implements this method. This makes the compiled code dependent
@ -1064,6 +1085,8 @@ ciMethod* SharkTopLevelBlock::improve_virtual_call(ciMethod* caller,
if (monomorphic_target != NULL) {
assert(!monomorphic_target->is_abstract(), "shouldn't be");
function()->dependencies()->assert_unique_concrete_method(actual_receiver, monomorphic_target);
// Opto has a bunch of type checking here that I don't
// understand. It's to inhibit casting in one direction,
// possibly because objects in Opto can have inexact
@ -1097,7 +1120,6 @@ ciMethod* SharkTopLevelBlock::improve_virtual_call(ciMethod* caller,
// with non-monomorphic targets if the receiver has an exact
// type. We don't mark types this way, so we can't do this.
#endif // SHARK_CAN_DEOPTIMIZE_ANYWHERE
return NULL;
}
@ -1298,8 +1320,9 @@ void SharkTopLevelBlock::do_call() {
// Try to inline the call
if (!call_is_virtual) {
if (SharkInliner::attempt_inline(call_method, current_state()))
if (SharkInliner::attempt_inline(call_method, current_state())) {
return;
}
}
// Find the method we are calling

View File

@ -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.
*
* 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)

View File

@ -702,7 +702,7 @@ void VMError::report(outputStream* st) {
if (_verbose && Universe::is_fully_initialized()) {
// print code cache information before vm abort
CodeCache::print_bounds(st);
CodeCache::print_summary(st);
st->cr();
}

View File

@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,7 +23,16 @@
*/
/*
* Manual test
* @test
* @bug 7190310
* @summary Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
* @run main/othervm/timeout=600 -Xbatch Test7190310
*/
/*
* Note bug exhibits as infinite loop, timeout is helpful.
* It should normally finish pretty quickly, but on some especially slow machines
* it may not. The companion _unsafe test lacks a timeout, but that is okay.
*/
import java.lang.ref.*;