Skip to content

Commit d7e4087

Browse files
author
Doug Simon
committed
8315369: [JVMCI] failure to attach to a libgraal isolate during shutdown should not be fatal
Reviewed-by: never
1 parent d1cabe4 commit d7e4087

File tree

7 files changed

+131
-110
lines changed

7 files changed

+131
-110
lines changed

src/hotspot/share/compiler/compileBroker.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2203,7 +2203,14 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
22032203
compilable = ciEnv::MethodCompilable_never;
22042204
} else {
22052205
JVMCIEnv env(thread, &compile_state, __FILE__, __LINE__);
2206-
failure_reason = compile_state.failure_reason();
2206+
if (env.init_error() != JNI_OK) {
2207+
failure_reason = os::strdup(err_msg("Error attaching to libjvmci (err: %d)", env.init_error()), mtJVMCI);
2208+
bool reason_on_C_heap = true;
2209+
// In case of JNI_ENOMEM, there's a good chance a subsequent attempt to create libjvmci or attach to it
2210+
// might succeed. Other errors most likely indicate a non-recoverable error in the JVMCI runtime.
2211+
bool retryable = env.init_error() == JNI_ENOMEM;
2212+
compile_state.set_failure(retryable, failure_reason, reason_on_C_heap);
2213+
}
22072214
if (failure_reason == nullptr) {
22082215
if (WhiteBoxAPI && WhiteBox::compilation_locked) {
22092216
// Must switch to native to block

src/hotspot/share/jvmci/jniAccessMark.inline.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class JNIAccessMark : public StackObj {
4444
inline JNIAccessMark(JVMCIEnv* jvmci_env, JavaThread* thread=JavaThread::current()) :
4545
_ttnfv(thread), _hm(thread) {
4646
_env = jvmci_env->_env;
47+
guarantee(jvmci_env->init_error() == JNI_OK, "invalid JVMCIEnv (err: %d)", jvmci_env->init_error());
4748
}
4849
JNIEnv* env() const { return _env; }
4950
JNIEnv* operator () () const { return _env; }

src/hotspot/share/jvmci/jvmciCompilerToVM.cpp

Lines changed: 25 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ Handle JavaArgumentUnboxer::next_arg(BasicType expectedType) {
171171
#define C2V_BLOCK(result_type, name, signature) \
172172
JVMCI_VM_ENTRY_MARK; \
173173
ResourceMark rm; \
174-
JNI_JVMCIENV(JVMCI::compilation_tick(thread), env);
174+
JVMCIENV_FROM_JNI(JVMCI::compilation_tick(thread), env);
175175

176176
static JavaThread* get_current_thread(bool allow_null=true) {
177177
Thread* thread = Thread::current_or_null_safe();
@@ -2436,16 +2436,13 @@ C2V_VMENTRY_NULL(jlongArray, registerNativeMethods, (JNIEnv* env, jobject, jclas
24362436
JVMCIRuntime* runtime;
24372437
{
24382438
// Ensure the JVMCI shared library runtime is initialized.
2439-
bool jni_enomem_is_fatal = false;
2440-
JVMCIEnv __peer_jvmci_env__(thread, false, jni_enomem_is_fatal, __FILE__, __LINE__);
2441-
JVMCIEnv* peerEnv = &__peer_jvmci_env__;
2442-
if (peerEnv->has_jni_enomem()) {
2443-
JVMCI_THROW_MSG_0(OutOfMemoryError, "JNI_ENOMEM creating or attaching to libjvmci");
2444-
}
2439+
PEER_JVMCIENV_FROM_THREAD(THREAD, false);
2440+
PEER_JVMCIENV->check_init(JVMCI_CHECK_NULL);
2441+
24452442
HandleMark hm(THREAD);
24462443
runtime = JVMCI::compiler_runtime(thread);
2447-
if (peerEnv->has_pending_exception()) {
2448-
peerEnv->describe_pending_exception(tty);
2444+
if (PEER_JVMCIENV->has_pending_exception()) {
2445+
PEER_JVMCIENV->describe_pending_exception(tty);
24492446
}
24502447
sl_handle = JVMCI::get_shared_library(sl_path, false);
24512448
if (sl_handle == nullptr) {
@@ -2604,17 +2601,13 @@ C2V_VMENTRY_PREFIX(jboolean, attachCurrentThread, (JNIEnv* env, jobject c2vm, jb
26042601

26052602
{
26062603
// Ensure the JVMCI shared library runtime is initialized.
2607-
bool jni_enomem_is_fatal = false;
2608-
JVMCIEnv __peer_jvmci_env__(thread, false, jni_enomem_is_fatal, __FILE__, __LINE__);
2609-
JVMCIEnv* peerJVMCIEnv = &__peer_jvmci_env__;
2610-
if (peerJVMCIEnv->has_jni_enomem()) {
2611-
JVMCI_THROW_MSG_0(OutOfMemoryError, "JNI_ENOMEM creating or attaching to libjvmci");
2612-
}
2604+
PEER_JVMCIENV_FROM_THREAD(THREAD, false);
2605+
PEER_JVMCIENV->check_init(JVMCI_CHECK_0);
26132606

26142607
HandleMark hm(thread);
2615-
JVMCIObject receiver = runtime->get_HotSpotJVMCIRuntime(peerJVMCIEnv);
2616-
if (peerJVMCIEnv->has_pending_exception()) {
2617-
peerJVMCIEnv->describe_pending_exception(tty);
2608+
JVMCIObject receiver = runtime->get_HotSpotJVMCIRuntime(PEER_JVMCIENV);
2609+
if (PEER_JVMCIENV->has_pending_exception()) {
2610+
PEER_JVMCIENV->describe_pending_exception(tty);
26182611
}
26192612
char* sl_path;
26202613
if (JVMCI::get_shared_library(sl_path, false) == nullptr) {
@@ -2704,33 +2697,29 @@ C2V_VMENTRY_0(jlong, translate, (JNIEnv* env, jobject, jobject obj_handle, jbool
27042697
if (obj_handle == nullptr) {
27052698
return 0L;
27062699
}
2707-
bool jni_enomem_is_fatal = false;
2708-
JVMCIEnv __peer_jvmci_env__(thread, !JVMCIENV->is_hotspot(), jni_enomem_is_fatal, __FILE__, __LINE__);
2709-
JVMCIEnv* peerEnv = &__peer_jvmci_env__;
2710-
JVMCIEnv* thisEnv = JVMCIENV;
2711-
if (peerEnv->has_jni_enomem()) {
2712-
JVMCI_THROW_MSG_0(OutOfMemoryError, "JNI_ENOMEM creating or attaching to libjvmci");
2713-
}
2700+
PEER_JVMCIENV_FROM_THREAD(THREAD, !JVMCIENV->is_hotspot());
2701+
PEER_JVMCIENV->check_init(JVMCI_CHECK_0);
27142702

2703+
JVMCIEnv* thisEnv = JVMCIENV;
27152704
JVMCIObject obj = thisEnv->wrap(obj_handle);
27162705
JVMCIObject result;
27172706
if (thisEnv->isa_HotSpotResolvedJavaMethodImpl(obj)) {
27182707
methodHandle method(THREAD, thisEnv->asMethod(obj));
2719-
result = peerEnv->get_jvmci_method(method, JVMCI_CHECK_0);
2708+
result = PEER_JVMCIENV->get_jvmci_method(method, JVMCI_CHECK_0);
27202709
} else if (thisEnv->isa_HotSpotResolvedObjectTypeImpl(obj)) {
27212710
Klass* klass = thisEnv->asKlass(obj);
27222711
JVMCIKlassHandle klass_handle(THREAD);
27232712
klass_handle = klass;
2724-
result = peerEnv->get_jvmci_type(klass_handle, JVMCI_CHECK_0);
2713+
result = PEER_JVMCIENV->get_jvmci_type(klass_handle, JVMCI_CHECK_0);
27252714
} else if (thisEnv->isa_HotSpotResolvedPrimitiveType(obj)) {
27262715
BasicType type = JVMCIENV->kindToBasicType(JVMCIENV->get_HotSpotResolvedPrimitiveType_kind(obj), JVMCI_CHECK_0);
2727-
result = peerEnv->get_jvmci_primitive_type(type);
2716+
result = PEER_JVMCIENV->get_jvmci_primitive_type(type);
27282717
} else if (thisEnv->isa_IndirectHotSpotObjectConstantImpl(obj) ||
27292718
thisEnv->isa_DirectHotSpotObjectConstantImpl(obj)) {
27302719
Handle constant = thisEnv->asConstant(obj, JVMCI_CHECK_0);
2731-
result = peerEnv->get_object_constant(constant());
2720+
result = PEER_JVMCIENV->get_object_constant(constant());
27322721
} else if (thisEnv->isa_HotSpotNmethod(obj)) {
2733-
if (peerEnv->is_hotspot()) {
2722+
if (PEER_JVMCIENV->is_hotspot()) {
27342723
nmethod* nm = JVMCIENV->get_nmethod(obj);
27352724
if (nm != nullptr) {
27362725
JVMCINMethodData* data = nm->jvmci_nmethod_data();
@@ -2753,17 +2742,17 @@ C2V_VMENTRY_0(jlong, translate, (JNIEnv* env, jobject, jobject obj_handle, jbool
27532742
JVMCIObject name_string = thisEnv->get_InstalledCode_name(obj);
27542743
const char* cstring = name_string.is_null() ? nullptr : thisEnv->as_utf8_string(name_string);
27552744
// Create a new HotSpotNmethod instance in the peer runtime
2756-
result = peerEnv->new_HotSpotNmethod(mh, cstring, isDefault, compileIdSnapshot, JVMCI_CHECK_0);
2745+
result = PEER_JVMCIENV->new_HotSpotNmethod(mh, cstring, isDefault, compileIdSnapshot, JVMCI_CHECK_0);
27572746
nmethod* nm = JVMCIENV->get_nmethod(obj);
27582747
if (result.is_null()) {
27592748
// exception occurred (e.g. OOME) creating a new HotSpotNmethod
27602749
} else if (nm == nullptr) {
27612750
// nmethod must have been unloaded
27622751
} else {
27632752
// Link the new HotSpotNmethod to the nmethod
2764-
peerEnv->initialize_installed_code(result, nm, JVMCI_CHECK_0);
2753+
PEER_JVMCIENV->initialize_installed_code(result, nm, JVMCI_CHECK_0);
27652754
// Only HotSpotNmethod instances in the HotSpot heap are tracked directly by the runtime.
2766-
if (peerEnv->is_hotspot()) {
2755+
if (PEER_JVMCIENV->is_hotspot()) {
27672756
JVMCINMethodData* data = nm->jvmci_nmethod_data();
27682757
if (data == nullptr) {
27692758
JVMCI_THROW_MSG_0(IllegalArgumentException, "Cannot set HotSpotNmethod mirror for default nmethod");
@@ -2781,13 +2770,13 @@ C2V_VMENTRY_0(jlong, translate, (JNIEnv* env, jobject, jobject obj_handle, jbool
27812770
err_msg("Cannot translate object of type: %s", thisEnv->klass_name(obj)));
27822771
}
27832772
if (callPostTranslation) {
2784-
peerEnv->call_HotSpotJVMCIRuntime_postTranslation(result, JVMCI_CHECK_0);
2773+
PEER_JVMCIENV->call_HotSpotJVMCIRuntime_postTranslation(result, JVMCI_CHECK_0);
27852774
}
27862775
// Propagate any exception that occurred while creating the translated object
2787-
if (peerEnv->transfer_pending_exception(thread, thisEnv)) {
2776+
if (PEER_JVMCIENV->transfer_pending_exception(thread, thisEnv)) {
27882777
return 0L;
27892778
}
2790-
return (jlong) peerEnv->make_global(result).as_jobject();
2779+
return (jlong) PEER_JVMCIENV->make_global(result).as_jobject();
27912780
}
27922781

27932782
C2V_VMENTRY_NULL(jobject, unhand, (JNIEnv* env, jobject, jlong obj_handle))

src/hotspot/share/jvmci/jvmciEnv.cpp

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ bool JVMCICompileState::jvmti_state_changed() const {
115115
return false;
116116
}
117117

118-
void JVMCIEnv::init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env, bool jni_enomem_is_fatal) {
118+
void JVMCIEnv::init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env) {
119119
assert(thread != nullptr, "npe");
120120
_env = nullptr;
121121
_pop_frame_on_close = false;
@@ -147,18 +147,14 @@ void JVMCIEnv::init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env, boo
147147
_is_hotspot = false;
148148

149149
_runtime = JVMCI::compiler_runtime(thread);
150-
int create_JavaVM_err = JNI_OK;
151-
_env = _runtime->init_shared_library_javavm(&create_JavaVM_err);
150+
_env = _runtime->init_shared_library_javavm(&_init_error);
152151
if (_env != nullptr) {
153152
// Creating the JVMCI shared library VM also attaches the current thread
154153
_detach_on_close = true;
155-
} else if (create_JavaVM_err != JNI_OK) {
156-
if (!jni_enomem_is_fatal && create_JavaVM_err == JNI_ENOMEM) {
157-
_jni_enomem = true;
158-
return;
159-
} else {
160-
fatal("JNI_CreateJavaVM failed with return value %d", create_JavaVM_err);
161-
}
154+
} else if (_init_error != JNI_OK) {
155+
// Caller creating this JVMCIEnv must handle the error.
156+
JVMCI_event_1("[%s:%d] Error creating libjvmci (err: %d)", _file, _line, _init_error);
157+
return;
162158
} else {
163159
_runtime->GetEnv(thread, (void**)&parent_env, JNI_VERSION_1_2);
164160
if (parent_env != nullptr) {
@@ -174,15 +170,14 @@ void JVMCIEnv::init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env, boo
174170
attach_args.version = JNI_VERSION_1_2;
175171
attach_args.name = const_cast<char*>(thread->name());
176172
attach_args.group = nullptr;
177-
jint attach_result = _runtime->AttachCurrentThread(thread, (void**) &_env, &attach_args);
178-
if (attach_result == JNI_OK) {
173+
_init_error = _runtime->AttachCurrentThread(thread, (void**) &_env, &attach_args);
174+
if (_init_error == JNI_OK) {
179175
_detach_on_close = true;
180-
} else if (!jni_enomem_is_fatal && attach_result == JNI_ENOMEM) {
176+
} else {
177+
// Caller creating this JVMCIEnv must handle the error.
181178
_env = nullptr;
182-
_jni_enomem = true;
179+
JVMCI_event_1("[%s:%d] Error attaching to libjvmci (err: %d)", _file, _line, _init_error);
183180
return;
184-
} else {
185-
fatal("Error attaching current thread (%s) to JVMCI shared library JNI interface", attach_args.name);
186181
}
187182
}
188183
}
@@ -193,50 +188,66 @@ void JVMCIEnv::init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env, boo
193188
JNIAccessMark jni(this, thread);
194189
jint result = _env->PushLocalFrame(32);
195190
if (result != JNI_OK) {
196-
char message[256];
197-
jio_snprintf(message, 256, "Uncaught exception pushing local frame for JVMCIEnv scope entered at %s:%d", _file, _line);
198-
JVMCIRuntime::fatal_exception(this, message);
191+
JVMCI_event_1("[%s:%d] Error pushing local JNI frame (err: %d)", _file, _line, _init_error);
192+
return;
199193
}
200194
_pop_frame_on_close = true;
201195
}
202196

203197
JVMCIEnv::JVMCIEnv(JavaThread* thread, JVMCICompileState* compile_state, const char* file, int line):
204-
_throw_to_caller(false), _file(file), _line(line), _jni_enomem(false), _compile_state(compile_state) {
205-
// In case of JNI_ENOMEM, there's a good chance a subsequent attempt to create libjvmci or attach to it
206-
// might succeed. Other errors most likely indicate a non-recoverable error in the JVMCI runtime.
207-
bool jni_enomem_is_fatal = false;
208-
init_env_mode_runtime(thread, nullptr, jni_enomem_is_fatal);
209-
if (_jni_enomem) {
210-
compile_state->set_failure(true, "Out of memory while attaching JVMCI compiler to current thread");
211-
}
198+
_throw_to_caller(false), _file(file), _line(line), _init_error(JNI_OK), _compile_state(compile_state) {
199+
init_env_mode_runtime(thread, nullptr);
212200
}
213201

214202
JVMCIEnv::JVMCIEnv(JavaThread* thread, const char* file, int line):
215-
_throw_to_caller(false), _file(file), _line(line), _jni_enomem(false), _compile_state(nullptr) {
203+
_throw_to_caller(false), _file(file), _line(line), _init_error(JNI_OK), _compile_state(nullptr) {
216204
init_env_mode_runtime(thread, nullptr);
217205
}
218206

219207
JVMCIEnv::JVMCIEnv(JavaThread* thread, JNIEnv* parent_env, const char* file, int line):
220-
_throw_to_caller(true), _file(file), _line(line), _jni_enomem(false), _compile_state(nullptr) {
208+
_throw_to_caller(true), _file(file), _line(line), _init_error(JNI_OK), _compile_state(nullptr) {
209+
assert(parent_env != nullptr, "npe");
221210
init_env_mode_runtime(thread, parent_env);
222211
assert(_env == nullptr || parent_env == _env, "mismatched JNIEnvironment");
212+
assert(_init_error == JNI_OK, "err: %d", _init_error);
223213
}
224214

225-
void JVMCIEnv::init(JavaThread* thread, bool is_hotspot, bool jni_enomem_is_fatal, const char* file, int line) {
215+
void JVMCIEnv::init(JavaThread* thread, bool is_hotspot, const char* file, int line) {
226216
_compile_state = nullptr;
227217
_throw_to_caller = false;
228218
_file = file;
229219
_line = line;
230-
_jni_enomem = false;
220+
_init_error = JNI_OK;
231221
if (is_hotspot) {
232222
_env = nullptr;
233223
_pop_frame_on_close = false;
234224
_detach_on_close = false;
235225
_is_hotspot = true;
236226
_runtime = JVMCI::java_runtime();
237227
} else {
238-
init_env_mode_runtime(thread, nullptr, jni_enomem_is_fatal);
228+
init_env_mode_runtime(thread, nullptr);
229+
}
230+
}
231+
232+
void JVMCIEnv::check_init(JVMCI_TRAPS) {
233+
guarantee(JVMCIENV != this, "must be");
234+
if (_init_error == JNI_OK) {
235+
return;
236+
}
237+
if (_init_error == JNI_ENOMEM) {
238+
JVMCI_THROW_MSG(OutOfMemoryError, "JNI_ENOMEM creating or attaching to libjvmci");
239+
}
240+
JVMCI_THROW_MSG(InternalError, err_msg("Error creating or attaching to libjvmci (err: %d)", _init_error));
241+
}
242+
243+
void JVMCIEnv::check_init(TRAPS) {
244+
if (_init_error == JNI_OK) {
245+
return;
246+
}
247+
if (_init_error == JNI_ENOMEM) {
248+
THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), "JNI_ENOMEM creating or attaching to libjvmci");
239249
}
250+
THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), err_msg("Error creating or attaching to libjvmci (err: %d)", _init_error));
240251
}
241252

242253
// Prints a pending exception (if any) and its stack trace to st.
@@ -561,7 +572,7 @@ jboolean JVMCIEnv::transfer_pending_exception(JavaThread* THREAD, JVMCIEnv* peer
561572
}
562573

563574
JVMCIEnv::~JVMCIEnv() {
564-
if (_jni_enomem) {
575+
if (_init_error != JNI_OK) {
565576
return;
566577
}
567578
if (_throw_to_caller) {

src/hotspot/share/jvmci/jvmciEnv.hpp

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,9 @@ class JVMCIEnv : public ResourceObj {
157157
friend class JNIAccessMark;
158158

159159
// Initializes the _env, _mode and _runtime fields.
160-
void init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env, bool jni_enomem_is_fatal = true);
160+
void init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env);
161161

162-
void init(JavaThread* thread, bool is_hotspot, bool jni_enomem_is_fatal, const char* file, int line);
162+
void init(JavaThread* thread, bool is_hotspot, const char* file, int line);
163163

164164
JNIEnv* _env; // JNI env for calling into shared library
165165
bool _pop_frame_on_close; // Must pop frame on close?
@@ -169,9 +169,9 @@ class JVMCIEnv : public ResourceObj {
169169
bool _throw_to_caller; // Propagate an exception raised in this env to the caller?
170170
const char* _file; // The file and ...
171171
int _line; // ... line where this JNIEnv was created
172-
bool _jni_enomem; // JNI_ENOMEM returned when creating or attaching to a libjvmci isolate.
173-
// If true, the JVMCIEnv is invalid and should not be used apart from
174-
// calling has_jni_enomem().
172+
int _init_error; // JNI code returned when creating or attaching to a libjvmci isolate.
173+
// If not JNI_OK, the JVMCIEnv is invalid and should not be used apart from
174+
// calling init_error().
175175

176176
// Translates an exception on the HotSpot heap (i.e., hotspot_env) to an exception on
177177
// the shared library heap (i.e., jni_env). The translation includes the stack and cause(s) of `throwable`.
@@ -185,11 +185,12 @@ class JVMCIEnv : public ResourceObj {
185185

186186
public:
187187
// Opens a JVMCIEnv scope for a Java to VM call (e.g., via CompilerToVM).
188+
// The `parent_env` argument must not be null.
188189
// An exception occurring within the scope is left pending when the
189190
// scope closes so that it will be propagated back to Java.
190191
// The JVMCIEnv destructor translates the exception object for the
191192
// Java runtime if necessary.
192-
JVMCIEnv(JavaThread* thread, JNIEnv* env, const char* file, int line);
193+
JVMCIEnv(JavaThread* thread, JNIEnv* parent_env, const char* file, int line);
193194

194195
// Opens a JVMCIEnv scope for a compilation scheduled by the CompileBroker.
195196
// An exception occurring within the scope must not be propagated back to
@@ -200,34 +201,32 @@ class JVMCIEnv : public ResourceObj {
200201
// within the scope must not be propagated back to the caller.
201202
JVMCIEnv(JavaThread* env, const char* file, int line);
202203

203-
// Opens a JNIEnv scope for accessing `for_object`. An exception occurring
204-
// within the scope must not be propagated back to the caller.
205-
JVMCIEnv(JavaThread* thread, JVMCIObject for_object, const char* file, int line) {
206-
// A JNI call to access an object in the shared library heap
207-
// can block or take a long time so do not allow such access
208-
// on the VM thread.
209-
assert(for_object.is_hotspot() || !Thread::current()->is_VM_thread(),
210-
"cannot open JVMCIEnv scope when in the VM thread for accessing a shared library heap object");
211-
bool jni_enomem_is_fatal = true;
212-
init(thread, for_object.is_hotspot(), jni_enomem_is_fatal, file, line);
213-
}
214-
215204
// Opens a JNIEnv scope for the HotSpot runtime if `is_hotspot` is true
216205
// otherwise for the shared library runtime. An exception occurring
217206
// within the scope must not be propagated back to the caller.
218-
JVMCIEnv(JavaThread* thread, bool is_hotspot, bool jni_enomem_is_fatal, const char* file, int line) {
219-
init(thread, is_hotspot, jni_enomem_is_fatal, file, line);
207+
JVMCIEnv(JavaThread* thread, bool is_hotspot, const char* file, int line) {
208+
init(thread, is_hotspot, file, line);
220209
}
221210

222211
~JVMCIEnv();
223212

224-
// Determines if a JNI_ENOMEM occurred while trying to create a libjvmci
225-
// isolate or attach to it within the scope of a JVMCIEnv constructor.
226-
bool has_jni_enomem() {
227-
return _jni_enomem;
213+
// Gets the JNI result code returned when creating or attaching to a libjvmci isolate.
214+
// If not JNI_OK, the JVMCIEnv is invalid and the caller must abort the operation
215+
// this JVMCIEnv context was created for.
216+
int init_error() {
217+
return _init_error;
228218
}
229219

220+
// Checks the value of init_error() and throws an exception in `JVMCI_TRAPS`
221+
// (which must not be this) if it is not JNI_OK.
222+
void check_init(JVMCI_TRAPS);
223+
224+
// Checks the value of init_error() and throws an exception in `TRAPS`
225+
// if it is not JNI_OK.
226+
void check_init(TRAPS);
227+
230228
JVMCIRuntime* runtime() {
229+
guarantee(_init_error == 0, "invalid JVMCIEnv: %d", _init_error);
231230
return _runtime;
232231
}
233232

0 commit comments

Comments
 (0)