src/share/vm/compiler/compileBroker.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File
*** old/src/share/vm/compiler/compileBroker.cpp	Thu Oct 23 13:40:55 2014
--- new/src/share/vm/compiler/compileBroker.cpp	Thu Oct 23 13:40:53 2014

*** 154,165 **** --- 154,163 ---- long CompileBroker::_peak_compilation_time = 0; CompileQueue* CompileBroker::_c2_compile_queue = NULL; CompileQueue* CompileBroker::_c1_compile_queue = NULL; GrowableArray<CompilerThread*>* CompileBroker::_compiler_threads = NULL; class CompilationLog : public StringEventLog { public: CompilationLog() : StringEventLog("Compilation events") { }
*** 647,663 **** --- 645,658 ---- // Wake up all threads that block on the queue. lock()->notify_all(); } // ------------------------------------------------------------------ // CompileQueue::get ! // // Get the next CompileTask from a CompileQueue + /** + * Get the next CompileTask from a CompileQueue ! */ CompileTask* CompileQueue::get() { NMethodSweeper::possibly_sweep(); MutexLocker locker(lock()); // If _first is NULL we have no more compile jobs. There are two reasons for // having no compile jobs: First, we compiled everything we wanted. Second, // we ran out of code cache so compilation has been disabled. In the latter // case we perform code cache sweeps to free memory such that we can re-enable
*** 666,693 **** --- 661,670 ---- // Exit loop if compilation is disabled forever if (CompileBroker::is_compilation_disabled_forever()) { return NULL; } if (UseCodeCacheFlushing && !CompileBroker::should_compile_new_jobs()) { // Wait a certain amount of time to possibly do another sweep. // We must wait until stack scanning has happened so that we can // transition a method's state from 'not_entrant' to 'zombie'. long wait_time = NmethodSweepCheckInterval * 1000; if (FLAG_IS_DEFAULT(NmethodSweepCheckInterval)) { // Only one thread at a time can do sweeping. Scale the // wait time according to the number of compiler threads. // As a result, the next sweep is likely to happen every 100ms // with an arbitrary number of threads that do sweeping. wait_time = 100 * CICompilerCount; } bool timeout = lock()->wait(!Mutex::_no_safepoint_check_flag, wait_time); if (timeout) { MutexUnlocker ul(lock()); NMethodSweeper::possibly_sweep(); } } else { // If there are no compilation tasks and we can compile new jobs // (i.e., there is enough free space in the code cache) there is // no need to invoke the sweeper. As a result, the hotness of methods // remains unchanged. This behavior is desired, since we want to keep // the stable state, i.e., we do not want to evict methods from the
*** 695,705 **** --- 672,681 ---- // We need a timed wait here, since compiler threads can exit if compilation // is disabled forever. We use 5 seconds wait time; the exiting of compiler threads // is not critical and we do not want idle compiler threads to wake up too often. lock()->wait(!Mutex::_no_safepoint_check_flag, 5*1000); } } if (CompileBroker::is_compilation_disabled_forever()) { return NULL; }
*** 884,895 **** --- 860,871 ---- int c2_count = 1; _compilers[1] = new SharkCompiler(); #endif // SHARK ! // Start the CompilerThreads ! init_compiler_threads(c1_count, c2_count); ! // Start the compiler thread(s) and the sweeper thread ! init_compiler_sweeper_threads(c1_count, c2_count); // totalTime performance counter is always created as it is required // by the implementation of java.lang.management.CompilationMBean. { EXCEPTION_MARK; _perf_total_compilation =
*** 989,1005 **** --- 965,978 ---- _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); ! JavaThread* CompileBroker::make_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, ! AbstractCompiler* comp, bool compiler_thread, TRAPS) { ! JavaThread* thread = NULL; + Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_0); instanceKlassHandle klass (THREAD, k); instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_0); Handle string = java_lang_String::create_from_str(name, CHECK_0); // Initialize thread_oop to put it into the system threadGroup
*** 1013,1023 **** --- 986,1000 ---- string, CHECK_0); { MutexLocker mu(Threads_lock, THREAD); compiler_thread = new CompilerThread(queue, counters); + if (compiler_thread) { + thread = new CompilerThread(queue, counters); + } else { + thread = new CodeCacheSweeperThread(); + } // At this point the new CompilerThread data-races with this startup // thread (which I believe is the primoridal thread and NOT the VM // thread). This means Java bytecodes being executed at startup can // queue compile jobs which will run at whatever default priority the // newly created CompilerThread runs at.
*** 1026,1041 **** --- 1003,1018 ---- // At this point it may be possible that no osthread was created for the // JavaThread due to lack of memory. We would have to throw an exception // in that case. However, since this must work and we do not allow // exceptions anyway, check and abort if this fails. ! if (compiler_thread == NULL || compiler_thread->osthread() == NULL){ ! if (thread == NULL || thread->osthread() == NULL) { vm_exit_during_initialization("java.lang.OutOfMemoryError", os::native_thread_creation_failed_msg()); } - java_lang_Thread::set_thread(thread_oop(), compiler_thread); // Note that this only sets the JavaThread _priority field, which by // definition is limited to Java priorities and not OS priorities. // The os-priority is set in the CompilerThread startup code itself
*** 1052,1079 **** --- 1029,1058 ---- native_prio = os::java_to_os_priority[CriticalPriority]; } else { native_prio = os::java_to_os_priority[NearMaxPriority]; } } - 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); + if (compiler_thread) { ! thread->as_CompilerThread()->set_compiler(comp); + } + Threads::add(thread); + Thread::start(thread); } // Let go of Threads_lock before yielding os::naked_yield(); // make sure that the compiler thread is started early (especially helpful on SOLARIS) - return compiler_thread; } ! void CompileBroker::init_compiler_threads(int c1_compiler_count, int c2_compiler_count) { ! void CompileBroker::init_compiler_sweeper_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
*** 1086,1120 **** --- 1065,1100 ---- _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]; + const bool compiler_thread = true; 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_compile_queue, counters, _compilers[1], CHECK); _compiler_threads->append(new_thread); ! make_thread(name_buffer, _c2_compile_queue, counters, _compilers[1], compiler_thread, CHECK); } 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_compile_queue, counters, _compilers[0], CHECK); _compiler_threads->append(new_thread); ! make_thread(name_buffer, _c1_compile_queue, counters, _compilers[0], compiler_thread, CHECK); } if (UsePerfData) { PerfDataManager::create_constant(SUN_CI, "threads", PerfData::U_Bytes, compiler_count, CHECK); } + + if (MethodFlushing) { + // Initialize the sweeper thread + make_thread("Sweeper thread", NULL, NULL, NULL, false, CHECK); + } } /** * Set the methods on the stack as on_stack so that redefine classes doesn't
*** 1757,1782 **** --- 1737,1756 ---- // 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); // Check if the CodeCache is full int code_blob_type = 0; if (CodeCache::is_full(&code_blob_type)) { // The CodeHeap for code_blob_type is really full handle_full_code_cache(code_blob_type); } CompileTask* task = queue->get(); if (task == NULL) { continue; } // Give compiler threads an extra quanta. They tend to be bursty and // this helps the compiler to finish up the job. ! if( CompilerThreadHintNoPreempt ) ! if (CompilerThreadHintNoPreempt) { os::hint_no_preempt(); + } // trace per thread time and compile statistics CompilerCounters* counters = ((CompilerThread*)thread)->counters(); PerfTraceTimedEvent(counters->time_counter(), counters->compile_counter());
*** 2072,2083 **** --- 2046,2059 ---- } #endif } /** ! * The CodeCache is full. Print out warning and disable compilation ! * or try code cache cleaning so compilation can continue later. ! * The CodeCache is full. Print warning and disable compilation. ! * Schedule code cache cleaning so compilation can continue later. + * This function needs to be called only from CodeCache::allocate(), + * since we currently handle a full code cache uniformly. */ void CompileBroker::handle_full_code_cache(int code_blob_type) { UseInterpreter = true; if (UseCompiler || AlwaysCompileLoopMethods ) { if (xtty != NULL) {
*** 2105,2118 **** --- 2081,2090 ---- if (UseCodeCacheFlushing) { // Since code cache is full, immediately stop new compiles if (CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation)) { NMethodSweeper::log_sweep("disable_compiler"); } // Switch to 'vm_state'. This ensures that possibly_sweep() can be called // without having to consider the state in which the current thread is. ThreadInVMfromUnknown in_vm; NMethodSweeper::possibly_sweep(); } else { disable_compilation_forever(); } CodeCache::report_codemem_full(code_blob_type, should_print_compiler_warning());

src/share/vm/compiler/compileBroker.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File