Skip to content

Commit da09eab

Browse files
author
Tom Rodriguez
committed
8319980: [JVMCI] libgraal should reuse Thread instances as C2 does
Reviewed-by: dnsimon, kvn
1 parent 33b26f7 commit da09eab

File tree

2 files changed

+23
-30
lines changed

2 files changed

+23
-30
lines changed

src/hotspot/share/compiler/compileBroker.cpp

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ bool CompileBroker::can_remove(CompilerThread *ct, bool do_it) {
278278
if (ct->idle_time_millis() < (c1 ? 500 : 100)) return false;
279279

280280
#if INCLUDE_JVMCI
281-
if (compiler->is_jvmci()) {
281+
if (compiler->is_jvmci() && !UseJVMCINativeLibrary) {
282282
// Handles for JVMCI thread objects may get released concurrently.
283283
if (do_it) {
284284
assert(CompileThread_lock->owner() == ct, "must be holding lock");
@@ -297,7 +297,7 @@ bool CompileBroker::can_remove(CompilerThread *ct, bool do_it) {
297297
assert_locked_or_safepoint(CompileThread_lock); // Update must be consistent.
298298
compiler->set_num_compiler_threads(compiler_count - 1);
299299
#if INCLUDE_JVMCI
300-
if (compiler->is_jvmci()) {
300+
if (compiler->is_jvmci() && !UseJVMCINativeLibrary) {
301301
// Old j.l.Thread object can die when no longer referenced elsewhere.
302302
JNIHandles::destroy_global(compiler2_object(compiler_count - 1));
303303
_compiler2_objects[compiler_count - 1] = nullptr;
@@ -772,11 +772,6 @@ void CompileBroker::compilation_init(JavaThread* THREAD) {
772772
_initialized = true;
773773
}
774774

775-
Handle CompileBroker::create_thread_oop(const char* name, TRAPS) {
776-
Handle thread_oop = JavaThread::create_system_thread_object(name, CHECK_NH);
777-
return thread_oop;
778-
}
779-
780775
#if defined(ASSERT) && COMPILER2_OR_JVMCI
781776
// Stress testing. Dedicated threads revert optimizations based on escape analysis concurrently to
782777
// the running java application. Configured with vm options DeoptimizeObjectsALot*.
@@ -923,6 +918,13 @@ static bool trace_compiler_threads() {
923918
return TraceCompilerThreads || lt.is_enabled();
924919
}
925920

921+
static jobject create_compiler_thread(AbstractCompiler* compiler, int i, TRAPS) {
922+
char name_buffer[256];
923+
os::snprintf_checked(name_buffer, sizeof(name_buffer), "%s CompilerThread%d", compiler->name(), i);
924+
Handle thread_oop = JavaThread::create_system_thread_object(name_buffer, CHECK_NULL);
925+
return JNIHandles::make_global(thread_oop);
926+
}
927+
926928
static void print_compiler_threads(stringStream& msg) {
927929
if (TraceCompilerThreads) {
928930
tty->print_cr("%7d %s", (int)tty->time_stamp().milliseconds(), msg.as_string());
@@ -953,18 +955,9 @@ void CompileBroker::init_compiler_threads() {
953955
_compiler1_logs = NEW_C_HEAP_ARRAY(CompileLog*, _c1_count, mtCompiler);
954956
}
955957

956-
char name_buffer[256];
957-
958958
for (int i = 0; i < _c2_count; i++) {
959-
jobject thread_handle = nullptr;
960-
// Create all j.l.Thread objects for C1 and C2 threads here, but only one
961-
// for JVMCI compiler which can create further ones on demand.
962-
JVMCI_ONLY(if (!UseJVMCICompiler || !UseDynamicNumberOfCompilerThreads || i == 0) {)
963959
// Create a name for our thread.
964-
os::snprintf_checked(name_buffer, sizeof(name_buffer), "%s CompilerThread%d", _compilers[1]->name(), i);
965-
Handle thread_oop = create_thread_oop(name_buffer, CHECK);
966-
thread_handle = JNIHandles::make_global(thread_oop);
967-
JVMCI_ONLY(})
960+
jobject thread_handle = create_compiler_thread(_compilers[1], i, CHECK);
968961
_compiler2_objects[i] = thread_handle;
969962
_compiler2_logs[i] = nullptr;
970963

@@ -985,9 +978,7 @@ void CompileBroker::init_compiler_threads() {
985978

986979
for (int i = 0; i < _c1_count; i++) {
987980
// Create a name for our thread.
988-
os::snprintf_checked(name_buffer, sizeof(name_buffer), "C1 CompilerThread%d", i);
989-
Handle thread_oop = create_thread_oop(name_buffer, CHECK);
990-
jobject thread_handle = JNIHandles::make_global(thread_oop);
981+
jobject thread_handle = create_compiler_thread(_compilers[0], i, CHECK);
991982
_compiler1_objects[i] = thread_handle;
992983
_compiler1_logs[i] = nullptr;
993984

@@ -1015,7 +1006,7 @@ void CompileBroker::init_compiler_threads() {
10151006
// Initialize and start the object deoptimizer threads
10161007
const int total_count = DeoptimizeObjectsALotThreadCountSingle + DeoptimizeObjectsALotThreadCountAll;
10171008
for (int count = 0; count < total_count; count++) {
1018-
Handle thread_oop = create_thread_oop("Deoptimize objects a lot single mode", CHECK);
1009+
Handle thread_oop = JavaThread::create_system_thread_object("Deoptimize objects a lot single mode", CHECK);
10191010
jobject thread_handle = JNIHandles::make_local(THREAD, thread_oop());
10201011
make_thread(deoptimizer_t, thread_handle, nullptr, nullptr, THREAD);
10211012
}
@@ -1042,21 +1033,23 @@ void CompileBroker::possibly_add_compiler_threads(JavaThread* THREAD) {
10421033

10431034
for (int i = old_c2_count; i < new_c2_count; i++) {
10441035
#if INCLUDE_JVMCI
1045-
if (UseJVMCICompiler) {
1046-
// Native compiler threads as used in C1/C2 can reuse the j.l.Thread
1047-
// objects as their existence is completely hidden from the rest of
1048-
// the VM (and those compiler threads can't call Java code to do the
1049-
// creation anyway). For JVMCI we have to create new j.l.Thread objects
1050-
// as they are visible and we can see unexpected thread lifecycle
1051-
// transitions if we bind them to new JavaThreads.
1036+
if (UseJVMCICompiler && !UseJVMCINativeLibrary && _compiler2_objects[i] == nullptr) {
1037+
// Native compiler threads as used in C1/C2 can reuse the j.l.Thread objects as their
1038+
// existence is completely hidden from the rest of the VM (and those compiler threads can't
1039+
// call Java code to do the creation anyway).
1040+
//
1041+
// For pure Java JVMCI we have to create new j.l.Thread objects as they are visible and we
1042+
// can see unexpected thread lifecycle transitions if we bind them to new JavaThreads. For
1043+
// native library JVMCI it's preferred to use the C1/C2 strategy as this avoids unnecessary
1044+
// coupling with Java.
10521045
if (!THREAD->can_call_java()) break;
10531046
char name_buffer[256];
10541047
os::snprintf_checked(name_buffer, sizeof(name_buffer), "%s CompilerThread%d", _compilers[1]->name(), i);
10551048
Handle thread_oop;
10561049
{
10571050
// We have to give up the lock temporarily for the Java calls.
10581051
MutexUnlocker mu(CompileThread_lock);
1059-
thread_oop = create_thread_oop(name_buffer, THREAD);
1052+
thread_oop = JavaThread::create_system_thread_object(name_buffer, THREAD);
10601053
}
10611054
if (HAS_PENDING_EXCEPTION) {
10621055
if (trace_compiler_threads()) {
@@ -1076,6 +1069,7 @@ void CompileBroker::possibly_add_compiler_threads(JavaThread* THREAD) {
10761069
_compiler2_objects[i] = thread_handle;
10771070
}
10781071
#endif
1072+
guarantee(compiler2_object(i) != nullptr, "Thread oop must exist");
10791073
JavaThread *ct = make_thread(compiler_t, compiler2_object(i), _c2_compile_queue, _compilers[1], THREAD);
10801074
if (ct == nullptr) break;
10811075
_compilers[1]->set_num_compiler_threads(i + 1);

src/hotspot/share/compiler/compileBroker.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,6 @@ class CompileBroker: AllStatic {
241241
deoptimizer_t
242242
};
243243

244-
static Handle create_thread_oop(const char* name, TRAPS);
245244
static JavaThread* make_thread(ThreadType type, jobject thread_oop, CompileQueue* queue, AbstractCompiler* comp, JavaThread* THREAD);
246245
static void init_compiler_threads();
247246
static void possibly_add_compiler_threads(JavaThread* THREAD);

0 commit comments

Comments
 (0)