--- a/src/hotspot/share/compiler/compileBroker.cpp Wed Nov 13 17:24:53 2019 +0800
+++ b/src/hotspot/share/compiler/compileBroker.cpp Mon Oct 21 19:58:16 2019 +0200
@@ -299,7 +299,7 @@
/**
* 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 @@
// 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 @@
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 @@
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 @@
(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);
--- a/src/hotspot/share/compiler/compileBroker.hpp Wed Nov 13 17:24:53 2019 +0800
+++ b/src/hotspot/share/compiler/compileBroker.hpp Mon Oct 21 19:58:16 2019 +0200
@@ -395,6 +395,8 @@
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; }