Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/hotspot/share/compiler/compilerThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
15 changes: 9 additions & 6 deletions src/hotspot/share/jvmci/jvmci.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,26 +54,29 @@ volatile intx JVMCI::_fatal_log_init_thread = -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;
}
}

Expand Down
13 changes: 6 additions & 7 deletions src/hotspot/share/jvmci/jvmci.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 8 additions & 1 deletion src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -3387,6 +3393,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() {
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1514,4 +1514,12 @@ void getOopMapAt(HotSpotResolvedJavaMethodImpl method, int bci, long[] oopMap) {
}

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);
}