Skip to content

Commit 751a914

Browse files
author
Tomas Zezula
committed
8340733: Add scope for relaxing constraint on JavaCalls from CompilerThread
Reviewed-by: dnsimon, kvn
1 parent 7e87c07 commit 751a914

File tree

6 files changed

+120
-16
lines changed

6 files changed

+120
-16
lines changed

src/hotspot/share/compiler/compilerThread.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,11 @@ CompilerThread::~CompilerThread() {
5555
}
5656

5757
void CompilerThread::set_compiler(AbstractCompiler* c) {
58-
// Only jvmci compiler threads can call Java
59-
_can_call_java = c != nullptr && c->is_jvmci();
58+
/*
59+
* Compiler threads need to make Java upcalls to the jargraal compiler.
60+
* Java upcalls are also needed by the InterpreterRuntime when using jargraal.
61+
*/
62+
_can_call_java = c != nullptr && c->is_jvmci() JVMCI_ONLY(&& !UseJVMCINativeLibrary);
6063
_compiler = c;
6164
}
6265

src/hotspot/share/jvmci/jvmci.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,26 +54,29 @@ volatile intx JVMCI::_first_error_tid = -1;
5454
volatile int JVMCI::_fatal_log_fd = -1;
5555
const char* JVMCI::_fatal_log_filename = nullptr;
5656

57-
CompilerThreadCanCallJava::CompilerThreadCanCallJava(JavaThread* current, bool new_state) {
58-
_current = nullptr;
57+
CompilerThread* CompilerThreadCanCallJava::update(JavaThread* current, bool new_state) {
5958
if (current->is_Compiler_thread()) {
6059
CompilerThread* ct = CompilerThread::cast(current);
6160
if (ct->_can_call_java != new_state &&
6261
ct->_compiler != nullptr &&
6362
ct->_compiler->is_jvmci())
6463
{
65-
// Only enter a new context if the ability of the
64+
// Only update the state if the ability of the
6665
// current thread to call Java actually changes
67-
_reset_state = ct->_can_call_java;
6866
ct->_can_call_java = new_state;
69-
_current = ct;
67+
return ct;
7068
}
7169
}
70+
return nullptr;
71+
}
72+
73+
CompilerThreadCanCallJava::CompilerThreadCanCallJava(JavaThread* current, bool new_state) {
74+
_current = CompilerThreadCanCallJava::update(current, new_state);
7275
}
7376

7477
CompilerThreadCanCallJava::~CompilerThreadCanCallJava() {
7578
if (_current != nullptr) {
76-
_current->_can_call_java = _reset_state;
79+
_current->_can_call_java = !_current->_can_call_java;
7780
}
7881
}
7982

src/hotspot/share/jvmci/jvmci.hpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,13 @@ typedef struct _jmetadata *jmetadata;
6060
class CompilerThreadCanCallJava : StackObj {
6161
private:
6262
CompilerThread* _current; // Only non-null if state of thread changed
63-
bool _reset_state; // Value prior to state change, undefined
64-
// if no state change.
6563
public:
66-
// Enters a scope in which the ability of the current CompilerThread
67-
// to call Java is specified by `new_state`. This call only makes a
68-
// change if the current thread is a CompilerThread associated with
69-
// a JVMCI compiler whose CompilerThread::_can_call_java is not
70-
// currently `new_state`.
64+
// If the current thread is a CompilerThread associated with
65+
// a JVMCI compiler where CompilerThread::_can_call_java != new_state,
66+
// then _can_call_java is set to `new_state`
67+
// Returns nullptr if no change was made, otherwise the current CompilerThread
68+
static CompilerThread* update(JavaThread* current, bool new_state);
69+
7170
CompilerThreadCanCallJava(JavaThread* current, bool new_state);
7271

7372
// Resets CompilerThread::_can_call_java of the current thread if the

src/hotspot/share/jvmci/jvmciCompilerToVM.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ Handle JavaArgumentUnboxer::next_arg(BasicType expectedType) {
184184
JVMCI_VM_ENTRY_MARK; \
185185
ResourceMark rm; \
186186
bool __is_hotspot = env == thread->jni_environment(); \
187-
CompilerThreadCanCallJava ccj(thread, __is_hotspot); \
187+
bool __block_can_call_java = __is_hotspot || !thread->is_Compiler_thread() || CompilerThread::cast(thread)->can_call_java(); \
188+
CompilerThreadCanCallJava ccj(thread, __block_can_call_java); \
188189
JVMCIENV_FROM_JNI(JVMCI::compilation_tick(thread), env); \
189190

190191
// Entry to native method implementation that transitions
@@ -401,6 +402,11 @@ C2V_VMENTRY_NULL(jobject, asResolvedJavaMethod, (JNIEnv* env, jobject, jobject e
401402
return JVMCIENV->get_jobject(result);
402403
}
403404

405+
C2V_VMENTRY_PREFIX(jboolean, updateCompilerThreadCanCallJava, (JNIEnv* env, jobject, jboolean newState))
406+
return CompilerThreadCanCallJava::update(thread, newState) != nullptr;
407+
C2V_END
408+
409+
404410
C2V_VMENTRY_NULL(jobject, getResolvedJavaMethod, (JNIEnv* env, jobject, jobject base, jlong offset))
405411
Method* method = nullptr;
406412
JVMCIObject base_object = JVMCIENV->wrap(base);
@@ -3386,6 +3392,7 @@ JNINativeMethod CompilerToVM::methods[] = {
33863392
{CC "notifyCompilerPhaseEvent", CC "(JIII)V", FN_PTR(notifyCompilerPhaseEvent)},
33873393
{CC "notifyCompilerInliningEvent", CC "(I" HS_METHOD2 HS_METHOD2 "ZLjava/lang/String;I)V", FN_PTR(notifyCompilerInliningEvent)},
33883394
{CC "getOopMapAt", CC "(" HS_METHOD2 "I[J)V", FN_PTR(getOopMapAt)},
3395+
{CC "updateCompilerThreadCanCallJava", CC "(Z)Z", FN_PTR(updateCompilerThreadCanCallJava)},
33893396
};
33903397

33913398
int CompilerToVM::methods_count() {
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
package jdk.vm.ci.hotspot;
24+
25+
/**
26+
* Scope used to potentially change whether the current thread can make VM-to-Java calls.
27+
* A scope is exited by the {@link #close()} method so it should be used in a
28+
* try-with-resources statement.
29+
*
30+
* The scope does nothing if the current thread is not a HotSpot VM CompilerThread
31+
* for a JVMCI compiler.
32+
*/
33+
public class CompilerThreadCanCallJavaScope implements AutoCloseable {
34+
35+
/**
36+
* Thread state used during the scope.
37+
*/
38+
private final boolean state;
39+
40+
/**
41+
* Non-null iff the thread state needs resetting in {@link #close()}.
42+
*/
43+
private final CompilerToVM vm;
44+
45+
/**
46+
* The thread on which the constructor was called.
47+
*/
48+
private final Thread thread;
49+
50+
/**
51+
* Opens a scope to allow/disallow the current thread to make VM-to-Java calls.
52+
* The scope is a no-op if the current thread is not a HotSpot VM CompilerThread
53+
* for a JVMCI compiler.
54+
*
55+
* @param newState true/false to allow/disallow VM-to-Java calls within the scope
56+
*/
57+
public CompilerThreadCanCallJavaScope(boolean newState) {
58+
this.state = newState;
59+
this.thread = Thread.currentThread();
60+
CompilerToVM vm = HotSpotJVMCIRuntime.runtime().getCompilerToVM();
61+
if (vm.updateCompilerThreadCanCallJava(newState)) {
62+
this.vm = vm;
63+
} else {
64+
this.vm = null;
65+
}
66+
}
67+
68+
/**
69+
* Resets the state of the current thread with respect to whether it can make
70+
* VM-to-Java calls to what it was before the constructor was called.
71+
*
72+
* @throws IllegalStateException if called on a different thread than the constructor
73+
*/
74+
@Override
75+
public void close() {
76+
if (this.thread != Thread.currentThread()) {
77+
throw new IllegalStateException();
78+
}
79+
80+
if (vm != null) {
81+
vm.updateCompilerThreadCanCallJava(!state);
82+
}
83+
}
84+
}

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,4 +1514,12 @@ void getOopMapAt(HotSpotResolvedJavaMethodImpl method, int bci, long[] oopMap) {
15141514
}
15151515

15161516
native void getOopMapAt(HotSpotResolvedJavaMethodImpl method, long methodPointer, int bci, long[] oopMap);
1517+
1518+
/**
1519+
* If the current thread is a CompilerThread associated with a JVMCI compiler where
1520+
* newState != CompilerThread::_can_call_java, then _can_call_java is set to newState.
1521+
*
1522+
* @returns false if no change was made, otherwise true
1523+
*/
1524+
native boolean updateCompilerThreadCanCallJava(boolean newState);
15171525
}

0 commit comments

Comments
 (0)