8022494: Make compilation IDs sequential
Summary: Use atomic operations to provide sequential compilation IDs
Reviewed-by: kvn, twisti
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Thu Jan 09 18:09:59 2014 -0800
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Fri Jan 10 06:36:18 2014 +0100
@@ -132,9 +132,9 @@
// The installed compiler(s)
AbstractCompiler* CompileBroker::_compilers[2];
-// These counters are used for assigning id's to each compilation
-uint CompileBroker::_compilation_id = 0;
-uint CompileBroker::_osr_compilation_id = 0;
+// These counters are used to assign an unique ID to each compilation.
+volatile jint CompileBroker::_compilation_id = 0;
+volatile jint CompileBroker::_osr_compilation_id = 0;
// Debugging information
int CompileBroker::_last_compile_type = no_compile;
@@ -1158,7 +1158,7 @@
// We now know that this compilation is not pending, complete,
// or prohibited. Assign a compile_id to this compilation
// and check to see if it is in our [Start..Stop) range.
- uint compile_id = assign_compile_id(method, osr_bci);
+ int compile_id = assign_compile_id(method, osr_bci);
if (compile_id == 0) {
// The compilation falls outside the allowed range.
return;
@@ -1305,18 +1305,12 @@
// do the compilation
if (method->is_native()) {
if (!PreferInterpreterNativeStubs || method->is_method_handle_intrinsic()) {
- // Acquire our lock.
- int compile_id;
- {
- MutexLocker locker(MethodCompileQueue_lock, THREAD);
- compile_id = assign_compile_id(method, standard_entry_bci);
- }
// To properly handle the appendix argument for out-of-line calls we are using a small trampoline that
// pops off the appendix argument and jumps to the target (see gen_special_dispatch in SharedRuntime).
//
// Since normal compiled-to-compiled calls are not able to handle such a thing we MUST generate an adapter
// in this case. If we can't generate one and use it we can not execute the out-of-line method handle calls.
- (void) AdapterHandlerLibrary::create_native_wrapper(method, compile_id);
+ AdapterHandlerLibrary::create_native_wrapper(method);
} else {
return NULL;
}
@@ -1419,27 +1413,28 @@
return false;
}
-
-// ------------------------------------------------------------------
-// CompileBroker::assign_compile_id
-//
-// Assign a serialized id number to this compilation request. If the
-// number falls out of the allowed range, return a 0. OSR
-// compilations may be numbered separately from regular compilations
-// if certain debugging flags are used.
-uint CompileBroker::assign_compile_id(methodHandle method, int osr_bci) {
- assert(MethodCompileQueue_lock->owner() == Thread::current(),
- "must hold the compilation queue lock");
+/**
+ * Generate serialized IDs for compilation requests. If certain debugging flags are used
+ * and the ID is not within the specified range, the method is not compiled and 0 is returned.
+ * The function also allows to generate separate compilation IDs for OSR compilations.
+ */
+int CompileBroker::assign_compile_id(methodHandle method, int osr_bci) {
+#ifdef ASSERT
bool is_osr = (osr_bci != standard_entry_bci);
- uint id;
- if (CICountOSR && is_osr) {
- id = ++_osr_compilation_id;
- if ((uint)CIStartOSR <= id && id < (uint)CIStopOSR) {
+ int id;
+ if (method->is_native()) {
+ assert(!is_osr, "can't be osr");
+ // Adapters, native wrappers and method handle intrinsics
+ // should be generated always.
+ return Atomic::add(1, &_compilation_id);
+ } else if (CICountOSR && is_osr) {
+ id = Atomic::add(1, &_osr_compilation_id);
+ if (CIStartOSR <= id && id < CIStopOSR) {
return id;
}
} else {
- id = ++_compilation_id;
- if ((uint)CIStart <= id && id < (uint)CIStop) {
+ id = Atomic::add(1, &_compilation_id);
+ if (CIStart <= id && id < CIStop) {
return id;
}
}
@@ -1447,6 +1442,11 @@
// Method was not in the appropriate compilation range.
method->set_not_compilable_quietly();
return 0;
+#else
+ // CICountOSR is a develop flag and set to 'false' by default. In a product built,
+ // only _compilation_id is incremented.
+ return Atomic::add(1, &_compilation_id);
+#endif
}
--- a/hotspot/src/share/vm/compiler/compileBroker.hpp Thu Jan 09 18:09:59 2014 -0800
+++ b/hotspot/src/share/vm/compiler/compileBroker.hpp Fri Jan 10 06:36:18 2014 +0100
@@ -246,6 +246,8 @@
// Compile type Information for print_last_compile() and CompilerCounters
enum { no_compile, normal_compile, osr_compile, native_compile };
+ static int assign_compile_id (methodHandle method, int osr_bci);
+
private:
static bool _initialized;
@@ -258,9 +260,8 @@
static AbstractCompiler* _compilers[2];
// These counters are used for assigning id's to each compilation
- static uint _compilation_id;
- static uint _osr_compilation_id;
- static uint _native_compilation_id;
+ static volatile jint _compilation_id;
+ static volatile jint _osr_compilation_id;
static int _last_compile_type;
static int _last_compile_level;
@@ -321,7 +322,6 @@
static void init_compiler_threads(int c1_compiler_count, int c2_compiler_count);
static bool compilation_is_complete (methodHandle method, int osr_bci, int comp_level);
static bool compilation_is_prohibited(methodHandle method, int osr_bci, int comp_level);
- static uint assign_compile_id (methodHandle method, int osr_bci);
static bool is_compile_blocking (methodHandle method, int osr_bci);
static void preload_classes (methodHandle method, TRAPS);
--- a/hotspot/src/share/vm/runtime/globals.hpp Thu Jan 09 18:09:59 2014 -0800
+++ b/hotspot/src/share/vm/runtime/globals.hpp Fri Jan 10 06:36:18 2014 +0100
@@ -3309,21 +3309,21 @@
develop(intx, CIStart, 0, \
"The id of the first compilation to permit") \
\
- develop(intx, CIStop, -1, \
+ develop(intx, CIStop, max_jint, \
"The id of the last compilation to permit") \
\
- develop(intx, CIStartOSR, 0, \
+ develop(intx, CIStartOSR, 0, \
"The id of the first osr compilation to permit " \
"(CICountOSR must be on)") \
\
- develop(intx, CIStopOSR, -1, \
+ develop(intx, CIStopOSR, max_jint, \
"The id of the last osr compilation to permit " \
"(CICountOSR must be on)") \
\
- develop(intx, CIBreakAtOSR, -1, \
+ develop(intx, CIBreakAtOSR, -1, \
"The id of osr compilation to break at") \
\
- develop(intx, CIBreakAt, -1, \
+ develop(intx, CIBreakAt, -1, \
"The id of compilation to break at") \
\
product(ccstrlist, CompileOnly, "", \
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Jan 09 18:09:59 2014 -0800
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Fri Jan 10 06:36:18 2014 +0100
@@ -2595,11 +2595,13 @@
#endif
-// Create a native wrapper for this native method. The wrapper converts the
-// java compiled calling convention to the native convention, handlizes
-// arguments, and transitions to native. On return from the native we transition
-// back to java blocking if a safepoint is in progress.
-nmethod *AdapterHandlerLibrary::create_native_wrapper(methodHandle method, int compile_id) {
+/**
+ * Create a native wrapper for this native method. The wrapper converts the
+ * Java-compiled calling convention to the native convention, handles
+ * arguments, and transitions to native. On return from the native we transition
+ * back to java blocking if a safepoint is in progress.
+ */
+void AdapterHandlerLibrary::create_native_wrapper(methodHandle method) {
ResourceMark rm;
nmethod* nm = NULL;
@@ -2608,16 +2610,19 @@
method->has_native_function(), "must have something valid to call!");
{
- // perform the work while holding the lock, but perform any printing outside the lock
+ // Perform the work while holding the lock, but perform any printing outside the lock
MutexLocker mu(AdapterHandlerLibrary_lock);
// See if somebody beat us to it
nm = method->code();
- if (nm) {
- return nm;
+ if (nm != NULL) {
+ return;
}
+ const int compile_id = CompileBroker::assign_compile_id(method, CompileBroker::standard_entry_bci);
+ assert(compile_id > 0, "Must generate native wrapper");
+
+
ResourceMark rm;
-
BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache
if (buf != NULL) {
CodeBuffer buffer(buf);
@@ -2649,16 +2654,14 @@
int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, is_outgoing);
// Generate the compiled-to-native wrapper code
- nm = SharedRuntime::generate_native_wrapper(&_masm,
- method,
- compile_id,
- sig_bt,
- regs,
- ret_type);
+ nm = SharedRuntime::generate_native_wrapper(&_masm, method, compile_id, sig_bt, regs, ret_type);
+
+ if (nm != NULL) {
+ method->set_code(method, nm);
+ }
}
- }
-
- // Must unlock before calling set_code
+ } // Unlock AdapterHandlerLibrary_lock
+
// Install the generated code.
if (nm != NULL) {
@@ -2666,13 +2669,11 @@
ttyLocker ttyl;
CompileTask::print_compilation(tty, nm, method->is_static() ? "(static)" : "");
}
- method->set_code(method, nm);
nm->post_compiled_method_load_event();
} else {
// CodeCache is full, disable compilation
CompileBroker::handle_full_code_cache();
}
- return nm;
}
JRT_ENTRY_NO_ASYNC(void, SharedRuntime::block_for_jni_critical(JavaThread* thread))
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp Thu Jan 09 18:09:59 2014 -0800
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp Fri Jan 10 06:36:18 2014 +0100
@@ -666,7 +666,7 @@
static AdapterHandlerEntry* new_entry(AdapterFingerPrint* fingerprint,
address i2c_entry, address c2i_entry, address c2i_unverified_entry);
- static nmethod* create_native_wrapper(methodHandle method, int compile_id);
+ static void create_native_wrapper(methodHandle method);
static AdapterHandlerEntry* get_adapter(methodHandle method);
#ifdef HAVE_DTRACE_H