mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8252543: [JVMCI] Libgraal can deadlock in blocking compilation mode
Reviewed-by: kvn
This commit is contained in:
parent
b1b0f0b2cc
commit
998ce78e53
11 changed files with 112 additions and 54 deletions
|
@ -249,11 +249,6 @@ bool compileBroker_init() {
|
||||||
CompileTaskWrapper::CompileTaskWrapper(CompileTask* task) {
|
CompileTaskWrapper::CompileTaskWrapper(CompileTask* task) {
|
||||||
CompilerThread* thread = CompilerThread::current();
|
CompilerThread* thread = CompilerThread::current();
|
||||||
thread->set_task(task);
|
thread->set_task(task);
|
||||||
#if INCLUDE_JVMCI
|
|
||||||
if (task->is_blocking() && CompileBroker::compiler(task->comp_level())->is_jvmci()) {
|
|
||||||
task->set_jvmci_compiler_thread(thread);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
CompileLog* log = thread->log();
|
CompileLog* log = thread->log();
|
||||||
if (log != NULL && !task->is_unloaded()) task->log_task_start(log);
|
if (log != NULL && !task->is_unloaded()) task->log_task_start(log);
|
||||||
}
|
}
|
||||||
|
@ -277,7 +272,7 @@ CompileTaskWrapper::~CompileTaskWrapper() {
|
||||||
// The waiting thread timed out and thus did not free the task.
|
// The waiting thread timed out and thus did not free the task.
|
||||||
free_task = true;
|
free_task = true;
|
||||||
}
|
}
|
||||||
task->set_jvmci_compiler_thread(NULL);
|
task->set_blocking_jvmci_compile_state(NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!free_task) {
|
if (!free_task) {
|
||||||
|
@ -1604,22 +1599,27 @@ bool CompileBroker::wait_for_jvmci_completion(JVMCICompiler* jvmci, CompileTask*
|
||||||
assert(UseJVMCICompiler, "sanity");
|
assert(UseJVMCICompiler, "sanity");
|
||||||
MonitorLocker ml(thread, task->lock());
|
MonitorLocker ml(thread, task->lock());
|
||||||
int progress_wait_attempts = 0;
|
int progress_wait_attempts = 0;
|
||||||
int methods_compiled = jvmci->methods_compiled();
|
jint thread_jvmci_compilation_ticks = 0;
|
||||||
|
jint global_jvmci_compilation_ticks = jvmci->global_compilation_ticks();
|
||||||
while (!task->is_complete() && !is_compilation_disabled_forever() &&
|
while (!task->is_complete() && !is_compilation_disabled_forever() &&
|
||||||
ml.wait(JVMCI_COMPILATION_PROGRESS_WAIT_TIMESLICE)) {
|
ml.wait(JVMCI_COMPILATION_PROGRESS_WAIT_TIMESLICE)) {
|
||||||
CompilerThread* jvmci_compiler_thread = task->jvmci_compiler_thread();
|
JVMCICompileState* jvmci_compile_state = task->blocking_jvmci_compile_state();
|
||||||
|
|
||||||
bool progress;
|
bool progress;
|
||||||
if (jvmci_compiler_thread != NULL) {
|
if (jvmci_compile_state != NULL) {
|
||||||
// If the JVMCI compiler thread is not blocked or suspended, we deem it to be making progress.
|
jint ticks = jvmci_compile_state->compilation_ticks();
|
||||||
progress = jvmci_compiler_thread->thread_state() != _thread_blocked &&
|
progress = (ticks - thread_jvmci_compilation_ticks) != 0;
|
||||||
!jvmci_compiler_thread->is_external_suspend();
|
JVMCI_event_1("waiting on compilation %d [ticks=%d]", task->compile_id(), ticks);
|
||||||
|
thread_jvmci_compilation_ticks = ticks;
|
||||||
} else {
|
} else {
|
||||||
// Still waiting on JVMCI compiler queue. This thread may be holding a lock
|
// Still waiting on JVMCI compiler queue. This thread may be holding a lock
|
||||||
// that all JVMCI compiler threads are blocked on. We use the counter for
|
// that all JVMCI compiler threads are blocked on. We use the global JVMCI
|
||||||
// successful JVMCI compilations to determine whether JVMCI compilation
|
// compilation ticks to determine whether JVMCI compilation
|
||||||
// is still making progress through the JVMCI compiler queue.
|
// is still making progress through the JVMCI compiler queue.
|
||||||
progress = jvmci->methods_compiled() != methods_compiled;
|
jint ticks = jvmci->global_compilation_ticks();
|
||||||
|
progress = (ticks - global_jvmci_compilation_ticks) != 0;
|
||||||
|
JVMCI_event_1("waiting on compilation %d to be queued [ticks=%d]", task->compile_id(), ticks);
|
||||||
|
global_jvmci_compilation_ticks = ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!progress) {
|
if (!progress) {
|
||||||
|
@ -1627,13 +1627,11 @@ bool CompileBroker::wait_for_jvmci_completion(JVMCICompiler* jvmci, CompileTask*
|
||||||
if (PrintCompilation) {
|
if (PrintCompilation) {
|
||||||
task->print(tty, "wait for blocking compilation timed out");
|
task->print(tty, "wait for blocking compilation timed out");
|
||||||
}
|
}
|
||||||
|
JVMCI_event_1("waiting on compilation %d timed out", task->compile_id());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
progress_wait_attempts = 0;
|
progress_wait_attempts = 0;
|
||||||
if (jvmci_compiler_thread == NULL) {
|
|
||||||
methods_compiled = jvmci->methods_compiled();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
task->clear_waiter();
|
task->clear_waiter();
|
||||||
|
@ -2152,7 +2150,7 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
|
||||||
|
|
||||||
TraceTime t1("compilation", &time);
|
TraceTime t1("compilation", &time);
|
||||||
EventCompilation event;
|
EventCompilation event;
|
||||||
JVMCICompileState compile_state(task);
|
JVMCICompileState compile_state(task, jvmci);
|
||||||
JVMCIRuntime *runtime = NULL;
|
JVMCIRuntime *runtime = NULL;
|
||||||
|
|
||||||
if (JVMCI::in_shutdown()) {
|
if (JVMCI::in_shutdown()) {
|
||||||
|
|
|
@ -100,7 +100,7 @@ void CompileTask::initialize(int compile_id,
|
||||||
_osr_bci = osr_bci;
|
_osr_bci = osr_bci;
|
||||||
_is_blocking = is_blocking;
|
_is_blocking = is_blocking;
|
||||||
JVMCI_ONLY(_has_waiter = CompileBroker::compiler(comp_level)->is_jvmci();)
|
JVMCI_ONLY(_has_waiter = CompileBroker::compiler(comp_level)->is_jvmci();)
|
||||||
JVMCI_ONLY(_jvmci_compiler_thread = NULL;)
|
JVMCI_ONLY(_blocking_jvmci_compile_state = NULL;)
|
||||||
_comp_level = comp_level;
|
_comp_level = comp_level;
|
||||||
_num_inlined_bytecodes = 0;
|
_num_inlined_bytecodes = 0;
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
#include "memory/allocation.hpp"
|
#include "memory/allocation.hpp"
|
||||||
#include "utilities/xmlstream.hpp"
|
#include "utilities/xmlstream.hpp"
|
||||||
|
|
||||||
|
JVMCI_ONLY(class JVMCICompileState;)
|
||||||
|
|
||||||
// CompileTask
|
// CompileTask
|
||||||
//
|
//
|
||||||
// An entry in the compile queue. It represents a pending or current
|
// An entry in the compile queue. It represents a pending or current
|
||||||
|
@ -81,8 +83,8 @@ class CompileTask : public CHeapObj<mtCompiler> {
|
||||||
bool _is_blocking;
|
bool _is_blocking;
|
||||||
#if INCLUDE_JVMCI
|
#if INCLUDE_JVMCI
|
||||||
bool _has_waiter;
|
bool _has_waiter;
|
||||||
// Compiler thread for a blocking JVMCI compilation
|
// Compilation state for a blocking JVMCI compilation
|
||||||
CompilerThread* _jvmci_compiler_thread;
|
JVMCICompileState* _blocking_jvmci_compile_state;
|
||||||
#endif
|
#endif
|
||||||
int _comp_level;
|
int _comp_level;
|
||||||
int _num_inlined_bytecodes;
|
int _num_inlined_bytecodes;
|
||||||
|
@ -144,11 +146,9 @@ class CompileTask : public CHeapObj<mtCompiler> {
|
||||||
|
|
||||||
bool has_waiter() const { return _has_waiter; }
|
bool has_waiter() const { return _has_waiter; }
|
||||||
void clear_waiter() { _has_waiter = false; }
|
void clear_waiter() { _has_waiter = false; }
|
||||||
CompilerThread* jvmci_compiler_thread() const { return _jvmci_compiler_thread; }
|
JVMCICompileState* blocking_jvmci_compile_state() const { return _blocking_jvmci_compile_state; }
|
||||||
void set_jvmci_compiler_thread(CompilerThread* t) {
|
void set_blocking_jvmci_compile_state(JVMCICompileState* state) {
|
||||||
assert(is_blocking(), "must be");
|
_blocking_jvmci_compile_state = state;
|
||||||
assert((t == NULL) != (_jvmci_compiler_thread == NULL), "must be");
|
|
||||||
_jvmci_compiler_thread = t;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,11 @@
|
||||||
|
|
||||||
#include "precompiled.hpp"
|
#include "precompiled.hpp"
|
||||||
#include "classfile/systemDictionary.hpp"
|
#include "classfile/systemDictionary.hpp"
|
||||||
|
#include "compiler/compileTask.hpp"
|
||||||
#include "gc/shared/collectedHeap.hpp"
|
#include "gc/shared/collectedHeap.hpp"
|
||||||
#include "jvmci/jvmci.hpp"
|
#include "jvmci/jvmci.hpp"
|
||||||
#include "jvmci/jvmciJavaClasses.hpp"
|
#include "jvmci/jvmciJavaClasses.hpp"
|
||||||
|
#include "jvmci/jvmciEnv.hpp"
|
||||||
#include "jvmci/jvmciRuntime.hpp"
|
#include "jvmci/jvmciRuntime.hpp"
|
||||||
#include "jvmci/metadataHandles.hpp"
|
#include "jvmci/metadataHandles.hpp"
|
||||||
#include "memory/resourceArea.hpp"
|
#include "memory/resourceArea.hpp"
|
||||||
|
@ -123,6 +125,18 @@ void JVMCI::initialize_globals() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JavaThread* JVMCI::compilation_tick(JavaThread* thread) {
|
||||||
|
if (thread->is_Compiler_thread()) {
|
||||||
|
CompileTask *task = thread->as_CompilerThread()->task();
|
||||||
|
if (task != NULL) {
|
||||||
|
JVMCICompileState *state = task->blocking_jvmci_compile_state();
|
||||||
|
if (state != NULL) {
|
||||||
|
state->inc_compilation_ticks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
|
||||||
void JVMCI::metadata_do(void f(Metadata*)) {
|
void JVMCI::metadata_do(void f(Metadata*)) {
|
||||||
if (_java_runtime != NULL) {
|
if (_java_runtime != NULL) {
|
||||||
|
|
|
@ -110,6 +110,11 @@ class JVMCI : public AllStatic {
|
||||||
|
|
||||||
static void initialize_compiler(TRAPS);
|
static void initialize_compiler(TRAPS);
|
||||||
|
|
||||||
|
// Increments a value indicating some JVMCI compilation activity
|
||||||
|
// happened on `thread` if it is a CompilerThread.
|
||||||
|
// Returns `thread`.
|
||||||
|
static JavaThread* compilation_tick(JavaThread* thread);
|
||||||
|
|
||||||
static JVMCIRuntime* compiler_runtime() { return _compiler_runtime; }
|
static JVMCIRuntime* compiler_runtime() { return _compiler_runtime; }
|
||||||
// Gets the single runtime for JVMCI on the Java heap. This is the only
|
// Gets the single runtime for JVMCI on the Java heap. This is the only
|
||||||
// JVMCI runtime available when !UseJVMCINativeLibrary.
|
// JVMCI runtime available when !UseJVMCINativeLibrary.
|
||||||
|
|
|
@ -37,6 +37,7 @@ JVMCICompiler::JVMCICompiler() : AbstractCompiler(compiler_jvmci) {
|
||||||
_bootstrapping = false;
|
_bootstrapping = false;
|
||||||
_bootstrap_compilation_request_handled = false;
|
_bootstrap_compilation_request_handled = false;
|
||||||
_methods_compiled = 0;
|
_methods_compiled = 0;
|
||||||
|
_global_compilation_ticks = 0;
|
||||||
assert(_instance == NULL, "only one instance allowed");
|
assert(_instance == NULL, "only one instance allowed");
|
||||||
_instance = this;
|
_instance = this;
|
||||||
}
|
}
|
||||||
|
@ -154,3 +155,12 @@ void JVMCICompiler::print_compilation_timers() {
|
||||||
tty->print_cr(" JVMCI code install time: %6.3f s", code_install_time);
|
tty->print_cr(" JVMCI code install time: %6.3f s", code_install_time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JVMCICompiler::inc_methods_compiled() {
|
||||||
|
Atomic::inc(&_methods_compiled);
|
||||||
|
Atomic::inc(&_global_compilation_ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JVMCICompiler::inc_global_compilation_ticks() {
|
||||||
|
Atomic::inc(&_global_compilation_ticks);
|
||||||
|
}
|
|
@ -42,6 +42,10 @@ private:
|
||||||
*/
|
*/
|
||||||
volatile int _methods_compiled;
|
volatile int _methods_compiled;
|
||||||
|
|
||||||
|
// Incremented periodically by JVMCI compiler threads
|
||||||
|
// to indicate JVMCI compilation activity.
|
||||||
|
volatile int _global_compilation_ticks;
|
||||||
|
|
||||||
static JVMCICompiler* _instance;
|
static JVMCICompiler* _instance;
|
||||||
|
|
||||||
static elapsedTimer _codeInstallTimer;
|
static elapsedTimer _codeInstallTimer;
|
||||||
|
@ -99,15 +103,16 @@ public:
|
||||||
// Print compilation timers and statistics
|
// Print compilation timers and statistics
|
||||||
virtual void print_timers();
|
virtual void print_timers();
|
||||||
|
|
||||||
/**
|
// Gets the number of methods that have been successfully compiled by
|
||||||
* Gets the number of methods that have been successfully compiled by
|
// a call to JVMCICompiler::compile_method().
|
||||||
* a call to JVMCICompiler::compile_method().
|
|
||||||
*/
|
|
||||||
int methods_compiled() { return _methods_compiled; }
|
int methods_compiled() { return _methods_compiled; }
|
||||||
|
void inc_methods_compiled();
|
||||||
|
|
||||||
void inc_methods_compiled() {
|
// Gets a value indicating JVMCI compilation activity on any thread.
|
||||||
Atomic::inc(&_methods_compiled);
|
// If successive calls to this method return a different value, then
|
||||||
}
|
// some degree of JVMCI compilation occurred between the calls.
|
||||||
|
int global_compilation_ticks() const { return _global_compilation_ticks; }
|
||||||
|
void inc_global_compilation_ticks();
|
||||||
|
|
||||||
// Print compilation timers and statistics
|
// Print compilation timers and statistics
|
||||||
static void print_compilation_timers();
|
static void print_compilation_timers();
|
||||||
|
|
|
@ -132,7 +132,7 @@ Handle JavaArgumentUnboxer::next_arg(BasicType expectedType) {
|
||||||
TRACE_CALL(result_type, jvmci_ ## name signature) \
|
TRACE_CALL(result_type, jvmci_ ## name signature) \
|
||||||
JVMCI_VM_ENTRY_MARK; \
|
JVMCI_VM_ENTRY_MARK; \
|
||||||
ResourceMark rm; \
|
ResourceMark rm; \
|
||||||
JNI_JVMCIENV(thread, env);
|
JNI_JVMCIENV(JVMCI::compilation_tick(thread), env);
|
||||||
|
|
||||||
static JavaThread* get_current_thread(bool allow_null=true) {
|
static JavaThread* get_current_thread(bool allow_null=true) {
|
||||||
Thread* thread = Thread::current_or_null_safe();
|
Thread* thread = Thread::current_or_null_safe();
|
||||||
|
|
|
@ -36,10 +36,12 @@
|
||||||
#include "runtime/jniHandles.inline.hpp"
|
#include "runtime/jniHandles.inline.hpp"
|
||||||
#include "runtime/javaCalls.hpp"
|
#include "runtime/javaCalls.hpp"
|
||||||
#include "jvmci/jniAccessMark.inline.hpp"
|
#include "jvmci/jniAccessMark.inline.hpp"
|
||||||
|
#include "jvmci/jvmciCompiler.hpp"
|
||||||
#include "jvmci/jvmciRuntime.hpp"
|
#include "jvmci/jvmciRuntime.hpp"
|
||||||
|
|
||||||
JVMCICompileState::JVMCICompileState(CompileTask* task):
|
JVMCICompileState::JVMCICompileState(CompileTask* task, JVMCICompiler* compiler):
|
||||||
_task(task),
|
_task(task),
|
||||||
|
_compiler(compiler),
|
||||||
_retryable(true),
|
_retryable(true),
|
||||||
_failure_reason(NULL),
|
_failure_reason(NULL),
|
||||||
_failure_reason_on_C_heap(false) {
|
_failure_reason_on_C_heap(false) {
|
||||||
|
@ -51,6 +53,20 @@ JVMCICompileState::JVMCICompileState(CompileTask* task):
|
||||||
_jvmti_can_post_on_exceptions = JvmtiExport::can_post_on_exceptions() ? 1 : 0;
|
_jvmti_can_post_on_exceptions = JvmtiExport::can_post_on_exceptions() ? 1 : 0;
|
||||||
_jvmti_can_pop_frame = JvmtiExport::can_pop_frame() ? 1 : 0;
|
_jvmti_can_pop_frame = JvmtiExport::can_pop_frame() ? 1 : 0;
|
||||||
_target_method_is_old = _task != NULL && _task->method()->is_old();
|
_target_method_is_old = _task != NULL && _task->method()->is_old();
|
||||||
|
if (task->is_blocking()) {
|
||||||
|
task->set_blocking_jvmci_compile_state(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update global JVMCI compilation ticks after 512 thread-local JVMCI compilation ticks.
|
||||||
|
// This mitigates the overhead of the atomic operation used for the global update.
|
||||||
|
#define THREAD_TICKS_PER_GLOBAL_TICKS (2 << 9)
|
||||||
|
#define THREAD_TICKS_PER_GLOBAL_TICKS_MASK (THREAD_TICKS_PER_GLOBAL_TICKS - 1)
|
||||||
|
|
||||||
|
void JVMCICompileState::inc_compilation_ticks() {
|
||||||
|
if ((++_compilation_ticks & THREAD_TICKS_PER_GLOBAL_TICKS_MASK) == 0) {
|
||||||
|
_compiler->inc_global_compilation_ticks();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JVMCICompileState::jvmti_state_changed() const {
|
bool JVMCICompileState::jvmti_state_changed() const {
|
||||||
|
@ -620,8 +636,8 @@ void JVMCIEnv::fthrow_error(const char* file, int line, const char* format, ...)
|
||||||
|
|
||||||
JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtime, JVMCIObject method, int entry_bci,
|
JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtime, JVMCIObject method, int entry_bci,
|
||||||
jlong compile_state, int id) {
|
jlong compile_state, int id) {
|
||||||
|
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
|
||||||
if (is_hotspot()) {
|
if (is_hotspot()) {
|
||||||
Thread* THREAD = Thread::current();
|
|
||||||
JavaCallArguments jargs;
|
JavaCallArguments jargs;
|
||||||
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
|
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
|
||||||
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(method)));
|
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(method)));
|
||||||
|
@ -635,7 +651,7 @@ JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtim
|
||||||
vmSymbols::compileMethod_signature(), &jargs, CHECK_(JVMCIObject()));
|
vmSymbols::compileMethod_signature(), &jargs, CHECK_(JVMCIObject()));
|
||||||
return wrap((oop) result.get_jobject());
|
return wrap((oop) result.get_jobject());
|
||||||
} else {
|
} else {
|
||||||
JNIAccessMark jni(this);
|
JNIAccessMark jni(this, THREAD);
|
||||||
jobject result = jni()->CallNonvirtualObjectMethod(runtime.as_jobject(),
|
jobject result = jni()->CallNonvirtualObjectMethod(runtime.as_jobject(),
|
||||||
JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
|
JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
|
||||||
JNIJVMCI::HotSpotJVMCIRuntime::compileMethod_method(),
|
JNIJVMCI::HotSpotJVMCIRuntime::compileMethod_method(),
|
||||||
|
@ -648,14 +664,14 @@ JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtim
|
||||||
}
|
}
|
||||||
|
|
||||||
void JVMCIEnv::call_HotSpotJVMCIRuntime_bootstrapFinished (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {
|
void JVMCIEnv::call_HotSpotJVMCIRuntime_bootstrapFinished (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {
|
||||||
|
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
|
||||||
if (is_hotspot()) {
|
if (is_hotspot()) {
|
||||||
Thread* THREAD = Thread::current();
|
|
||||||
JavaCallArguments jargs;
|
JavaCallArguments jargs;
|
||||||
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
|
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
|
||||||
JavaValue result(T_VOID);
|
JavaValue result(T_VOID);
|
||||||
JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::bootstrapFinished_name(), vmSymbols::void_method_signature(), &jargs, CHECK);
|
JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::bootstrapFinished_name(), vmSymbols::void_method_signature(), &jargs, CHECK);
|
||||||
} else {
|
} else {
|
||||||
JNIAccessMark jni(this);
|
JNIAccessMark jni(this, THREAD);
|
||||||
jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::bootstrapFinished_method());
|
jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::bootstrapFinished_method());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -681,7 +697,7 @@ void JVMCIEnv::call_HotSpotJVMCIRuntime_shutdown (JVMCIObject runtime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_runtime (JVMCIEnv* JVMCIENV) {
|
JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_runtime (JVMCIEnv* JVMCIENV) {
|
||||||
JavaThread* THREAD = JavaThread::current();
|
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
|
||||||
if (is_hotspot()) {
|
if (is_hotspot()) {
|
||||||
JavaCallArguments jargs;
|
JavaCallArguments jargs;
|
||||||
JavaValue result(T_OBJECT);
|
JavaValue result(T_OBJECT);
|
||||||
|
@ -698,7 +714,7 @@ JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_runtime (JVMCIEnv* JVMCIENV) {
|
||||||
}
|
}
|
||||||
|
|
||||||
JVMCIObject JVMCIEnv::call_JVMCI_getRuntime (JVMCIEnv* JVMCIENV) {
|
JVMCIObject JVMCIEnv::call_JVMCI_getRuntime (JVMCIEnv* JVMCIENV) {
|
||||||
JavaThread* THREAD = JavaThread::current();
|
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
|
||||||
if (is_hotspot()) {
|
if (is_hotspot()) {
|
||||||
JavaCallArguments jargs;
|
JavaCallArguments jargs;
|
||||||
JavaValue result(T_OBJECT);
|
JavaValue result(T_OBJECT);
|
||||||
|
@ -715,7 +731,7 @@ JVMCIObject JVMCIEnv::call_JVMCI_getRuntime (JVMCIEnv* JVMCIENV) {
|
||||||
}
|
}
|
||||||
|
|
||||||
JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_getCompiler (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {
|
JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_getCompiler (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {
|
||||||
JavaThread* THREAD = JavaThread::current();
|
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
|
||||||
if (is_hotspot()) {
|
if (is_hotspot()) {
|
||||||
JavaCallArguments jargs;
|
JavaCallArguments jargs;
|
||||||
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
|
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
|
||||||
|
@ -734,7 +750,7 @@ JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_getCompiler (JVMCIObject runtime,
|
||||||
|
|
||||||
|
|
||||||
JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_callToString(JVMCIObject object, JVMCIEnv* JVMCIENV) {
|
JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_callToString(JVMCIObject object, JVMCIEnv* JVMCIENV) {
|
||||||
JavaThread* THREAD = JavaThread::current();
|
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
|
||||||
if (is_hotspot()) {
|
if (is_hotspot()) {
|
||||||
JavaCallArguments jargs;
|
JavaCallArguments jargs;
|
||||||
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(object)));
|
jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(object)));
|
||||||
|
@ -758,7 +774,7 @@ JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_callToString(JVMCIObject object,
|
||||||
|
|
||||||
|
|
||||||
JVMCIObject JVMCIEnv::call_PrimitiveConstant_forTypeChar(jchar kind, jlong value, JVMCI_TRAPS) {
|
JVMCIObject JVMCIEnv::call_PrimitiveConstant_forTypeChar(jchar kind, jlong value, JVMCI_TRAPS) {
|
||||||
JavaThread* THREAD = JavaThread::current();
|
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
|
||||||
if (is_hotspot()) {
|
if (is_hotspot()) {
|
||||||
JavaCallArguments jargs;
|
JavaCallArguments jargs;
|
||||||
jargs.push_int(kind);
|
jargs.push_int(kind);
|
||||||
|
@ -782,7 +798,7 @@ JVMCIObject JVMCIEnv::call_PrimitiveConstant_forTypeChar(jchar kind, jlong value
|
||||||
}
|
}
|
||||||
|
|
||||||
JVMCIObject JVMCIEnv::call_JavaConstant_forFloat(float value, JVMCI_TRAPS) {
|
JVMCIObject JVMCIEnv::call_JavaConstant_forFloat(float value, JVMCI_TRAPS) {
|
||||||
JavaThread* THREAD = JavaThread::current();
|
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
|
||||||
if (is_hotspot()) {
|
if (is_hotspot()) {
|
||||||
JavaCallArguments jargs;
|
JavaCallArguments jargs;
|
||||||
jargs.push_float(value);
|
jargs.push_float(value);
|
||||||
|
@ -805,7 +821,7 @@ JVMCIObject JVMCIEnv::call_JavaConstant_forFloat(float value, JVMCI_TRAPS) {
|
||||||
}
|
}
|
||||||
|
|
||||||
JVMCIObject JVMCIEnv::call_JavaConstant_forDouble(double value, JVMCI_TRAPS) {
|
JVMCIObject JVMCIEnv::call_JavaConstant_forDouble(double value, JVMCI_TRAPS) {
|
||||||
JavaThread* THREAD = JavaThread::current();
|
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
|
||||||
if (is_hotspot()) {
|
if (is_hotspot()) {
|
||||||
JavaCallArguments jargs;
|
JavaCallArguments jargs;
|
||||||
jargs.push_double(value);
|
jargs.push_double(value);
|
||||||
|
@ -886,7 +902,7 @@ JVMCIObject JVMCIEnv::new_StackTraceElement(const methodHandle& method, int bci,
|
||||||
}
|
}
|
||||||
|
|
||||||
JVMCIObject JVMCIEnv::new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS) {
|
JVMCIObject JVMCIEnv::new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS) {
|
||||||
JavaThread* THREAD = JavaThread::current();
|
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
|
||||||
|
|
||||||
JVMCIObject methodObject = get_jvmci_method(method, JVMCI_CHECK_(JVMCIObject()));
|
JVMCIObject methodObject = get_jvmci_method(method, JVMCI_CHECK_(JVMCIObject()));
|
||||||
|
|
||||||
|
@ -989,7 +1005,7 @@ JVMCIObject JVMCIEnv::get_jvmci_method(const methodHandle& method, JVMCI_TRAPS)
|
||||||
return method_object;
|
return method_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread* THREAD = Thread::current();
|
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
|
||||||
jmetadata handle = _runtime->allocate_handle(method);
|
jmetadata handle = _runtime->allocate_handle(method);
|
||||||
jboolean exception = false;
|
jboolean exception = false;
|
||||||
if (is_hotspot()) {
|
if (is_hotspot()) {
|
||||||
|
@ -1005,7 +1021,7 @@ JVMCIObject JVMCIEnv::get_jvmci_method(const methodHandle& method, JVMCI_TRAPS)
|
||||||
method_object = wrap((oop)result.get_jobject());
|
method_object = wrap((oop)result.get_jobject());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
JNIAccessMark jni(this);
|
JNIAccessMark jni(this, THREAD);
|
||||||
method_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedJavaMethodImpl::clazz(),
|
method_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedJavaMethodImpl::clazz(),
|
||||||
JNIJVMCI::HotSpotResolvedJavaMethodImpl_fromMetaspace_method(),
|
JNIJVMCI::HotSpotResolvedJavaMethodImpl_fromMetaspace_method(),
|
||||||
(jlong) handle));
|
(jlong) handle));
|
||||||
|
@ -1032,7 +1048,7 @@ JVMCIObject JVMCIEnv::get_jvmci_type(const JVMCIKlassHandle& klass, JVMCI_TRAPS)
|
||||||
}
|
}
|
||||||
|
|
||||||
jlong pointer = (jlong) klass();
|
jlong pointer = (jlong) klass();
|
||||||
JavaThread* THREAD = JavaThread::current();
|
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
|
||||||
JVMCIObject signature = create_string(klass->signature_name(), JVMCI_CHECK_(JVMCIObject()));
|
JVMCIObject signature = create_string(klass->signature_name(), JVMCI_CHECK_(JVMCIObject()));
|
||||||
jboolean exception = false;
|
jboolean exception = false;
|
||||||
if (is_hotspot()) {
|
if (is_hotspot()) {
|
||||||
|
@ -1071,7 +1087,7 @@ JVMCIObject JVMCIEnv::get_jvmci_constant_pool(const constantPoolHandle& cp, JVMC
|
||||||
JVMCIObject cp_object;
|
JVMCIObject cp_object;
|
||||||
jmetadata handle = _runtime->allocate_handle(cp);
|
jmetadata handle = _runtime->allocate_handle(cp);
|
||||||
jboolean exception = false;
|
jboolean exception = false;
|
||||||
JavaThread* THREAD = JavaThread::current();
|
JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
|
||||||
if (is_hotspot()) {
|
if (is_hotspot()) {
|
||||||
JavaValue result(T_OBJECT);
|
JavaValue result(T_OBJECT);
|
||||||
JavaCallArguments args;
|
JavaCallArguments args;
|
||||||
|
|
|
@ -94,6 +94,7 @@ class JVMCICompileState : public ResourceObj {
|
||||||
friend class JVMCIVMStructs;
|
friend class JVMCIVMStructs;
|
||||||
private:
|
private:
|
||||||
CompileTask* _task;
|
CompileTask* _task;
|
||||||
|
JVMCICompiler* _compiler;
|
||||||
|
|
||||||
// Cache JVMTI state. Defined as bytes so that reading them from Java
|
// Cache JVMTI state. Defined as bytes so that reading them from Java
|
||||||
// via Unsafe is well defined (the C++ type for bool is implementation
|
// via Unsafe is well defined (the C++ type for bool is implementation
|
||||||
|
@ -113,8 +114,13 @@ class JVMCICompileState : public ResourceObj {
|
||||||
// with the mtJVMCI NMT flag.
|
// with the mtJVMCI NMT flag.
|
||||||
bool _failure_reason_on_C_heap;
|
bool _failure_reason_on_C_heap;
|
||||||
|
|
||||||
|
// A value indicating compilation activity during the compilation.
|
||||||
|
// If successive calls to this method return a different value, then
|
||||||
|
// some degree of JVMCI compilation occurred between the calls.
|
||||||
|
jint _compilation_ticks;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
JVMCICompileState(CompileTask* task);
|
JVMCICompileState(CompileTask* task, JVMCICompiler* compiler);
|
||||||
|
|
||||||
CompileTask* task() { return _task; }
|
CompileTask* task() { return _task; }
|
||||||
|
|
||||||
|
@ -135,6 +141,9 @@ class JVMCICompileState : public ResourceObj {
|
||||||
_failure_reason_on_C_heap = reason_on_C_heap;
|
_failure_reason_on_C_heap = reason_on_C_heap;
|
||||||
_retryable = retryable;
|
_retryable = retryable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jint compilation_ticks() const { return _compilation_ticks; }
|
||||||
|
void inc_compilation_ticks();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -284,7 +293,7 @@ public:
|
||||||
JVMCIPrimitiveArray wrap(typeArrayOop obj) { assert(is_hotspot(), "must be"); return (JVMCIPrimitiveArray) wrap(JNIHandles::make_local(obj)); }
|
JVMCIPrimitiveArray wrap(typeArrayOop obj) { assert(is_hotspot(), "must be"); return (JVMCIPrimitiveArray) wrap(JNIHandles::make_local(obj)); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Compiles a method with the JVMIC compiler.
|
// Compiles a method with the JVMCI compiler.
|
||||||
// Caller must handle pending exception.
|
// Caller must handle pending exception.
|
||||||
JVMCIObject call_HotSpotJVMCIRuntime_compileMethod(JVMCIObject runtime, JVMCIObject method, int entry_bci,
|
JVMCIObject call_HotSpotJVMCIRuntime_compileMethod(JVMCIObject runtime, JVMCIObject method, int entry_bci,
|
||||||
jlong compile_state, int id);
|
jlong compile_state, int id);
|
||||||
|
|
|
@ -163,6 +163,7 @@
|
||||||
nonstatic_field(JVMCICompileState, _jvmti_can_access_local_variables, jbyte) \
|
nonstatic_field(JVMCICompileState, _jvmti_can_access_local_variables, jbyte) \
|
||||||
nonstatic_field(JVMCICompileState, _jvmti_can_post_on_exceptions, jbyte) \
|
nonstatic_field(JVMCICompileState, _jvmti_can_post_on_exceptions, jbyte) \
|
||||||
nonstatic_field(JVMCICompileState, _jvmti_can_pop_frame, jbyte) \
|
nonstatic_field(JVMCICompileState, _jvmti_can_pop_frame, jbyte) \
|
||||||
|
nonstatic_field(JVMCICompileState, _compilation_ticks, jint) \
|
||||||
\
|
\
|
||||||
nonstatic_field(JavaThread, _threadObj, OopHandle) \
|
nonstatic_field(JavaThread, _threadObj, OopHandle) \
|
||||||
nonstatic_field(JavaThread, _anchor, JavaFrameAnchor) \
|
nonstatic_field(JavaThread, _anchor, JavaFrameAnchor) \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue