From cdb1632fcf08f94deadd76b8d5f94849827545d7 Mon Sep 17 00:00:00 2001 From: anoll Date: Fri, 10 Jan 2014 06:36:18 +0100 Subject: [PATCH] 8022494: Make compilation IDs sequential Summary: Use atomic operations to provide sequential compilation IDs Reviewed-by: kvn, twisti --- src/share/vm/compiler/compileBroker.cpp | 56 ++++++++++++------------- src/share/vm/compiler/compileBroker.hpp | 8 ++-- src/share/vm/runtime/globals.hpp | 10 ++--- src/share/vm/runtime/sharedRuntime.cpp | 39 ++++++++--------- src/share/vm/runtime/sharedRuntime.hpp | 2 +- 5 files changed, 58 insertions(+), 57 deletions(-) diff --git a/src/share/vm/compiler/compileBroker.cpp b/src/share/vm/compiler/compileBroker.cpp index f8fa26ff8..a6c9117e9 100644 --- a/src/share/vm/compiler/compileBroker.cpp +++ b/src/share/vm/compiler/compileBroker.cpp @@ -132,9 +132,9 @@ volatile jint CompileBroker::_should_compile_new_jobs = run_compilation; // 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 @@ void CompileBroker::compile_method_base(methodHandle method, // 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 @@ nmethod* CompileBroker::compile_method(methodHandle method, int osr_bci, // 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 @@ bool CompileBroker::compilation_is_prohibited(methodHandle method, int osr_bci, 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 @@ uint CompileBroker::assign_compile_id(methodHandle method, int osr_bci) { // 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 } diff --git a/src/share/vm/compiler/compileBroker.hpp b/src/share/vm/compiler/compileBroker.hpp index a74afb306..75cbcafaa 100644 --- a/src/share/vm/compiler/compileBroker.hpp +++ b/src/share/vm/compiler/compileBroker.hpp @@ -246,6 +246,8 @@ class CompileBroker: AllStatic { // 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 @@ class CompileBroker: AllStatic { 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 @@ class CompileBroker: AllStatic { 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); diff --git a/src/share/vm/runtime/globals.hpp b/src/share/vm/runtime/globals.hpp index 575e6d316..e8c695756 100644 --- a/src/share/vm/runtime/globals.hpp +++ b/src/share/vm/runtime/globals.hpp @@ -3309,21 +3309,21 @@ class CommandLineFlags { 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, "", \ diff --git a/src/share/vm/runtime/sharedRuntime.cpp b/src/share/vm/runtime/sharedRuntime.cpp index b13fbddc2..fc89af6c4 100644 --- a/src/share/vm/runtime/sharedRuntime.cpp +++ b/src/share/vm/runtime/sharedRuntime.cpp @@ -2595,11 +2595,13 @@ bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length) { #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 @@ nmethod *AdapterHandlerLibrary::create_native_wrapper(methodHandle method, int c 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; } - ResourceMark rm; + 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 @@ nmethod *AdapterHandlerLibrary::create_native_wrapper(methodHandle method, int c 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); + } } - } + } // Unlock AdapterHandlerLibrary_lock - // Must unlock before calling set_code // Install the generated code. if (nm != NULL) { @@ -2666,13 +2669,11 @@ nmethod *AdapterHandlerLibrary::create_native_wrapper(methodHandle method, int c 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)) diff --git a/src/share/vm/runtime/sharedRuntime.hpp b/src/share/vm/runtime/sharedRuntime.hpp index 72f84589e..6fc942452 100644 --- a/src/share/vm/runtime/sharedRuntime.hpp +++ b/src/share/vm/runtime/sharedRuntime.hpp @@ -666,7 +666,7 @@ class AdapterHandlerLibrary: public AllStatic { 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 -- GitLab