Skip to content

Commit

Permalink
added CompilerThreadCanCallJavaScope
Browse files Browse the repository at this point in the history
  • Loading branch information
dougxc committed Sep 25, 2024
1 parent 9176f68 commit c3e23c0
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 13 deletions.
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
6 changes: 6 additions & 0 deletions src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,11 @@ C2V_VMENTRY_NULL(jobject, asResolvedJavaMethod, (JNIEnv* env, jobject, jobject e
return JVMCIENV->get_jobject(result);
}

C2V_VMENTRY_0(jboolean, changeCompilerThreadCanCallJava, (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 +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 "changeCompilerThreadCanCallJava", CC "(Z)Z", FN_PTR(changeCompilerThreadCanCallJava)},
};

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.changeCompilerThreadCanCallJava(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.changeCompilerThreadCanCallJava(!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 changeCompilerThreadCanCallJava(boolean newState);
}

0 comments on commit c3e23c0

Please sign in to comment.