mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-18 01:54:47 +02:00
8230459: Test failed to resume JVMCI CompilerThread
Reviewed-by: dholmes, kvn
This commit is contained in:
parent
9dd7038c43
commit
0a5f074a77
2 changed files with 64 additions and 5 deletions
|
@ -299,7 +299,7 @@ CompileTaskWrapper::~CompileTaskWrapper() {
|
|||
/**
|
||||
* Check if a CompilerThread can be removed and update count if requested.
|
||||
*/
|
||||
static bool can_remove(CompilerThread *ct, bool do_it) {
|
||||
bool CompileBroker::can_remove(CompilerThread *ct, bool do_it) {
|
||||
assert(UseDynamicNumberOfCompilerThreads, "or shouldn't be here");
|
||||
if (!ReduceNumberOfCompilerThreads) return false;
|
||||
|
||||
|
@ -313,13 +313,32 @@ static bool can_remove(CompilerThread *ct, bool do_it) {
|
|||
// Keep thread alive for at least some time.
|
||||
if (ct->idle_time_millis() < (c1 ? 500 : 100)) return false;
|
||||
|
||||
#if INCLUDE_JVMCI
|
||||
if (compiler->is_jvmci()) {
|
||||
// Handles for JVMCI thread objects may get released concurrently.
|
||||
if (do_it) {
|
||||
assert(CompileThread_lock->owner() == ct, "must be holding lock");
|
||||
} else {
|
||||
// Skip check if it's the last thread and let caller check again.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// We only allow the last compiler thread of each type to get removed.
|
||||
jobject last_compiler = c1 ? CompileBroker::compiler1_object(compiler_count - 1)
|
||||
: CompileBroker::compiler2_object(compiler_count - 1);
|
||||
jobject last_compiler = c1 ? compiler1_object(compiler_count - 1)
|
||||
: compiler2_object(compiler_count - 1);
|
||||
if (ct->threadObj() == JNIHandles::resolve_non_null(last_compiler)) {
|
||||
if (do_it) {
|
||||
assert_locked_or_safepoint(CompileThread_lock); // Update must be consistent.
|
||||
compiler->set_num_compiler_threads(compiler_count - 1);
|
||||
#if INCLUDE_JVMCI
|
||||
if (compiler->is_jvmci()) {
|
||||
// Old j.l.Thread object can die when no longer referenced elsewhere.
|
||||
JNIHandles::destroy_global(compiler2_object(compiler_count - 1));
|
||||
_compiler2_objects[compiler_count - 1] = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -426,7 +445,7 @@ CompileTask* CompileQueue::get() {
|
|||
|
||||
if (UseDynamicNumberOfCompilerThreads && _first == NULL) {
|
||||
// Still nothing to compile. Give caller a chance to stop this thread.
|
||||
if (can_remove(CompilerThread::current(), false)) return NULL;
|
||||
if (CompileBroker::can_remove(CompilerThread::current(), false)) return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -842,10 +861,15 @@ void CompileBroker::init_compiler_sweeper_threads() {
|
|||
char name_buffer[256];
|
||||
|
||||
for (int i = 0; i < _c2_count; i++) {
|
||||
jobject thread_handle = NULL;
|
||||
// Create all j.l.Thread objects for C1 and C2 threads here, but only one
|
||||
// for JVMCI compiler which can create further ones on demand.
|
||||
JVMCI_ONLY(if (!UseJVMCICompiler || !UseDynamicNumberOfCompilerThreads || i == 0) {)
|
||||
// Create a name for our thread.
|
||||
sprintf(name_buffer, "%s CompilerThread%d", _compilers[1]->name(), i);
|
||||
Handle thread_oop = create_thread_oop(name_buffer, CHECK);
|
||||
jobject thread_handle = JNIHandles::make_global(thread_oop);
|
||||
thread_handle = JNIHandles::make_global(thread_oop);
|
||||
JVMCI_ONLY(})
|
||||
_compiler2_objects[i] = thread_handle;
|
||||
_compiler2_logs[i] = NULL;
|
||||
|
||||
|
@ -912,6 +936,39 @@ void CompileBroker::possibly_add_compiler_threads() {
|
|||
(int)(available_cc_np / (128*K)));
|
||||
|
||||
for (int i = old_c2_count; i < new_c2_count; i++) {
|
||||
#if INCLUDE_JVMCI
|
||||
if (UseJVMCICompiler) {
|
||||
// Native compiler threads as used in C1/C2 can reuse the j.l.Thread
|
||||
// objects as their existence is completely hidden from the rest of
|
||||
// the VM (and those compiler threads can't call Java code to do the
|
||||
// creation anyway). For JVMCI we have to create new j.l.Thread objects
|
||||
// as they are visible and we can see unexpected thread lifecycle
|
||||
// transitions if we bind them to new JavaThreads.
|
||||
if (!THREAD->can_call_java()) break;
|
||||
char name_buffer[256];
|
||||
sprintf(name_buffer, "%s CompilerThread%d", _compilers[1]->name(), i);
|
||||
Handle thread_oop;
|
||||
{
|
||||
// We have to give up the lock temporarily for the Java calls.
|
||||
MutexUnlocker mu(CompileThread_lock);
|
||||
thread_oop = create_thread_oop(name_buffer, THREAD);
|
||||
}
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
if (TraceCompilerThreads) {
|
||||
ResourceMark rm;
|
||||
tty->print_cr("JVMCI compiler thread creation failed:");
|
||||
PENDING_EXCEPTION->print();
|
||||
}
|
||||
CLEAR_PENDING_EXCEPTION;
|
||||
break;
|
||||
}
|
||||
// Check if another thread has beaten us during the Java calls.
|
||||
if (_compilers[1]->num_compiler_threads() != 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;
|
||||
}
|
||||
#endif
|
||||
JavaThread *ct = make_thread(compiler2_object(i), _c2_compile_queue, _compilers[1], CHECK);
|
||||
if (ct == NULL) break;
|
||||
_compilers[1]->set_num_compiler_threads(i + 1);
|
||||
|
|
|
@ -395,6 +395,8 @@ public:
|
|||
return _compiler2_objects[idx];
|
||||
}
|
||||
|
||||
static bool can_remove(CompilerThread *ct, bool do_it);
|
||||
|
||||
static CompileLog* get_log(CompilerThread* ct);
|
||||
|
||||
static int get_total_compile_count() { return _total_compile_count; }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue