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
4 changes: 3 additions & 1 deletion src/hotspot/share/compiler/compileBroker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2203,7 +2203,9 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
} else {
JVMCIEnv env(thread, &compile_state, __FILE__, __LINE__);
if (env.init_error() != JNI_OK) {
failure_reason = os::strdup(err_msg("Error attaching to libjvmci (err: %d)", env.init_error()), mtJVMCI);
const char* msg = env.init_error_msg();
failure_reason = os::strdup(err_msg("Error attaching to libjvmci (err: %d, %s)",
env.init_error(), msg == nullptr ? "unknown" : msg), mtJVMCI);
bool reason_on_C_heap = true;
// In case of JNI_ENOMEM, there's a good chance a subsequent attempt to create libjvmci or attach to it
// might succeed. Other errors most likely indicate a non-recoverable error in the JVMCI runtime.
Expand Down
21 changes: 14 additions & 7 deletions src/hotspot/share/jvmci/jvmciEnv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,14 @@ void JVMCIEnv::init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env) {
_is_hotspot = false;

_runtime = JVMCI::compiler_runtime(thread);
_env = _runtime->init_shared_library_javavm(&_init_error);
_env = _runtime->init_shared_library_javavm(&_init_error, &_init_error_msg);
if (_env != nullptr) {
// Creating the JVMCI shared library VM also attaches the current thread
_detach_on_close = true;
} else if (_init_error != JNI_OK) {
// Caller creating this JVMCIEnv must handle the error.
JVMCI_event_1("[%s:%d] Error creating libjvmci (err: %d)", _file, _line, _init_error);
JVMCI_event_1("[%s:%d] Error creating libjvmci (err: %d, %s)", _file, _line,
_init_error, _init_error_msg == nullptr ? "unknown" : _init_error_msg);
return;
} else {
_runtime->GetEnv(thread, (void**)&parent_env, JNI_VERSION_1_2);
Expand Down Expand Up @@ -195,17 +196,17 @@ void JVMCIEnv::init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env) {
}

JVMCIEnv::JVMCIEnv(JavaThread* thread, JVMCICompileState* compile_state, const char* file, int line):
_throw_to_caller(false), _file(file), _line(line), _init_error(JNI_OK), _compile_state(compile_state) {
_throw_to_caller(false), _file(file), _line(line), _init_error(JNI_OK), _init_error_msg(nullptr), _compile_state(compile_state) {
init_env_mode_runtime(thread, nullptr);
}

JVMCIEnv::JVMCIEnv(JavaThread* thread, const char* file, int line):
_throw_to_caller(false), _file(file), _line(line), _init_error(JNI_OK), _compile_state(nullptr) {
_throw_to_caller(false), _file(file), _line(line), _init_error(JNI_OK), _init_error_msg(nullptr), _compile_state(nullptr) {
init_env_mode_runtime(thread, nullptr);
}

JVMCIEnv::JVMCIEnv(JavaThread* thread, JNIEnv* parent_env, const char* file, int line):
_throw_to_caller(true), _file(file), _line(line), _init_error(JNI_OK), _compile_state(nullptr) {
_throw_to_caller(true), _file(file), _line(line), _init_error(JNI_OK), _init_error_msg(nullptr), _compile_state(nullptr) {
assert(parent_env != nullptr, "npe");
init_env_mode_runtime(thread, parent_env);
assert(_env == nullptr || parent_env == _env, "mismatched JNIEnvironment");
Expand All @@ -218,6 +219,7 @@ void JVMCIEnv::init(JavaThread* thread, bool is_hotspot, const char* file, int l
_file = file;
_line = line;
_init_error = JNI_OK;
_init_error_msg = nullptr;
if (is_hotspot) {
_env = nullptr;
_pop_frame_on_close = false;
Expand All @@ -237,7 +239,8 @@ void JVMCIEnv::check_init(JVMCI_TRAPS) {
if (_init_error == JNI_ENOMEM) {
JVMCI_THROW_MSG(OutOfMemoryError, "JNI_ENOMEM creating or attaching to libjvmci");
}
JVMCI_THROW_MSG(InternalError, err_msg("Error creating or attaching to libjvmci (err: %d)", _init_error));
JVMCI_THROW_MSG(InternalError, err_msg("Error creating or attaching to libjvmci (err: %d, description: %s)",
_init_error, _init_error_msg == nullptr ? "unknown" : _init_error_msg));
}

void JVMCIEnv::check_init(TRAPS) {
Expand All @@ -247,7 +250,8 @@ void JVMCIEnv::check_init(TRAPS) {
if (_init_error == JNI_ENOMEM) {
THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), "JNI_ENOMEM creating or attaching to libjvmci");
}
THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), err_msg("Error creating or attaching to libjvmci (err: %d)", _init_error));
THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), err_msg("Error creating or attaching to libjvmci (err: %d, description: %s)",
_init_error, _init_error_msg == nullptr ? "unknown" : _init_error_msg));
}

// Prints a pending exception (if any) and its stack trace to st.
Expand Down Expand Up @@ -572,6 +576,9 @@ jboolean JVMCIEnv::transfer_pending_exception(JavaThread* THREAD, JVMCIEnv* peer
}

JVMCIEnv::~JVMCIEnv() {
if (_init_error_msg != nullptr) {
os::free((void*) _init_error_msg);
}
if (_init_error != JNI_OK) {
return;
}
Expand Down
7 changes: 7 additions & 0 deletions src/hotspot/share/jvmci/jvmciEnv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ class JVMCIEnv : public ResourceObj {
int _init_error; // JNI code returned when creating or attaching to a libjvmci isolate.
// If not JNI_OK, the JVMCIEnv is invalid and should not be used apart from
// calling init_error().
const char* _init_error_msg; // Message for _init_error if available. C heap allocated.

// Translates an exception on the HotSpot heap (i.e., hotspot_env) to an exception on
// the shared library heap (i.e., jni_env). The translation includes the stack and cause(s) of `throwable`.
Expand Down Expand Up @@ -217,6 +218,12 @@ class JVMCIEnv : public ResourceObj {
return _init_error;
}

// Gets a message describing a non-zero init_error().
// Valid as long as this JVMCIEnv is valid.
const char* init_error_msg() {
return _init_error_msg;
}

// Checks the value of init_error() and throws an exception in `JVMCI_TRAPS`
// (which must not be this) if it is not JNI_OK.
void check_init(JVMCI_TRAPS);
Expand Down
6 changes: 4 additions & 2 deletions src/hotspot/share/jvmci/jvmciRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1246,7 +1246,7 @@ bool JVMCIRuntime::detach_thread(JavaThread* thread, const char* reason, bool ca
return destroyed_javavm;
}

JNIEnv* JVMCIRuntime::init_shared_library_javavm(int* create_JavaVM_err) {
JNIEnv* JVMCIRuntime::init_shared_library_javavm(int* create_JavaVM_err, const char** err_msg) {
MutexLocker locker(_lock);
JavaVM* javaVM = _shared_library_javavm;
if (javaVM == nullptr) {
Expand All @@ -1273,7 +1273,7 @@ JNIEnv* JVMCIRuntime::init_shared_library_javavm(int* create_JavaVM_err) {
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_2;
vm_args.ignoreUnrecognized = JNI_TRUE;
JavaVMOption options[5];
JavaVMOption options[6];
jlong javaVM_id = 0;

// Protocol: JVMCI shared library JavaVM should support a non-standard "_javavm_id"
Expand All @@ -1290,6 +1290,8 @@ JNIEnv* JVMCIRuntime::init_shared_library_javavm(int* create_JavaVM_err) {
options[3].extraInfo = (void*) _fatal;
options[4].optionString = (char*) "_fatal_log";
options[4].extraInfo = (void*) _fatal_log;
options[5].optionString = (char*) "_createvm_errorstr";
options[5].extraInfo = (void*) err_msg;

vm_args.version = JNI_VERSION_1_2;
vm_args.options = options;
Expand Down
6 changes: 4 additions & 2 deletions src/hotspot/share/jvmci/jvmciRuntime.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,10 @@ class JVMCIRuntime: public CHeapObj<mtJVMCI> {
// If the JavaVM was created by this call, then the thread-local JNI
// interface pointer for the JavaVM is returned otherwise null is returned.
// If this method tried to create the JavaVM but failed, the error code returned
// by JNI_CreateJavaVM is returned in create_JavaVM_err.
JNIEnv* init_shared_library_javavm(int* create_JavaVM_err);
// by JNI_CreateJavaVM is returned in create_JavaVM_err and, if available, an
// error message is malloc'ed and assigned to err_msg. The caller is responsible
// for freeing err_msg.
JNIEnv* init_shared_library_javavm(int* create_JavaVM_err, const char** err_msg);

// Determines if the JVMCI shared library JavaVM exists for this runtime.
bool has_shared_library_javavm() { return _shared_library_javavm != nullptr; }
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/prims/whitebox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ WB_ENTRY(jboolean, WB_IsGCSupportedByJVMCICompiler(JNIEnv* env, jobject o, jint
if (EnableJVMCI) {
// Enter the JVMCI env that will be used by the CompileBroker.
JVMCIEnv jvmciEnv(thread, __FILE__, __LINE__);
return jvmciEnv.runtime()->is_gc_supported(&jvmciEnv, (CollectedHeap::Name)name);
return jvmciEnv.init_error() == JNI_OK && jvmciEnv.runtime()->is_gc_supported(&jvmciEnv, (CollectedHeap::Name)name);
}
#endif
return false;
Expand Down