mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8317689: [JVMCI] include error message when CreateJavaVM in libgraal fails
Reviewed-by: phofer, thartmann, never
This commit is contained in:
parent
f9795d0d09
commit
8879c78d62
6 changed files with 33 additions and 13 deletions
|
@ -2211,7 +2211,9 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
|
||||||
} else {
|
} else {
|
||||||
JVMCIEnv env(thread, &compile_state, __FILE__, __LINE__);
|
JVMCIEnv env(thread, &compile_state, __FILE__, __LINE__);
|
||||||
if (env.init_error() != JNI_OK) {
|
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;
|
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
|
// 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.
|
// might succeed. Other errors most likely indicate a non-recoverable error in the JVMCI runtime.
|
||||||
|
|
|
@ -147,13 +147,14 @@ void JVMCIEnv::init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env) {
|
||||||
_is_hotspot = false;
|
_is_hotspot = false;
|
||||||
|
|
||||||
_runtime = JVMCI::compiler_runtime(thread);
|
_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) {
|
if (_env != nullptr) {
|
||||||
// Creating the JVMCI shared library VM also attaches the current thread
|
// Creating the JVMCI shared library VM also attaches the current thread
|
||||||
_detach_on_close = true;
|
_detach_on_close = true;
|
||||||
} else if (_init_error != JNI_OK) {
|
} else if (_init_error != JNI_OK) {
|
||||||
// Caller creating this JVMCIEnv must handle the error.
|
// 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;
|
return;
|
||||||
} else {
|
} else {
|
||||||
_runtime->GetEnv(thread, (void**)&parent_env, JNI_VERSION_1_2);
|
_runtime->GetEnv(thread, (void**)&parent_env, JNI_VERSION_1_2);
|
||||||
|
@ -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):
|
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);
|
init_env_mode_runtime(thread, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
JVMCIEnv::JVMCIEnv(JavaThread* thread, const char* file, int line):
|
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);
|
init_env_mode_runtime(thread, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
JVMCIEnv::JVMCIEnv(JavaThread* thread, JNIEnv* parent_env, const char* file, int line):
|
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");
|
assert(parent_env != nullptr, "npe");
|
||||||
init_env_mode_runtime(thread, parent_env);
|
init_env_mode_runtime(thread, parent_env);
|
||||||
assert(_env == nullptr || parent_env == _env, "mismatched JNIEnvironment");
|
assert(_env == nullptr || parent_env == _env, "mismatched JNIEnvironment");
|
||||||
|
@ -218,6 +219,7 @@ void JVMCIEnv::init(JavaThread* thread, bool is_hotspot, const char* file, int l
|
||||||
_file = file;
|
_file = file;
|
||||||
_line = line;
|
_line = line;
|
||||||
_init_error = JNI_OK;
|
_init_error = JNI_OK;
|
||||||
|
_init_error_msg = nullptr;
|
||||||
if (is_hotspot) {
|
if (is_hotspot) {
|
||||||
_env = nullptr;
|
_env = nullptr;
|
||||||
_pop_frame_on_close = false;
|
_pop_frame_on_close = false;
|
||||||
|
@ -237,7 +239,8 @@ void JVMCIEnv::check_init(JVMCI_TRAPS) {
|
||||||
if (_init_error == JNI_ENOMEM) {
|
if (_init_error == JNI_ENOMEM) {
|
||||||
JVMCI_THROW_MSG(OutOfMemoryError, "JNI_ENOMEM creating or attaching to libjvmci");
|
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) {
|
void JVMCIEnv::check_init(TRAPS) {
|
||||||
|
@ -247,7 +250,8 @@ void JVMCIEnv::check_init(TRAPS) {
|
||||||
if (_init_error == JNI_ENOMEM) {
|
if (_init_error == JNI_ENOMEM) {
|
||||||
THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), "JNI_ENOMEM creating or attaching to libjvmci");
|
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.
|
// Prints a pending exception (if any) and its stack trace to st.
|
||||||
|
@ -572,6 +576,9 @@ jboolean JVMCIEnv::transfer_pending_exception(JavaThread* THREAD, JVMCIEnv* peer
|
||||||
}
|
}
|
||||||
|
|
||||||
JVMCIEnv::~JVMCIEnv() {
|
JVMCIEnv::~JVMCIEnv() {
|
||||||
|
if (_init_error_msg != nullptr) {
|
||||||
|
os::free((void*) _init_error_msg);
|
||||||
|
}
|
||||||
if (_init_error != JNI_OK) {
|
if (_init_error != JNI_OK) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,6 +172,7 @@ class JVMCIEnv : public ResourceObj {
|
||||||
int _init_error; // JNI code returned when creating or attaching to a libjvmci isolate.
|
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
|
// If not JNI_OK, the JVMCIEnv is invalid and should not be used apart from
|
||||||
// calling init_error().
|
// 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
|
// 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`.
|
// the shared library heap (i.e., jni_env). The translation includes the stack and cause(s) of `throwable`.
|
||||||
|
@ -217,6 +218,12 @@ public:
|
||||||
return _init_error;
|
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`
|
// Checks the value of init_error() and throws an exception in `JVMCI_TRAPS`
|
||||||
// (which must not be this) if it is not JNI_OK.
|
// (which must not be this) if it is not JNI_OK.
|
||||||
void check_init(JVMCI_TRAPS);
|
void check_init(JVMCI_TRAPS);
|
||||||
|
|
|
@ -1253,7 +1253,7 @@ bool JVMCIRuntime::detach_thread(JavaThread* thread, const char* reason, bool ca
|
||||||
return destroyed_javavm;
|
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);
|
MutexLocker locker(_lock);
|
||||||
JavaVM* javaVM = _shared_library_javavm;
|
JavaVM* javaVM = _shared_library_javavm;
|
||||||
if (javaVM == nullptr) {
|
if (javaVM == nullptr) {
|
||||||
|
@ -1280,7 +1280,7 @@ JNIEnv* JVMCIRuntime::init_shared_library_javavm(int* create_JavaVM_err) {
|
||||||
JavaVMInitArgs vm_args;
|
JavaVMInitArgs vm_args;
|
||||||
vm_args.version = JNI_VERSION_1_2;
|
vm_args.version = JNI_VERSION_1_2;
|
||||||
vm_args.ignoreUnrecognized = JNI_TRUE;
|
vm_args.ignoreUnrecognized = JNI_TRUE;
|
||||||
JavaVMOption options[5];
|
JavaVMOption options[6];
|
||||||
jlong javaVM_id = 0;
|
jlong javaVM_id = 0;
|
||||||
|
|
||||||
// Protocol: JVMCI shared library JavaVM should support a non-standard "_javavm_id"
|
// Protocol: JVMCI shared library JavaVM should support a non-standard "_javavm_id"
|
||||||
|
@ -1297,6 +1297,8 @@ JNIEnv* JVMCIRuntime::init_shared_library_javavm(int* create_JavaVM_err) {
|
||||||
options[3].extraInfo = (void*) _fatal;
|
options[3].extraInfo = (void*) _fatal;
|
||||||
options[4].optionString = (char*) "_fatal_log";
|
options[4].optionString = (char*) "_fatal_log";
|
||||||
options[4].extraInfo = (void*) _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.version = JNI_VERSION_1_2;
|
||||||
vm_args.options = options;
|
vm_args.options = options;
|
||||||
|
|
|
@ -280,8 +280,10 @@ class JVMCIRuntime: public CHeapObj<mtJVMCI> {
|
||||||
// If the JavaVM was created by this call, then the thread-local JNI
|
// If the JavaVM was created by this call, then the thread-local JNI
|
||||||
// interface pointer for the JavaVM is returned otherwise null is returned.
|
// 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
|
// If this method tried to create the JavaVM but failed, the error code returned
|
||||||
// by JNI_CreateJavaVM is returned in create_JavaVM_err.
|
// by JNI_CreateJavaVM is returned in create_JavaVM_err and, if available, an
|
||||||
JNIEnv* init_shared_library_javavm(int* create_JavaVM_err);
|
// 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.
|
// Determines if the JVMCI shared library JavaVM exists for this runtime.
|
||||||
bool has_shared_library_javavm() { return _shared_library_javavm != nullptr; }
|
bool has_shared_library_javavm() { return _shared_library_javavm != nullptr; }
|
||||||
|
|
|
@ -381,7 +381,7 @@ WB_ENTRY(jboolean, WB_IsGCSupportedByJVMCICompiler(JNIEnv* env, jobject o, jint
|
||||||
if (EnableJVMCI) {
|
if (EnableJVMCI) {
|
||||||
// Enter the JVMCI env that will be used by the CompileBroker.
|
// Enter the JVMCI env that will be used by the CompileBroker.
|
||||||
JVMCIEnv jvmciEnv(thread, __FILE__, __LINE__);
|
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
|
#endif
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue