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

src/share/vm/compiler/compileBroker.cpp

Print this page

        

*** 154,165 **** 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") { } --- 154,163 ----
*** 647,663 **** // Wake up all threads that block on the queue. lock()->notify_all(); } ! // ------------------------------------------------------------------ ! // CompileQueue::get ! // ! // 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 --- 645,658 ---- // Wake up all threads that block on the queue. lock()->notify_all(); } ! /** ! * Get the next CompileTask from a CompileQueue ! */ CompileTask* CompileQueue::get() { 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 **** // 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 --- 661,670 ----
*** 695,705 **** // 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; } --- 672,681 ----
*** 884,895 **** int c2_count = 1; _compilers[1] = new SharkCompiler(); #endif // SHARK ! // Start the CompilerThreads ! init_compiler_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 = --- 860,871 ---- int c2_count = 1; _compilers[1] = new SharkCompiler(); #endif // SHARK ! // 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 **** _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); 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 --- 965,978 ---- _initialized = true; } ! 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 **** string, CHECK_0); { MutexLocker mu(Threads_lock, THREAD); ! compiler_thread = new CompilerThread(queue, counters); // 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. --- 986,1000 ---- string, CHECK_0); { MutexLocker mu(Threads_lock, THREAD); ! 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 **** // 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){ 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 --- 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 (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(), 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 **** 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); } // 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) { 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 --- 1029,1058 ---- native_prio = os::java_to_os_priority[CriticalPriority]; } else { native_prio = os::java_to_os_priority[NearMaxPriority]; } } ! os::set_native_priority(thread, native_prio); java_lang_Thread::set_daemon(thread_oop()); ! thread->set_threadObj(thread_oop()); ! 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 thread; } ! 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 **** _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_compile_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_compile_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 --- 1065,1100 ---- _compilers[0]->set_num_compiler_threads(c1_compiler_count); } int compiler_count = c1_compiler_count + c2_compiler_count; 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 ! 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 ! 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 **** // 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 ) os::hint_no_preempt(); // trace per thread time and compile statistics CompilerCounters* counters = ((CompilerThread*)thread)->counters(); PerfTraceTimedEvent(counters->time_counter(), counters->compile_counter()); --- 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); 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) { os::hint_no_preempt(); + } // trace per thread time and compile statistics CompilerCounters* counters = ((CompilerThread*)thread)->counters(); PerfTraceTimedEvent(counters->time_counter(), counters->compile_counter());
*** 2105,2118 **** 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()); --- 2079,2088 ----
src/share/vm/compiler/compileBroker.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File