src/share/vm/compiler/compileBroker.cpp

Print this page

        

*** 184,194 **** CompileQueue* CompileBroker::_c2_method_queue = NULL; CompileQueue* CompileBroker::_c1_method_queue = NULL; CompileTask* CompileBroker::_task_free_list = NULL; ! GrowableArray<CompilerThread*>* CompileBroker::_method_threads = NULL; class CompilationLog : public StringEventLog { public: CompilationLog() : StringEventLog("Compilation events") { --- 184,194 ---- CompileQueue* CompileBroker::_c2_method_queue = NULL; CompileQueue* CompileBroker::_c1_method_queue = NULL; CompileTask* CompileBroker::_task_free_list = NULL; ! GrowableArray<CompilerThread*>* CompileBroker::_compiler_threads = NULL; class CompilationLog : public StringEventLog { public: CompilationLog() : StringEventLog("Compilation events") {
*** 585,597 **** log->mark_file_end(); } - // ------------------------------------------------------------------ - // CompileQueue::add - // // Add a CompileTask to a CompileQueue void CompileQueue::add(CompileTask* task) { assert(lock()->owned_by_self(), "must own lock"); task->set_next(NULL); --- 585,594 ----
*** 624,633 **** --- 621,640 ---- // Notify CompilerThreads that a task is available. lock()->notify_all(); } + void CompileQueue::delete_all() { + assert(lock()->owned_by_self(), "must own lock"); + if (_first != NULL) { + for (CompileTask* task = _first; task != NULL; task = task->next()) { + delete task; + } + _first = NULL; + } + } + // ------------------------------------------------------------------ // CompileQueue::get // // Get the next CompileTask from a CompileQueue CompileTask* CompileQueue::get() {
*** 889,902 **** _initialized = true; } ! ! // ------------------------------------------------------------------ ! // CompileBroker::make_compiler_thread ! CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, TRAPS) { CompilerThread* compiler_thread = NULL; Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_0); --- 896,907 ---- _initialized = true; } ! CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, ! AbstractCompiler* comp, TRAPS) { CompilerThread* compiler_thread = NULL; Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_0);
*** 959,968 **** --- 964,974 ---- os::set_native_priority(compiler_thread, native_prio); 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); } // Let go of Threads_lock before yielding
*** 970,1020 **** return compiler_thread; } - // ------------------------------------------------------------------ - // 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 if (c2_compiler_count > 0) { _c2_method_queue = new CompileQueue("C2MethodQueue", MethodCompileQueue_lock); } if (c1_compiler_count > 0) { _c1_method_queue = new CompileQueue("C1MethodQueue", MethodCompileQueue_lock); } int compiler_count = c1_compiler_count + c2_compiler_count; ! _method_threads = new (ResourceObj::C_HEAP, mtCompiler) GrowableArray<CompilerThread*>(compiler_count, true); char name_buffer[256]; for (int i = 0; i < c2_compiler_count; i++) { // 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); } 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); } if (UsePerfData) { ! PerfDataManager::create_constant(SUN_CI, "threads", PerfData::U_Bytes, ! compiler_count, CHECK); } } // Set the methods on the stack as on_stack so that redefine classes doesn't --- 976,1026 ---- return compiler_thread; } 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); + _compilers[1]->set_num_compiler_threads(c2_compiler_count); } if (c1_compiler_count > 0) { _c1_method_queue = new CompileQueue("C1MethodQueue", MethodCompileQueue_lock); + _compilers[0]->set_num_compiler_threads(c1_compiler_count); } int compiler_count = c1_compiler_count + c2_compiler_count; ! _compiler_threads = new (ResourceObj::C_HEAP, mtCompiler) GrowableArray<CompilerThread*>(compiler_count, true); char name_buffer[256]; for (int i = 0; i < c2_compiler_count; i++) { // Create a name for our thread. sprintf(name_buffer, "C2 CompilerThread%d", i); CompilerCounters* counters = new CompilerCounters("compilerThread", i, CHECK); ! // 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); ! // 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); } } // Set the methods on the stack as on_stack so that redefine classes doesn't
*** 1027,1057 **** _c1_method_queue->mark_on_stack(); } } // ------------------------------------------------------------------ - // 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; i<num_threads; i++) { - if (_method_threads->at(i)->task() != NULL) { - return false; - } - } - - // No pending or active compilations. - return true; - } - } - - - // ------------------------------------------------------------------ // CompileBroker::compile_method // // Request compilation of a method. void CompileBroker::compile_method_base(methodHandle method, int osr_bci, --- 1033,1042 ----
*** 1549,1566 **** // waiting on a CompileTask, we know that no one else will // be using this CompileTask; we can free it. free_task(task); } // ------------------------------------------------------------------ // CompileBroker::compiler_thread_loop // // The main loop run by a CompilerThread. 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; // First thread to get here will initialize the compiler interface --- 1534,1642 ---- // waiting on a CompileTask, we know that no one else will // be using this CompileTask; we can free it. 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 + ThreadInVMfromNative tv(thread); + ResetNoHandleMark rnhm; + + if (!comp->is_shark()) { + // Perform per-thread and global initializations + comp->initialize(); + } + } + + if (comp->is_state_failed()) { + disable_compilation_forever(); + // If compiler initialization failed, no compiler thread that is specific to a + // particular compiler runtime will ever start to compile methods. + + // Tiered: If C1 and/or C2 initialization failed, we shut down all compilation. + // We do this to keep things simple. This can be changed if it ever turns out to be + // a problem. + + if (comp->should_perform_shutdown()) { + MutexLocker mu(MethodCompileQueue_lock, thread); + CompileQueue* queue; + if (_c1_method_queue != NULL) { + _c1_method_queue->delete_all(); + queue = _c1_method_queue; + _c1_method_queue = NULL; + delete _c1_method_queue; + } + + if (_c2_method_queue != NULL) { + _c2_method_queue->delete_all(); + queue = _c2_method_queue; + _c2_method_queue = NULL; + delete _c2_method_queue; + } + } + warning("Initialization of %s failed -- shutting down compiler(s)", comp->name()); + + // Free buffer blob, if allocated + if (thread->get_buffer_blob() != NULL) { + CodeCache::free(thread->get_buffer_blob()); + } + + // Set state to shut down + comp->set_shut_down(); + + // Delete compiler runtimes + MutexLocker mu(MethodCompileQueue_lock, thread); + if ((comp->is_c1()) && (_compilers[0] != NULL)) { + delete _compilers[0]; + _compilers[0] = NULL; + } + + if ((comp->is_c2()) && (_compilers[1] != NULL)) { + delete _compilers[1]; + _compilers[1] = NULL; + } + + return false; + } + + // C1 specific check + if ((comp->is_c1()) && (thread->get_buffer_blob() == NULL)) { + warning("Initialization of %s thread failed", comp->name()); + return false; + } + + return true; + } + // ------------------------------------------------------------------ // CompileBroker::compiler_thread_loop // // The main loop run by a CompilerThread. 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; // First thread to get here will initialize the compiler interface
*** 1585,1596 **** os::current_process_id()); log->stamp(); log->end_elem(); } ! while (true) { ! { // We need this HandleMark to avoid leaking VM handles. HandleMark hm(thread); if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) { // the code cache is really full --- 1661,1681 ---- os::current_process_id()); log->stamp(); log->end_elem(); } ! // If compiler thread/runtime initialization fails, exit the compiler thread ! if (!init_compiler_runtime()) { ! return; ! } ! ! // Poll for new compilation tasks as long as the JVM runs. Compilation ! // should only be disabled if something went wrong while initializing the ! // compiler runtimes. This, in turn, should not happen. The only known case ! // when compiler runtime initialization fails is if there is not enough free ! // space in the code cache to generate the necessary stubs, etc. ! while (!is_compilation_disabled_forever()) { // We need this HandleMark to avoid leaking VM handles. HandleMark hm(thread); if (CodeCache::unallocated_capacity() < CodeCacheMinimumFreeSpace) { // the code cache is really full
*** 1640,1653 **** // After compilation is disabled, remove remaining methods from queue method->clear_queued_for_compilation(); } } } - } } - // ------------------------------------------------------------------ // CompileBroker::init_compiler_thread_log // // Set up state required by +LogCompilation. void CompileBroker::init_compiler_thread_log() { --- 1725,1736 ----