diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp index f54308944e2..b77ab569bdd 100644 --- a/src/hotspot/share/compiler/compileBroker.cpp +++ b/src/hotspot/share/compiler/compileBroker.cpp @@ -1069,18 +1069,34 @@ void CompileBroker::init_compiler_sweeper_threads() { void CompileBroker::possibly_add_compiler_threads(JavaThread* THREAD) { + int old_c2_count = 0, new_c2_count = 0, old_c1_count = 0, new_c1_count = 0; + const int c2_tasks_per_thread = 2, c1_tasks_per_thread = 4; + + // Quick check if we already have enough compiler threads without taking the lock. + // Numbers may change concurrently, so we read them again after we have the lock. + if (_c2_compile_queue != nullptr) { + old_c2_count = get_c2_thread_count(); + new_c2_count = MIN2(_c2_count, _c2_compile_queue->size() / c2_tasks_per_thread); + } + if (_c1_compile_queue != nullptr) { + old_c1_count = get_c1_thread_count(); + new_c1_count = MIN2(_c1_count, _c1_compile_queue->size() / c1_tasks_per_thread); + } + if (new_c2_count <= old_c2_count && new_c1_count <= old_c1_count) return; + + // Now, we do the more expensive operations. julong available_memory = os::available_memory(); // If SegmentedCodeCache is off, both values refer to the single heap (with type CodeBlobType::All). - size_t available_cc_np = CodeCache::unallocated_capacity(CodeBlobType::MethodNonProfiled), - available_cc_p = CodeCache::unallocated_capacity(CodeBlobType::MethodProfiled); + size_t available_cc_np = CodeCache::unallocated_capacity(CodeBlobType::MethodNonProfiled), + available_cc_p = CodeCache::unallocated_capacity(CodeBlobType::MethodProfiled); - // Only do attempt to start additional threads if the lock is free. + // Only attempt to start additional threads if the lock is free. if (!CompileThread_lock->try_lock()) return; if (_c2_compile_queue != NULL) { - int old_c2_count = _compilers[1]->num_compiler_threads(); - int new_c2_count = MIN4(_c2_count, - _c2_compile_queue->size() / 2, + old_c2_count = get_c2_thread_count(); + new_c2_count = MIN4(_c2_count, + _c2_compile_queue->size() / c2_tasks_per_thread, (int)(available_memory / (200*M)), (int)(available_cc_np / (128*K))); @@ -1114,7 +1130,7 @@ void CompileBroker::possibly_add_compiler_threads(JavaThread* THREAD) { break; } // Check if another thread has beaten us during the Java calls. - if (_compilers[1]->num_compiler_threads() != i) break; + if (get_c2_thread_count() != i) break; jobject thread_handle = JNIHandles::make_global(thread_oop); assert(compiler2_object(i) == NULL, "Old one must be released!"); _compiler2_objects[i] = thread_handle; @@ -1136,9 +1152,9 @@ void CompileBroker::possibly_add_compiler_threads(JavaThread* THREAD) { } if (_c1_compile_queue != NULL) { - int old_c1_count = _compilers[0]->num_compiler_threads(); - int new_c1_count = MIN4(_c1_count, - _c1_compile_queue->size() / 4, + old_c1_count = get_c1_thread_count(); + new_c1_count = MIN4(_c1_count, + _c1_compile_queue->size() / c1_tasks_per_thread, (int)(available_memory / (100*M)), (int)(available_cc_p / (128*K))); diff --git a/src/hotspot/share/compiler/compileBroker.hpp b/src/hotspot/share/compiler/compileBroker.hpp index 0b721f83121..adf7a3c6a45 100644 --- a/src/hotspot/share/compiler/compileBroker.hpp +++ b/src/hotspot/share/compiler/compileBroker.hpp @@ -88,7 +88,7 @@ class CompileQueue : public CHeapObj { CompileTask* _first_stale; - int _size; + volatile int _size; void purge_stale_tasks(); public: @@ -402,6 +402,8 @@ class CompileBroker: AllStatic { static CompileLog* get_log(CompilerThread* ct); + static int get_c1_thread_count() { return _compilers[0]->num_compiler_threads(); } + static int get_c2_thread_count() { return _compilers[1]->num_compiler_threads(); } static int get_total_compile_count() { return _total_compile_count; } static int get_total_bailout_count() { return _total_bailout_count; } static int get_total_invalidated_count() { return _total_invalidated_count; }