8340733: Add scope for relaxing constraint on JavaCalls from CompilerThread
Reviewed-by: dnsimon, kvn
This commit is contained in:
parent
7e87c071b0
commit
751a914b0a
@ -55,8 +55,11 @@ CompilerThread::~CompilerThread() {
|
||||
}
|
||||
|
||||
void CompilerThread::set_compiler(AbstractCompiler* c) {
|
||||
// Only jvmci compiler threads can call Java
|
||||
_can_call_java = c != nullptr && c->is_jvmci();
|
||||
/*
|
||||
* Compiler threads need to make Java upcalls to the jargraal compiler.
|
||||
* Java upcalls are also needed by the InterpreterRuntime when using jargraal.
|
||||
*/
|
||||
_can_call_java = c != nullptr && c->is_jvmci() JVMCI_ONLY(&& !UseJVMCINativeLibrary);
|
||||
_compiler = c;
|
||||
}
|
||||
|
||||
|
@ -54,26 +54,29 @@ volatile intx JVMCI::_first_error_tid = -1;
|
||||
volatile int JVMCI::_fatal_log_fd = -1;
|
||||
const char* JVMCI::_fatal_log_filename = nullptr;
|
||||
|
||||
CompilerThreadCanCallJava::CompilerThreadCanCallJava(JavaThread* current, bool new_state) {
|
||||
_current = nullptr;
|
||||
CompilerThread* CompilerThreadCanCallJava::update(JavaThread* current, bool new_state) {
|
||||
if (current->is_Compiler_thread()) {
|
||||
CompilerThread* ct = CompilerThread::cast(current);
|
||||
if (ct->_can_call_java != new_state &&
|
||||
ct->_compiler != nullptr &&
|
||||
ct->_compiler->is_jvmci())
|
||||
{
|
||||
// Only enter a new context if the ability of the
|
||||
// Only update the state if the ability of the
|
||||
// current thread to call Java actually changes
|
||||
_reset_state = ct->_can_call_java;
|
||||
ct->_can_call_java = new_state;
|
||||
_current = ct;
|
||||
return ct;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CompilerThreadCanCallJava::CompilerThreadCanCallJava(JavaThread* current, bool new_state) {
|
||||
_current = CompilerThreadCanCallJava::update(current, new_state);
|
||||
}
|
||||
|
||||
CompilerThreadCanCallJava::~CompilerThreadCanCallJava() {
|
||||
if (_current != nullptr) {
|
||||
_current->_can_call_java = _reset_state;
|
||||
_current->_can_call_java = !_current->_can_call_java;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,14 +60,13 @@ typedef struct _jmetadata *jmetadata;
|
||||
class CompilerThreadCanCallJava : StackObj {
|
||||
private:
|
||||
CompilerThread* _current; // Only non-null if state of thread changed
|
||||
bool _reset_state; // Value prior to state change, undefined
|
||||
// if no state change.
|
||||
public:
|
||||
// Enters a scope in which the ability of the current CompilerThread
|
||||
// to call Java is specified by `new_state`. This call only makes a
|
||||
// change if the current thread is a CompilerThread associated with
|
||||
// a JVMCI compiler whose CompilerThread::_can_call_java is not
|
||||
// currently `new_state`.
|
||||
// If the current thread is a CompilerThread associated with
|
||||
// a JVMCI compiler where CompilerThread::_can_call_java != new_state,
|
||||
// then _can_call_java is set to `new_state`
|
||||
// Returns nullptr if no change was made, otherwise the current CompilerThread
|
||||
static CompilerThread* update(JavaThread* current, bool new_state);
|
||||
|
||||
CompilerThreadCanCallJava(JavaThread* current, bool new_state);
|
||||
|
||||
// Resets CompilerThread::_can_call_java of the current thread if the
|
||||
|
@ -184,7 +184,8 @@ Handle JavaArgumentUnboxer::next_arg(BasicType expectedType) {
|
||||
JVMCI_VM_ENTRY_MARK; \
|
||||
ResourceMark rm; \
|
||||
bool __is_hotspot = env == thread->jni_environment(); \
|
||||
CompilerThreadCanCallJava ccj(thread, __is_hotspot); \
|
||||
bool __block_can_call_java = __is_hotspot || !thread->is_Compiler_thread() || CompilerThread::cast(thread)->can_call_java(); \
|
||||
CompilerThreadCanCallJava ccj(thread, __block_can_call_java); \
|
||||
JVMCIENV_FROM_JNI(JVMCI::compilation_tick(thread), env); \
|
||||
|
||||
// Entry to native method implementation that transitions
|
||||
@ -401,6 +402,11 @@ C2V_VMENTRY_NULL(jobject, asResolvedJavaMethod, (JNIEnv* env, jobject, jobject e
|
||||
return JVMCIENV->get_jobject(result);
|
||||
}
|
||||
|
||||
C2V_VMENTRY_PREFIX(jboolean, updateCompilerThreadCanCallJava, (JNIEnv* env, jobject, jboolean newState))
|
||||
return CompilerThreadCanCallJava::update(thread, newState) != nullptr;
|
||||
C2V_END
|
||||
|
||||
|
||||
C2V_VMENTRY_NULL(jobject, getResolvedJavaMethod, (JNIEnv* env, jobject, jobject base, jlong offset))
|
||||
Method* method = nullptr;
|
||||
JVMCIObject base_object = JVMCIENV->wrap(base);
|
||||
@ -3386,6 +3392,7 @@ JNINativeMethod CompilerToVM::methods[] = {
|
||||
{CC "notifyCompilerPhaseEvent", CC "(JIII)V", FN_PTR(notifyCompilerPhaseEvent)},
|
||||
{CC "notifyCompilerInliningEvent", CC "(I" HS_METHOD2 HS_METHOD2 "ZLjava/lang/String;I)V", FN_PTR(notifyCompilerInliningEvent)},
|
||||
{CC "getOopMapAt", CC "(" HS_METHOD2 "I[J)V", FN_PTR(getOopMapAt)},
|
||||
{CC "updateCompilerThreadCanCallJava", CC "(Z)Z", FN_PTR(updateCompilerThreadCanCallJava)},
|
||||
};
|
||||
|
||||
int CompilerToVM::methods_count() {
|
||||
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package jdk.vm.ci.hotspot;
|
||||
|
||||
/**
|
||||
* Scope used to potentially change whether the current thread can make VM-to-Java calls.
|
||||
* A scope is exited by the {@link #close()} method so it should be used in a
|
||||
* try-with-resources statement.
|
||||
*
|
||||
* The scope does nothing if the current thread is not a HotSpot VM CompilerThread
|
||||
* for a JVMCI compiler.
|
||||
*/
|
||||
public class CompilerThreadCanCallJavaScope implements AutoCloseable {
|
||||
|
||||
/**
|
||||
* Thread state used during the scope.
|
||||
*/
|
||||
private final boolean state;
|
||||
|
||||
/**
|
||||
* Non-null iff the thread state needs resetting in {@link #close()}.
|
||||
*/
|
||||
private final CompilerToVM vm;
|
||||
|
||||
/**
|
||||
* The thread on which the constructor was called.
|
||||
*/
|
||||
private final Thread thread;
|
||||
|
||||
/**
|
||||
* Opens a scope to allow/disallow the current thread to make VM-to-Java calls.
|
||||
* The scope is a no-op if the current thread is not a HotSpot VM CompilerThread
|
||||
* for a JVMCI compiler.
|
||||
*
|
||||
* @param newState true/false to allow/disallow VM-to-Java calls within the scope
|
||||
*/
|
||||
public CompilerThreadCanCallJavaScope(boolean newState) {
|
||||
this.state = newState;
|
||||
this.thread = Thread.currentThread();
|
||||
CompilerToVM vm = HotSpotJVMCIRuntime.runtime().getCompilerToVM();
|
||||
if (vm.updateCompilerThreadCanCallJava(newState)) {
|
||||
this.vm = vm;
|
||||
} else {
|
||||
this.vm = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the state of the current thread with respect to whether it can make
|
||||
* VM-to-Java calls to what it was before the constructor was called.
|
||||
*
|
||||
* @throws IllegalStateException if called on a different thread than the constructor
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
if (this.thread != Thread.currentThread()) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
if (vm != null) {
|
||||
vm.updateCompilerThreadCanCallJava(!state);
|
||||
}
|
||||
}
|
||||
}
|
@ -1514,4 +1514,12 @@ final class CompilerToVM {
|
||||
}
|
||||
|
||||
native void getOopMapAt(HotSpotResolvedJavaMethodImpl method, long methodPointer, int bci, long[] oopMap);
|
||||
|
||||
/**
|
||||
* If the current thread is a CompilerThread associated with a JVMCI compiler where
|
||||
* newState != CompilerThread::_can_call_java, then _can_call_java is set to newState.
|
||||
*
|
||||
* @returns false if no change was made, otherwise true
|
||||
*/
|
||||
native boolean updateCompilerThreadCanCallJava(boolean newState);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user