--- old/src/share/vm/c1/c1_Compiler.cpp 2013-09-26 12:53:12.677847698 +0200 +++ new/src/share/vm/c1/c1_Compiler.cpp 2013-09-26 12:53:12.617847700 +0200 @@ -42,8 +42,6 @@ #include "runtime/interfaceSupport.hpp" #include "runtime/sharedRuntime.hpp" -volatile int Compiler::_runtimes = uninitialized; - Compiler::Compiler() { } @@ -53,15 +51,13 @@ } -void Compiler::initialize_all() { +void Compiler::init_c1_runtime() { BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob(); Arena* arena = new (mtCompiler) Arena(); Runtime1::initialize(buffer_blob); FrameMap::initialize(); // initialize data structures ValueType::initialize(arena); - // Instruction::initialize(); - // BlockBegin::initialize(); GraphBuilder::initialize(); // note: to use more than one instance of LinearScan at a time this function call has to // be moved somewhere outside of this constructor: @@ -70,32 +66,35 @@ void Compiler::initialize() { - if (_runtimes != initialized) { - initialize_runtimes( initialize_all, &_runtimes); + // Buffer blob must be allocated per C1 compiler thread at startup + BufferBlob* buffer_blob = init_buffer_blob(); + if (buffer_blob == NULL) { + // If the state is initialized, other compiler threads could have + // had enough space to allocate memory + if (!is_initialized()) { + set_state(failed); + } + } + + if (should_perform_init()) { + init_c1_runtime(); + set_state(initialized); } - mark_initialized(); } -BufferBlob* Compiler::get_buffer_blob(ciEnv* env) { +BufferBlob* Compiler::init_buffer_blob() { // Allocate buffer blob once at startup since allocation for each // compilation seems to be too expensive (at least on Intel win32). - BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob(); - if (buffer_blob != NULL) { - return buffer_blob; - } + assert (CompilerThread::current()->get_buffer_blob() == NULL, "Should initialize only once"); // setup CodeBuffer. Preallocate a BufferBlob of size // NMethodSizeLimit plus some extra space for constants. int code_buffer_size = Compilation::desired_max_code_buffer_size() + Compilation::desired_max_constant_size(); - buffer_blob = BufferBlob::create("Compiler1 temporary CodeBuffer", - code_buffer_size); - if (buffer_blob == NULL) { - CompileBroker::handle_full_code_cache(); - env->record_failure("CodeCache is full"); - } else { + BufferBlob* buffer_blob = BufferBlob::create("C1 temporary CodeBuffer", code_buffer_size); + if (buffer_blob != NULL) { CompilerThread::current()->set_buffer_blob(buffer_blob); } @@ -104,15 +103,8 @@ void Compiler::compile_method(ciEnv* env, ciMethod* method, int entry_bci) { - BufferBlob* buffer_blob = Compiler::get_buffer_blob(env); - if (buffer_blob == NULL) { - return; - } - - if (!is_initialized()) { - initialize(); - } - + BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob(); + assert(buffer_blob != NULL, "Must exist"); // invoke compilation { // We are nested here because we need for the destructor --- old/src/share/vm/c1/c1_Compiler.hpp 2013-09-26 12:53:12.909847692 +0200 +++ new/src/share/vm/c1/c1_Compiler.hpp 2013-09-26 12:53:12.857847693 +0200 @@ -30,11 +30,9 @@ // There is one instance of the Compiler per CompilerThread. class Compiler: public AbstractCompiler { - private: - - // Tracks whether runtime has been initialized - static volatile int _runtimes; + static void init_c1_runtime(); + BufferBlob* init_buffer_blob(); public: // Creation @@ -46,19 +44,12 @@ virtual bool is_c1() { return true; }; - BufferBlob* get_buffer_blob(ciEnv* env); - // Missing feature tests virtual bool supports_native() { return true; } virtual bool supports_osr () { return true; } - // Customization - virtual bool needs_adapters () { return false; } - virtual bool needs_stubs () { return false; } - // Initialization virtual void initialize(); - static void initialize_all(); // Compilation entry point for methods virtual void compile_method(ciEnv* env, ciMethod* target, int entry_bci); --- old/src/share/vm/code/codeBlob.cpp 2013-09-26 12:53:13.137847685 +0200 +++ new/src/share/vm/code/codeBlob.cpp 2013-09-26 12:53:13.085847687 +0200 @@ -245,8 +245,8 @@ } -void* BufferBlob::operator new(size_t s, unsigned size) throw() { - void* p = CodeCache::allocate(size); +void* BufferBlob::operator new(size_t s, unsigned size, bool is_critical) throw() { + void* p = CodeCache::allocate(size, is_critical); return p; } @@ -277,7 +277,9 @@ unsigned int size = allocation_size(cb, sizeof(AdapterBlob)); { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - blob = new (size) AdapterBlob(size, cb); + // The parameter 'true' indicates a critical memory allocation. + // This means that CodeCacheMinimumFreeSpace is used, if necessary + blob = new (size, true) AdapterBlob(size, cb); } // Track memory usage statistic after releasing CodeCache_lock MemoryService::track_code_cache_memory_usage(); @@ -299,7 +301,9 @@ size += round_to(buffer_size, oopSize); { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - blob = new (size) MethodHandlesAdapterBlob(size); + // The parameter 'true' indicates a critical memory allocation. + // This means that CodeCacheMinimumFreeSpace is used, if necessary + blob = new (size, true) MethodHandlesAdapterBlob(size); } // Track memory usage statistic after releasing CodeCache_lock MemoryService::track_code_cache_memory_usage(); --- old/src/share/vm/code/codeBlob.hpp 2013-09-26 12:53:13.361847678 +0200 +++ new/src/share/vm/code/codeBlob.hpp 2013-09-26 12:53:13.317847680 +0200 @@ -209,7 +209,7 @@ BufferBlob(const char* name, int size); BufferBlob(const char* name, int size, CodeBuffer* cb); - void* operator new(size_t s, unsigned size) throw(); + void* operator new(size_t s, unsigned size, bool is_critical = false) throw(); public: // Creation @@ -253,7 +253,6 @@ class MethodHandlesAdapterBlob: public BufferBlob { private: MethodHandlesAdapterBlob(int size) : BufferBlob("MethodHandles adapters", size) {} - MethodHandlesAdapterBlob(int size, CodeBuffer* cb) : BufferBlob("MethodHandles adapters", size, cb) {} public: // Creation --- old/src/share/vm/compiler/abstractCompiler.cpp 2013-09-26 12:53:13.585847672 +0200 +++ new/src/share/vm/compiler/abstractCompiler.cpp 2013-09-26 12:53:13.537847673 +0200 @@ -25,40 +25,29 @@ #include "precompiled.hpp" #include "compiler/abstractCompiler.hpp" #include "runtime/mutexLocker.hpp" -void AbstractCompiler::initialize_runtimes(initializer f, volatile int* state) { - if (*state != initialized) { - // We are thread in native here... - CompilerThread* thread = CompilerThread::current(); - bool do_initialization = false; - { - ThreadInVMfromNative tv(thread); - ResetNoHandleMark rnhm; - MutexLocker only_one(CompileThread_lock, thread); - if ( *state == uninitialized) { - do_initialization = true; - *state = initializing; - } else { - while (*state == initializing ) { - CompileThread_lock->wait(); - } +bool AbstractCompiler::should_perform_init() { + if (_compiler_state != initialized) { + MutexLocker only_one(CompileThread_lock); + + if (_compiler_state == uninitialized) { + _compiler_state = initializing; + return true; + } else { + while (_compiler_state == initializing ) { + CompileThread_lock->wait(); } } - if (do_initialization) { - // We can not hold any locks here since JVMTI events may call agents - - // Compiler(s) run as native - - (*f)(); + } + return false; +} - // To in_vm so we can use the lock +void AbstractCompiler::set_state(int state) { + assert((_compiler_state == initializing) || (_compiler_state == failed), "wrong state"); + MutexLocker only_one(CompileThread_lock); - ThreadInVMfromNative tv(thread); - ResetNoHandleMark rnhm; - MutexLocker only_one(CompileThread_lock, thread); - assert(*state == initializing, "wrong state"); - *state = initialized; - CompileThread_lock->notify_all(); - } - } + // The state of the compiler could have been changed by another thread if + // memory allocation of the buffer blob failed. + _compiler_state = state; + CompileThread_lock->notify_all(); } --- old/src/share/vm/compiler/abstractCompiler.hpp 2013-09-26 12:53:13.813847665 +0200 +++ new/src/share/vm/compiler/abstractCompiler.hpp 2013-09-26 12:53:13.761847667 +0200 @@ -27,22 +27,18 @@ #include "ci/compilerInterface.hpp" -typedef void (*initializer)(void); - class AbstractCompiler : public CHeapObj { - private: - bool _is_initialized; // Mark whether compiler object is initialized - protected: + volatile int _compiler_state; // Used for tracking global state of compiler runtime initialization - enum { uninitialized, initializing, initialized }; + enum { uninitialized, initializing, initialized, failed }; - // This method will call the initialization method "f" once (per compiler class/subclass) - // and do so without holding any locks - void initialize_runtimes(initializer f, volatile int* state); + // This method returns true for the first compiler thread that reaches that methods. + // This thread will initialize the compiler runtime. + bool should_perform_init(); public: - AbstractCompiler() : _is_initialized(false) {} + AbstractCompiler() : _compiler_state(uninitialized) {} // Name of this compiler virtual const char* name() = 0; @@ -74,17 +70,14 @@ #endif // TIERED // Customization - virtual bool needs_stubs () = 0; - - void mark_initialized() { _is_initialized = true; } - bool is_initialized() { return _is_initialized; } - - virtual void initialize() = 0; + virtual void initialize () = 0; + // Get/set state of compiler objects + bool is_initialized () { return _compiler_state == initialized; } + bool is_state_failed () { return _compiler_state == failed; } + void set_state (int state); // Compilation entry point for methods - virtual void compile_method(ciEnv* env, - ciMethod* target, - int entry_bci) { + virtual void compile_method(ciEnv* env, ciMethod* target, int entry_bci) { ShouldNotReachHere(); } --- old/src/share/vm/compiler/compileBroker.cpp 2013-09-26 12:53:14.037847659 +0200 +++ new/src/share/vm/compiler/compileBroker.cpp 2013-09-26 12:53:13.985847660 +0200 @@ -186,7 +186,7 @@ CompileQueue* CompileBroker::_c1_method_queue = NULL; CompileTask* CompileBroker::_task_free_list = NULL; -GrowableArray* CompileBroker::_method_threads = NULL; +GrowableArray* CompileBroker::_compiler_threads = NULL; class CompilationLog : public StringEventLog { @@ -874,10 +874,8 @@ } - -// ------------------------------------------------------------------ -// CompileBroker::make_compiler_thread -CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, TRAPS) { +CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, + AbstractCompiler* comp, TRAPS) { CompilerThread* compiler_thread = NULL; Klass* k = @@ -944,6 +942,7 @@ java_lang_Thread::set_daemon(thread_oop()); compiler_thread->set_threadObj(thread_oop()); + compiler_thread->set_compiler(comp); Threads::add(compiler_thread); Thread::start(compiler_thread); } @@ -955,15 +954,12 @@ } -// ------------------------------------------------------------------ -// CompileBroker::init_compiler_threads -// -// Initialize the compilation queue void CompileBroker::init_compiler_threads(int c1_compiler_count, int c2_compiler_count) { EXCEPTION_MARK; #if !defined(ZERO) && !defined(SHARK) assert(c2_compiler_count > 0 || c1_compiler_count > 0, "No compilers?"); #endif // !ZERO && !SHARK + // Initialize the compilation queue if (c2_compiler_count > 0) { _c2_method_queue = new CompileQueue("C2MethodQueue", MethodCompileQueue_lock); } @@ -973,7 +969,7 @@ int compiler_count = c1_compiler_count + c2_compiler_count; - _method_threads = + _compiler_threads = new (ResourceObj::C_HEAP, mtCompiler) GrowableArray(compiler_count, true); char name_buffer[256]; @@ -981,21 +977,22 @@ // Create a name for our thread. sprintf(name_buffer, "C2 CompilerThread%d", i); CompilerCounters* counters = new CompilerCounters("compilerThread", i, CHECK); - CompilerThread* new_thread = make_compiler_thread(name_buffer, _c2_method_queue, counters, CHECK); - _method_threads->append(new_thread); + // Shark and C2 + CompilerThread* new_thread = make_compiler_thread(name_buffer, _c2_method_queue, counters, _compilers[1], CHECK); + _compiler_threads->append(new_thread); } for (int i = c2_compiler_count; i < compiler_count; i++) { // Create a name for our thread. sprintf(name_buffer, "C1 CompilerThread%d", i); CompilerCounters* counters = new CompilerCounters("compilerThread", i, CHECK); - CompilerThread* new_thread = make_compiler_thread(name_buffer, _c1_method_queue, counters, CHECK); - _method_threads->append(new_thread); + // C1 + CompilerThread* new_thread = make_compiler_thread(name_buffer, _c1_method_queue, counters, _compilers[0], CHECK); + _compiler_threads->append(new_thread); } if (UsePerfData) { - PerfDataManager::create_constant(SUN_CI, "threads", PerfData::U_Bytes, - compiler_count, CHECK); + PerfDataManager::create_constant(SUN_CI, "threads", PerfData::U_Bytes, compiler_count, CHECK); } } @@ -1012,27 +1009,6 @@ } // ------------------------------------------------------------------ -// CompileBroker::is_idle -bool CompileBroker::is_idle() { - if (_c2_method_queue != NULL && !_c2_method_queue->is_empty()) { - return false; - } else if (_c1_method_queue != NULL && !_c1_method_queue->is_empty()) { - return false; - } else { - int num_threads = _method_threads->length(); - for (int i=0; iat(i)->task() != NULL) { - return false; - } - } - - // No pending or active compilations. - return true; - } -} - - -// ------------------------------------------------------------------ // CompileBroker::compile_method // // Request compilation of a method. @@ -1541,6 +1517,51 @@ free_task(task); } +// Initialize compiler thread(s) + compiler object(s). +bool CompileBroker::init_compiler_runtime() { + CompilerThread* thread = CompilerThread::current(); + AbstractCompiler* comp = thread->compiler(); + // Final sanity check - the compiler object must exist + guarantee(comp != NULL, "Compiler object must exist"); + + int system_dictionary_modification_counter; + { + MutexLocker locker(Compile_lock, thread); + system_dictionary_modification_counter = SystemDictionary::number_of_modifications(); + } + + { + // Must switch to native to allocate ci_env + ThreadToNativeFromVM ttn(thread); + ciEnv ci_env(NULL, system_dictionary_modification_counter); + // Cache Jvmti state + ci_env.cache_jvmti_state(); + // Cache DTrace flags + ci_env.cache_dtrace_flags(); + + // Switch back to VM state to to compiler initialization + CompilerThread* thread = CompilerThread::current(); + ThreadInVMfromNative tv(thread); + ResetNoHandleMark rnhm; + + if (!comp->is_shark()) { + // Perform per-thread and global initializations + comp->initialize(); + if ((thread->compiler()->is_c1()) && (thread->get_buffer_blob() == NULL)) { + warning("Initialization of %s thread failed", comp->name()); + return false; + } + } + } + + if (comp->is_state_failed()) { + warning("Initialization of %s thread failed", comp->name()); + return false; + } + + return true; +} + // ------------------------------------------------------------------ // CompileBroker::compiler_thread_loop // @@ -1548,7 +1569,6 @@ void CompileBroker::compiler_thread_loop() { CompilerThread* thread = CompilerThread::current(); CompileQueue* queue = thread->queue(); - // For the thread that initializes the ciObjectFactory // this resource mark holds all the shared objects ResourceMark rm; @@ -1577,6 +1597,11 @@ log->end_elem(); } + // If compiler thread/runtime initialization fails, exit the compiler thread + if (!init_compiler_runtime()) { + return; + } + while (true) { { // We need this HandleMark to avoid leaking VM handles. --- old/src/share/vm/compiler/compileBroker.hpp 2013-09-26 12:53:14.293847651 +0200 +++ new/src/share/vm/compiler/compileBroker.hpp 2013-09-26 12:53:14.245847653 +0200 @@ -266,7 +266,7 @@ static CompileQueue* _c1_method_queue; static CompileTask* _task_free_list; - static GrowableArray* _method_threads; + static GrowableArray* _compiler_threads; // performance counters static PerfCounter* _perf_total_compilation; @@ -311,7 +311,7 @@ static int _sum_nmethod_code_size; static long _peak_compilation_time; - static CompilerThread* make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, TRAPS); + static CompilerThread* make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, AbstractCompiler* comp, TRAPS); 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); @@ -351,6 +351,8 @@ if (is_c1_compile(comp_level)) return _c1_method_queue; return NULL; } + static bool init_compiler_runtime(); + public: enum { // The entry bci used for non-OSR compilations. @@ -378,9 +380,7 @@ const char* comment, Thread* thread); static void compiler_thread_loop(); - static uint get_compilation_id() { return _compilation_id; } - static bool is_idle(); // Set _should_block. // Call this from the VM, with Threads_lock held and a safepoint requested. --- old/src/share/vm/opto/c2compiler.cpp 2013-09-26 12:53:14.521847645 +0200 +++ new/src/share/vm/opto/c2compiler.cpp 2013-09-26 12:53:14.473847646 +0200 @@ -44,9 +44,6 @@ # include "adfiles/ad_ppc.hpp" #endif - -volatile int C2Compiler::_runtimes = uninitialized; - // register information defined by ADLC extern const char register_save_policy[]; extern const int register_save_type[]; @@ -57,7 +54,7 @@ const char* C2Compiler::retry_no_escape_analysis() { return "retry without escape analysis"; } -void C2Compiler::initialize_runtime() { +bool C2Compiler::init_c2_runtime() { // Check assumptions used while running ADLC Compile::adlc_verification(); @@ -90,41 +87,31 @@ CompilerThread* thread = CompilerThread::current(); - HandleMark handle_mark(thread); - - OptoRuntime::generate(thread->env()); - + HandleMark handle_mark(thread); + return OptoRuntime::generate(thread->env()); } void C2Compiler::initialize() { - - // This method can only be called once per C2Compiler object // The first compiler thread that gets here will initialize the - // small amount of global state (and runtime stubs) that c2 needs. + // small amount of global state (and runtime stubs) that C2 needs. // There is a race possible once at startup and then we're fine // Note that this is being called from a compiler thread not the // main startup thread. - - if (_runtimes != initialized) { - initialize_runtimes( initialize_runtime, &_runtimes); + if (should_perform_init()) { + bool successful = C2Compiler::init_c2_runtime(); + int new_state = (successful) ? initialized : failed; + set_state(new_state); } - - // Mark this compiler object as ready to roll - mark_initialized(); } -void C2Compiler::compile_method(ciEnv* env, - ciMethod* target, - int entry_bci) { - if (!is_initialized()) { - initialize(); - } +void C2Compiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci) { + assert(is_initialized(), "Compiler thread must be initialized"); + bool subsume_loads = SubsumeLoads; - bool do_escape_analysis = DoEscapeAnalysis && - !env->jvmti_can_access_local_variables(); + bool do_escape_analysis = DoEscapeAnalysis && !env->jvmti_can_access_local_variables(); bool eliminate_boxing = EliminateAutoBox; while (!env->failing()) { // Attempt to compile while subsuming loads into machine instructions. --- old/src/share/vm/opto/c2compiler.hpp 2013-09-26 12:53:14.745847638 +0200 +++ new/src/share/vm/opto/c2compiler.hpp 2013-09-26 12:53:14.693847639 +0200 @@ -28,24 +28,17 @@ #include "compiler/abstractCompiler.hpp" class C2Compiler : public AbstractCompiler { -private: - - static void initialize_runtime(); + private: + static bool init_c2_runtime(); public: // Name const char *name() { return "C2"; } - static volatile int _runtimes; - #ifdef TIERED virtual bool is_c2() { return true; }; #endif // TIERED - // Customization - bool needs_adapters () { return true; } - bool needs_stubs () { return true; } - void initialize(); // Compilation entry point for methods --- old/src/share/vm/opto/runtime.cpp 2013-09-26 12:53:14.965847632 +0200 +++ new/src/share/vm/opto/runtime.cpp 2013-09-26 12:53:14.917847633 +0200 @@ -138,9 +138,10 @@ #define gen(env, var, type_func_gen, c_func, fancy_jump, pass_tls, save_arg_regs, return_pc) \ - var = generate_stub(env, type_func_gen, CAST_FROM_FN_PTR(address, c_func), #var, fancy_jump, pass_tls, save_arg_regs, return_pc) + var = generate_stub(env, type_func_gen, CAST_FROM_FN_PTR(address, c_func), #var, fancy_jump, pass_tls, save_arg_regs, return_pc); \ + if (var == NULL) { return false; } -void OptoRuntime::generate(ciEnv* env) { +bool OptoRuntime::generate(ciEnv* env) { generate_exception_blob(); @@ -158,7 +159,7 @@ gen(env, _multianewarrayN_Java , multianewarrayN_Type , multianewarrayN_C , 0 , true , false, false); gen(env, _g1_wb_pre_Java , g1_wb_pre_Type , SharedRuntime::g1_wb_pre , 0 , false, false, false); gen(env, _g1_wb_post_Java , g1_wb_post_Type , SharedRuntime::g1_wb_post , 0 , false, false, false); - gen(env, _complete_monitor_locking_Java , complete_monitor_enter_Type , SharedRuntime::complete_monitor_locking_C , 0 , false, false, false); + gen(env, _complete_monitor_locking_Java , complete_monitor_enter_Type , SharedRuntime::complete_monitor_locking_C, 0, false, false, false); gen(env, _rethrow_Java , rethrow_Type , rethrow_C , 2 , true , false, true ); gen(env, _slow_arraycopy_Java , slow_arraycopy_Type , SharedRuntime::slow_arraycopy_C , 0 , false, false, false); @@ -168,7 +169,7 @@ gen(env, _zap_dead_Java_locals_Java , zap_dead_locals_Type , zap_dead_Java_locals_C , 0 , false, true , false ); gen(env, _zap_dead_native_locals_Java , zap_dead_locals_Type , zap_dead_native_locals_C , 0 , false, true , false ); # endif - + return true; } #undef gen --- old/src/share/vm/opto/runtime.hpp 2013-09-26 12:53:15.213847624 +0200 +++ new/src/share/vm/opto/runtime.hpp 2013-09-26 12:53:15.161847626 +0200 @@ -203,8 +203,10 @@ static bool is_callee_saved_register(MachRegisterNumbers reg); - // One time only generate runtime code stubs - static void generate(ciEnv* env); + // One time only generate runtime code stubs. Returns true + // when runtime stubs have been generated successfully and + // false otherwise. + static bool generate(ciEnv* env); // Returns the name of a stub static const char* stub_name(address entry); --- old/src/share/vm/runtime/thread.cpp 2013-09-26 12:53:15.433847618 +0200 +++ new/src/share/vm/runtime/thread.cpp 2013-09-26 12:53:15.385847619 +0200 @@ -1452,7 +1452,6 @@ _interp_only_mode = 0; _special_runtime_exit_condition = _no_async_condition; _pending_async_exception = NULL; - _is_compiling = false; _thread_stat = NULL; _thread_stat = new ThreadStatistics(); _blocked_on_compilation = false; @@ -1813,7 +1812,8 @@ // Call Thread.exit(). We try 3 times in case we got another Thread.stop during // the execution of the method. If that is not enough, then we don't really care. Thread.stop // is deprecated anyhow. - { int count = 3; + if (!is_Compiler_thread()) { + int count = 3; while (java_lang_Thread::threadGroup(threadObj()) != NULL && (count-- > 0)) { EXCEPTION_MARK; JavaValue result(T_VOID); @@ -1826,7 +1826,6 @@ CLEAR_PENDING_EXCEPTION; } } - // notify JVMTI if (JvmtiExport::should_post_thread_life()) { JvmtiExport::post_thread_end(this); @@ -3237,6 +3236,7 @@ _counters = counters; _buffer_blob = NULL; _scanned_nmethod = NULL; + _compiler = NULL; #ifndef PRODUCT _ideal_graph_printer = NULL; @@ -3273,8 +3273,6 @@ // All JavaThreads #define ALL_JAVA_THREADS(X) for (JavaThread* X = _thread_list; X; X = X->next()) -void os_stream(); - // All JavaThreads + all non-JavaThreads (i.e., every thread in the system) void Threads::threads_do(ThreadClosure* tc) { assert_locked_or_safepoint(Threads_lock); --- old/src/share/vm/runtime/thread.hpp 2013-09-26 12:53:15.717847610 +0200 +++ new/src/share/vm/runtime/thread.hpp 2013-09-26 12:53:15.665847611 +0200 @@ -923,9 +923,6 @@ volatile address _exception_handler_pc; // PC for handler of exception volatile int _is_method_handle_return; // true (== 1) if the current exception PC is a MethodHandle call site. - // support for compilation - bool _is_compiling; // is true if a compilation is active inthis thread (one compilation per thread possible) - // support for JNI critical regions jint _jni_active_critical; // count of entries into JNI critical region @@ -1005,10 +1002,6 @@ // Testers virtual bool is_Java_thread() const { return true; } - // compilation - void set_is_compiling(bool f) { _is_compiling = f; } - bool is_compiling() const { return _is_compiling; } - // Thread chain operations JavaThread* next() const { return _next; } void set_next(JavaThread* p) { _next = p; } @@ -1811,13 +1804,14 @@ private: CompilerCounters* _counters; - ciEnv* _env; - CompileLog* _log; - CompileTask* _task; - CompileQueue* _queue; - BufferBlob* _buffer_blob; + ciEnv* _env; + CompileLog* _log; + CompileTask* _task; + CompileQueue* _queue; + BufferBlob* _buffer_blob; - nmethod* _scanned_nmethod; // nmethod being scanned by the sweeper + nmethod* _scanned_nmethod; // nmethod being scanned by the sweeper + AbstractCompiler* _compiler; public: @@ -1829,14 +1823,17 @@ // Hide this compiler thread from external view. bool is_hidden_from_external_view() const { return true; } - CompileQueue* queue() { return _queue; } - CompilerCounters* counters() { return _counters; } + void set_compiler(AbstractCompiler* c) { _compiler = c; } + AbstractCompiler* compiler() const { return _compiler; } + + CompileQueue* queue() const { return _queue; } + CompilerCounters* counters() const { return _counters; } // Get/set the thread's compilation environment. ciEnv* env() { return _env; } void set_env(ciEnv* env) { _env = env; } - BufferBlob* get_buffer_blob() { return _buffer_blob; } + BufferBlob* get_buffer_blob() const { return _buffer_blob; } void set_buffer_blob(BufferBlob* b) { _buffer_blob = b; }; // Get/set the thread's logging information --- old/src/share/vm/runtime/vmStructs.cpp 2013-09-26 12:53:15.961847602 +0200 +++ new/src/share/vm/runtime/vmStructs.cpp 2013-09-26 12:53:15.909847604 +0200 @@ -909,7 +909,6 @@ volatile_nonstatic_field(JavaThread, _exception_oop, oop) \ volatile_nonstatic_field(JavaThread, _exception_pc, address) \ volatile_nonstatic_field(JavaThread, _is_method_handle_return, int) \ - nonstatic_field(JavaThread, _is_compiling, bool) \ nonstatic_field(JavaThread, _special_runtime_exit_condition, JavaThread::AsyncRequests) \ nonstatic_field(JavaThread, _saved_exception_pc, address) \ volatile_nonstatic_field(JavaThread, _thread_state, JavaThreadState) \ --- old/src/share/vm/shark/sharkCompiler.cpp 2013-09-26 12:53:16.225847595 +0200 +++ new/src/share/vm/shark/sharkCompiler.cpp 2013-09-26 12:53:16.173847596 +0200 @@ -133,11 +133,10 @@ exit(1); } - execution_engine()->addModule( - _native_context->module()); + execution_engine()->addModule(_native_context->module()); // All done - mark_initialized(); + set_state(initialized); } void SharkCompiler::initialize() { --- old/src/share/vm/shark/sharkCompiler.hpp 2013-09-26 12:53:16.461847588 +0200 +++ new/src/share/vm/shark/sharkCompiler.hpp 2013-09-26 12:53:16.405847589 +0200 @@ -50,10 +50,6 @@ return ! (method->is_method_handle_intrinsic() || method->is_compiled_lambda_form()); } - // Customization - bool needs_adapters() { return false; } - bool needs_stubs() { return false; } - // Initialization void initialize();