-
Notifications
You must be signed in to change notification settings - Fork 6.1k
8318694: [JVMCI] disable can_call_java in most contexts for libjvmci compiler threads #16383
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9fc5ad9
7f2285e
af42062
0370178
a646620
b7181d7
832a591
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -165,14 +165,19 @@ Handle JavaArgumentUnboxer::next_arg(BasicType expectedType) { | |
| MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \ | ||
| ThreadInVMfromNative __tiv(thread); \ | ||
| HandleMarkCleaner __hm(thread); \ | ||
| JavaThread* THREAD = thread; \ | ||
| JavaThread* THREAD = thread; \ | ||
| debug_only(VMNativeEntryWrapper __vew;) | ||
|
|
||
| // Native method block that transitions current thread to '_thread_in_vm'. | ||
| #define C2V_BLOCK(result_type, name, signature) \ | ||
| JVMCI_VM_ENTRY_MARK; \ | ||
| ResourceMark rm; \ | ||
| JVMCIENV_FROM_JNI(JVMCI::compilation_tick(thread), env); | ||
| // Note: CompilerThreadCanCallJava must precede JVMCIENV_FROM_JNI so that | ||
| // the translation of an uncaught exception in the JVMCIEnv does not make | ||
| // a Java call when __is_hotspot == false. | ||
| #define C2V_BLOCK(result_type, name, signature) \ | ||
| JVMCI_VM_ENTRY_MARK; \ | ||
| ResourceMark rm; \ | ||
| bool __is_hotspot = env == thread->jni_environment(); \ | ||
| CompilerThreadCanCallJava ccj(thread, __is_hotspot); \ | ||
| JVMCIENV_FROM_JNI(JVMCI::compilation_tick(thread), env); \ | ||
|
|
||
| static JavaThread* get_current_thread(bool allow_null=true) { | ||
| Thread* thread = Thread::current_or_null_safe(); | ||
|
|
@@ -188,7 +193,7 @@ static JavaThread* get_current_thread(bool allow_null=true) { | |
| #define C2V_VMENTRY(result_type, name, signature) \ | ||
| JNIEXPORT result_type JNICALL c2v_ ## name signature { \ | ||
| JavaThread* thread = get_current_thread(); \ | ||
| if (thread == nullptr) { \ | ||
| if (thread == nullptr) { \ | ||
| env->ThrowNew(JNIJVMCI::InternalError::clazz(), \ | ||
| err_msg("Cannot call into HotSpot from JVMCI shared library without attaching current thread")); \ | ||
| return; \ | ||
|
|
@@ -199,7 +204,7 @@ static JavaThread* get_current_thread(bool allow_null=true) { | |
| #define C2V_VMENTRY_(result_type, name, signature, result) \ | ||
| JNIEXPORT result_type JNICALL c2v_ ## name signature { \ | ||
| JavaThread* thread = get_current_thread(); \ | ||
| if (thread == nullptr) { \ | ||
| if (thread == nullptr) { \ | ||
| env->ThrowNew(JNIJVMCI::InternalError::clazz(), \ | ||
| err_msg("Cannot call into HotSpot from JVMCI shared library without attaching current thread")); \ | ||
| return result; \ | ||
|
|
@@ -221,15 +226,15 @@ static JavaThread* get_current_thread(bool allow_null=true) { | |
| #define JNI_THROW(caller, name, msg) do { \ | ||
| jint __throw_res = env->ThrowNew(JNIJVMCI::name::clazz(), msg); \ | ||
| if (__throw_res != JNI_OK) { \ | ||
| tty->print_cr("Throwing " #name " in " caller " returned %d", __throw_res); \ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The VM should prefer event logging over printing to the console. |
||
| JVMCI_event_1("Throwing " #name " in " caller " returned %d", __throw_res); \ | ||
| } \ | ||
| return; \ | ||
| } while (0); | ||
|
|
||
| #define JNI_THROW_(caller, name, msg, result) do { \ | ||
| jint __throw_res = env->ThrowNew(JNIJVMCI::name::clazz(), msg); \ | ||
| if (__throw_res != JNI_OK) { \ | ||
| tty->print_cr("Throwing " #name " in " caller " returned %d", __throw_res); \ | ||
| JVMCI_event_1("Throwing " #name " in " caller " returned %d", __throw_res); \ | ||
| } \ | ||
| return result; \ | ||
| } while (0) | ||
|
|
@@ -579,6 +584,7 @@ C2V_VMENTRY_0(jboolean, shouldInlineMethod,(JNIEnv* env, jobject, ARGUMENT_PAIR( | |
| C2V_END | ||
|
|
||
| C2V_VMENTRY_NULL(jobject, lookupType, (JNIEnv* env, jobject, jstring jname, ARGUMENT_PAIR(accessing_klass), jint accessing_klass_loader, jboolean resolve)) | ||
| CompilerThreadCanCallJava canCallJava(thread, resolve); // Resolution requires Java calls | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is currently required by libgraal - it may be fixable in future. |
||
| JVMCIObject name = JVMCIENV->wrap(jname); | ||
| const char* str = JVMCIENV->as_utf8_string(name); | ||
| TempNewSymbol class_name = SymbolTable::new_symbol(str); | ||
|
|
@@ -592,7 +598,7 @@ C2V_VMENTRY_NULL(jobject, lookupType, (JNIEnv* env, jobject, jstring jname, ARGU | |
| if (val != nullptr) { | ||
| if (strstr(val, "<trace>") != nullptr) { | ||
| tty->print_cr("CompilerToVM.lookupType: %s", str); | ||
| } else if (strstr(val, str) != nullptr) { | ||
| } else if (strstr(str, val) != nullptr) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This fixes an existing bug: the test is meant to be whether |
||
| THROW_MSG_0(vmSymbols::java_lang_Exception(), | ||
| err_msg("lookupTypeException: %s", str)); | ||
| } | ||
|
|
@@ -938,6 +944,17 @@ C2V_VMENTRY_NULL(jobject, resolveFieldInPool, (JNIEnv* env, jobject, ARGUMENT_PA | |
| Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF); | ||
| fieldDescriptor fd; | ||
| methodHandle mh(THREAD, UNPACK_PAIR(Method, method)); | ||
|
|
||
| Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF); | ||
| int holder_index = cp->klass_ref_index_at(index, bc); | ||
| if (!cp->tag_at(holder_index).is_klass() && !THREAD->can_call_java()) { | ||
| // If the holder is not resolved in the constant pool and the current | ||
| // thread cannot call Java, return null. This avoids a Java call | ||
| // in LinkInfo to load the holder. | ||
| Symbol* klass_name = cp->klass_ref_at_noresolve(index, bc); | ||
| return nullptr; | ||
| } | ||
|
|
||
| LinkInfo link_info(cp, index, mh, code, CHECK_NULL); | ||
| LinkResolver::resolve_field(fd, link_info, Bytecodes::java_code(code), false, CHECK_NULL); | ||
| JVMCIPrimitiveArray info = JVMCIENV->wrap(info_handle); | ||
|
|
@@ -2726,6 +2743,7 @@ C2V_VMENTRY_0(jlong, translate, (JNIEnv* env, jobject, jobject obj_handle, jbool | |
| return 0L; | ||
| } | ||
| PEER_JVMCIENV_FROM_THREAD(THREAD, !JVMCIENV->is_hotspot()); | ||
| CompilerThreadCanCallJava canCallJava(thread, PEER_JVMCIENV->is_hotspot()); | ||
| PEER_JVMCIENV->check_init(JVMCI_CHECK_0); | ||
|
|
||
| JVMCIEnv* thisEnv = JVMCIENV; | ||
|
|
@@ -2945,18 +2963,21 @@ static jbyteArray get_encoded_annotation_data(InstanceKlass* holder, AnnotationA | |
|
|
||
| C2V_VMENTRY_NULL(jbyteArray, getEncodedClassAnnotationData, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass), | ||
| jobject filter, jint filter_length, jlong filter_klass_pointers)) | ||
| CompilerThreadCanCallJava canCallJava(thread, true); // Requires Java support | ||
| InstanceKlass* holder = InstanceKlass::cast(UNPACK_PAIR(Klass, klass)); | ||
| return get_encoded_annotation_data(holder, holder->class_annotations(), true, filter_length, filter_klass_pointers, THREAD, JVMCIENV); | ||
| C2V_END | ||
|
|
||
| C2V_VMENTRY_NULL(jbyteArray, getEncodedExecutableAnnotationData, (JNIEnv* env, jobject, ARGUMENT_PAIR(method), | ||
| jobject filter, jint filter_length, jlong filter_klass_pointers)) | ||
| CompilerThreadCanCallJava canCallJava(thread, true); // Requires Java support | ||
| methodHandle method(THREAD, UNPACK_PAIR(Method, method)); | ||
| return get_encoded_annotation_data(method->method_holder(), method->annotations(), false, filter_length, filter_klass_pointers, THREAD, JVMCIENV); | ||
| C2V_END | ||
|
|
||
| C2V_VMENTRY_NULL(jbyteArray, getEncodedFieldAnnotationData, (JNIEnv* env, jobject, ARGUMENT_PAIR(klass), jint index, | ||
| jobject filter, jint filter_length, jlong filter_klass_pointers)) | ||
| CompilerThreadCanCallJava canCallJava(thread, true); // Requires Java support | ||
| InstanceKlass* holder = check_field(InstanceKlass::cast(UNPACK_PAIR(Klass, klass)), index, JVMCIENV); | ||
| fieldDescriptor fd(holder, index); | ||
| return get_encoded_annotation_data(holder, fd.annotations(), false, filter_length, filter_klass_pointers, THREAD, JVMCIENV); | ||
|
|
@@ -3013,6 +3034,7 @@ C2V_VMENTRY_0(jboolean, addFailedSpeculation, (JNIEnv* env, jobject, jlong faile | |
| C2V_END | ||
|
|
||
| C2V_VMENTRY(void, callSystemExit, (JNIEnv* env, jobject, jint status)) | ||
| CompilerThreadCanCallJava canCallJava(thread, true); | ||
| JavaValue result(T_VOID); | ||
| JavaCallArguments jargs(1); | ||
| jargs.push_int(status); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This allows
java_lang_Throwable::print_stack_traceto be used in contexts where Java calls cannot be made.