Mercurial > hg > graal-jvmci-8
changeset 23302:90f7b4c21cfb
thread waiting for blocking JVMCI compilation should not wait on compiler queue forever (JDK-8148507)
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Thu, 04 Feb 2016 15:21:43 +0100 |
parents | 93caf66f5604 |
children | 633cf7bea01d |
files | src/share/vm/compiler/compileBroker.cpp src/share/vm/compiler/compileBroker.hpp src/share/vm/jvmci/jvmciCompiler.hpp |
diffstat | 3 files changed, 47 insertions(+), 35 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/vm/compiler/compileBroker.cpp Thu Feb 04 14:59:52 2016 +0100 +++ b/src/share/vm/compiler/compileBroker.cpp Thu Feb 04 15:21:43 2016 +0100 @@ -1724,50 +1724,57 @@ } #ifdef COMPILERJVMCI -// The number of milliseconds to wait before checking if the -// JVMCI compiler has become blocked during compilation. -static const long BLOCKING_JVMCI_COMPILATION_WAIT_TIMESLICE = 500; +// The number of milliseconds to wait before checking if +// JVMCI compilation has made progress. +static const long JVMCI_COMPILATION_PROGRESS_WAIT_TIMESLICE = 500; -// The number of successive times the above check is allowed to -// see a blocked JVMCI compiler thread before unblocking the -// thread waiting for the compilation to finish. -static const int BLOCKING_JVMCI_COMPILATION_WAIT_TO_UNBLOCK_ATTEMPTS = 5; +// The number of JVMCI compilation progress checks that must fail +// before unblocking a thread waiting for a blocking compilation. +static const int JVMCI_COMPILATION_PROGRESS_WAIT_ATTEMPTS = 5; /** * Waits for a JVMCI compiler to complete a given task. This thread - * waits until either the task completes or it sees the JVMCI compiler - * thread is blocked for N consecutive milliseconds where N is - * BLOCKING_JVMCI_COMPILATION_WAIT_TIMESLICE * - * BLOCKING_JVMCI_COMPILATION_WAIT_TO_UNBLOCK_ATTEMPTS. + * waits until either the task completes or it sees no JVMCI compilation + * progress for N consecutive milliseconds where N is + * JVMCI_COMPILATION_PROGRESS_WAIT_TIMESLICE * + * JVMCI_COMPILATION_PROGRESS_WAIT_ATTEMPTS. * * @return true if this thread needs to free/recycle the task */ -bool CompileBroker::wait_for_jvmci_completion(CompileTask* task, JavaThread* thread) { +bool CompileBroker::wait_for_jvmci_completion(AbstractCompiler* comp, CompileTask* task, JavaThread* thread) { MutexLocker waiter(task->lock(), thread); - int consecutively_blocked = 0; + assert(comp->is_jvmci(), "must be"); + JVMCICompiler* jvmci = (JVMCICompiler*) comp; + int progress_wait_attempts = 0; + int methods_compiled = jvmci->approx_num_methods_compiled(); while (!task->is_complete() && !is_compilation_disabled_forever() && - task->lock()->wait(!Mutex::_no_safepoint_check_flag, BLOCKING_JVMCI_COMPILATION_WAIT_TIMESLICE)) { + task->lock()->wait(!Mutex::_no_safepoint_check_flag, JVMCI_COMPILATION_PROGRESS_WAIT_TIMESLICE)) { CompilerThread* jvmci_compiler_thread = task->jvmci_compiler_thread(); + + bool progress; if (jvmci_compiler_thread != NULL) { - JavaThreadState state; - { - // A JVMCI compiler thread should not disappear at this point - // but let's be extra safe. - MutexLocker mu(Threads_lock, thread); - state = jvmci_compiler_thread->thread_state(); - } - if (state == _thread_blocked) { - if (++consecutively_blocked == BLOCKING_JVMCI_COMPILATION_WAIT_TO_UNBLOCK_ATTEMPTS) { - if (PrintCompilation) { - task->print_compilation(tty, "wait for blocking compilation timed out"); - } - break; + // If the JVMCI compiler thread is not blocked, we deem it to be making progress. + progress = jvmci_compiler_thread->thread_state() != _thread_blocked; + } else { + // Still waiting on JVMCI compiler queue. This thread may be holding a lock + // that all JVMCI compiler threads are blocked on. We use the counter for + // successful JVMCI compilations to determine whether JVMCI compilation + // is still making progress through the JVMCI compiler queue. + progress = jvmci->approx_num_methods_compiled() != methods_compiled; + } + + if (!progress) { + if (++progress_wait_attempts == JVMCI_COMPILATION_PROGRESS_WAIT_ATTEMPTS) { + if (PrintCompilation) { + task->print_compilation(tty, "wait for blocking compilation timed out"); } - } else { - consecutively_blocked = 0; + break; } } else { - // Still waiting on JVMCI compiler queue + progress_wait_attempts = 0; + if (jvmci_compiler_thread == NULL) { + methods_compiled = jvmci->approx_num_methods_compiled(); + } } } task->clear_waiter(); @@ -1792,8 +1799,9 @@ methodHandle method(thread, task->method()); bool free_task = true; #ifdef COMPILERJVMCI - if (compiler(task->comp_level())->is_jvmci()) { - free_task = wait_for_jvmci_completion(task, thread); + AbstractCompiler* comp = compiler(task->comp_level()); + if (comp->is_jvmci()) { + free_task = wait_for_jvmci_completion(comp, task, thread); } else #endif {
--- a/src/share/vm/compiler/compileBroker.hpp Thu Feb 04 14:59:52 2016 +0100 +++ b/src/share/vm/compiler/compileBroker.hpp Thu Feb 04 15:21:43 2016 +0100 @@ -372,7 +372,7 @@ bool blocking); static void wait_for_completion(CompileTask* task); #ifdef COMPILERJVMCI - static bool wait_for_jvmci_completion(CompileTask* task, JavaThread* thread); + static bool wait_for_jvmci_completion(AbstractCompiler* comp, CompileTask* task, JavaThread* thread); #endif static void invoke_compiler_on_method(CompileTask* task);
--- a/src/share/vm/jvmci/jvmciCompiler.hpp Thu Feb 04 14:59:52 2016 +0100 +++ b/src/share/vm/jvmci/jvmciCompiler.hpp Thu Feb 04 15:21:43 2016 +0100 @@ -80,8 +80,12 @@ // Print compilation timers and statistics virtual void print_timers(); - // Print compilation statistics - void reset_compilation_stats(); + /** + * Get the number of methods that have been successfully compiled. + * This is an approximation as updating the counter is not atomic. + */ + int approx_num_methods_compiled() { return _methodsCompiled; } + #endif // COMPILERJVMCI // Print compilation timers and statistics