7196277: JSR 292: Two jck/runtime tests crash on java.lang.invoke.MethodHandle.invokeExact
Reviewed-by: jrose, kvn
This commit is contained in:
parent
1763afaec5
commit
149097fbb7
@ -832,7 +832,9 @@ void Method::link_method(methodHandle h_method, TRAPS) {
|
||||
assert(entry != NULL, "interpreter entry must be non-null");
|
||||
// Sets both _i2i_entry and _from_interpreted_entry
|
||||
set_interpreter_entry(entry);
|
||||
if (is_native() && !is_method_handle_intrinsic()) {
|
||||
|
||||
// Don't overwrite already registered native entries.
|
||||
if (is_native() && !has_native_function()) {
|
||||
set_native_function(
|
||||
SharedRuntime::native_method_throw_unsatisfied_link_error_entry(),
|
||||
!native_bind_event_is_interesting);
|
||||
|
@ -1298,6 +1298,28 @@ JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobjec
|
||||
}
|
||||
JVM_END
|
||||
|
||||
/**
|
||||
* Throws a java/lang/UnsupportedOperationException unconditionally.
|
||||
* This is required by the specification of MethodHandle.invoke if
|
||||
* invoked directly.
|
||||
*/
|
||||
JVM_ENTRY(jobject, MH_invoke_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
|
||||
THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invoke cannot be invoked reflectively");
|
||||
return NULL;
|
||||
}
|
||||
JVM_END
|
||||
|
||||
/**
|
||||
* Throws a java/lang/UnsupportedOperationException unconditionally.
|
||||
* This is required by the specification of MethodHandle.invokeExact if
|
||||
* invoked directly.
|
||||
*/
|
||||
JVM_ENTRY(jobject, MH_invokeExact_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
|
||||
THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invokeExact cannot be invoked reflectively");
|
||||
return NULL;
|
||||
}
|
||||
JVM_END
|
||||
|
||||
/// JVM_RegisterMethodHandleMethods
|
||||
|
||||
#undef CS // Solaris builds complain
|
||||
@ -1317,7 +1339,7 @@ JVM_END
|
||||
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
|
||||
|
||||
// These are the native methods on java.lang.invoke.MethodHandleNatives.
|
||||
static JNINativeMethod required_methods_JDK8[] = {
|
||||
static JNINativeMethod MHN_methods[] = {
|
||||
{CC"init", CC"("MEM""OBJ")V", FN_PTR(MHN_init_Mem)},
|
||||
{CC"expand", CC"("MEM")V", FN_PTR(MHN_expand_Mem)},
|
||||
{CC"resolve", CC"("MEM""CLS")"MEM, FN_PTR(MHN_resolve_Mem)},
|
||||
@ -1335,8 +1357,28 @@ static JNINativeMethod required_methods_JDK8[] = {
|
||||
{CC"getMemberVMInfo", CC"("MEM")"OBJ, FN_PTR(MHN_getMemberVMInfo)}
|
||||
};
|
||||
|
||||
// This one function is exported, used by NativeLookup.
|
||||
static JNINativeMethod MH_methods[] = {
|
||||
// UnsupportedOperationException throwers
|
||||
{CC"invoke", CC"(["OBJ")"OBJ, FN_PTR(MH_invoke_UOE)},
|
||||
{CC"invokeExact", CC"(["OBJ")"OBJ, FN_PTR(MH_invokeExact_UOE)}
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper method to register native methods.
|
||||
*/
|
||||
static bool register_natives(JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods) {
|
||||
int status = env->RegisterNatives(clazz, methods, nMethods);
|
||||
if (status != JNI_OK || env->ExceptionOccurred()) {
|
||||
warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
|
||||
env->ExceptionClear();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This one function is exported, used by NativeLookup.
|
||||
*/
|
||||
JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
|
||||
if (!EnableInvokeDynamic) {
|
||||
warning("JSR 292 is disabled in this JVM. Use -XX:+UnlockDiagnosticVMOptions -XX:+EnableInvokeDynamic to enable.");
|
||||
@ -1354,16 +1396,14 @@ JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class))
|
||||
MH_class = (jclass) JNIHandles::make_local(env, mirror);
|
||||
}
|
||||
|
||||
int status;
|
||||
|
||||
if (enable_MH) {
|
||||
ThreadToNativeFromVM ttnfv(thread);
|
||||
|
||||
status = env->RegisterNatives(MHN_class, required_methods_JDK8, sizeof(required_methods_JDK8)/sizeof(JNINativeMethod));
|
||||
if (status != JNI_OK || env->ExceptionOccurred()) {
|
||||
warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
|
||||
enable_MH = false;
|
||||
env->ExceptionClear();
|
||||
if (enable_MH) {
|
||||
enable_MH = register_natives(env, MHN_class, MHN_methods, sizeof(MHN_methods)/sizeof(JNINativeMethod));
|
||||
}
|
||||
if (enable_MH) {
|
||||
enable_MH = register_natives(env, MH_class, MH_methods, sizeof(MH_methods)/sizeof(JNINativeMethod));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -383,10 +383,7 @@ address NativeLookup::lookup_base(methodHandle method, bool& in_base_library, TR
|
||||
|
||||
address NativeLookup::lookup(methodHandle method, bool& in_base_library, TRAPS) {
|
||||
if (!method->has_native_function()) {
|
||||
address entry =
|
||||
method->intrinsic_id() == vmIntrinsics::_invokeGeneric ?
|
||||
SharedRuntime::native_method_throw_unsupported_operation_exception_entry() :
|
||||
lookup_base(method, in_base_library, CHECK_NULL);
|
||||
address entry = lookup_base(method, in_base_library, CHECK_NULL);
|
||||
method->set_native_function(entry,
|
||||
Method::native_bind_event_is_interesting);
|
||||
// -verbose:jni printing
|
||||
|
@ -883,15 +883,23 @@ address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread,
|
||||
}
|
||||
|
||||
|
||||
JNI_ENTRY(void, throw_unsatisfied_link_error(JNIEnv* env, ...))
|
||||
/**
|
||||
* Throws an java/lang/UnsatisfiedLinkError. The address of this method is
|
||||
* installed in the native function entry of all native Java methods before
|
||||
* they get linked to their actual native methods.
|
||||
*
|
||||
* \note
|
||||
* This method actually never gets called! The reason is because
|
||||
* the interpreter's native entries call NativeLookup::lookup() which
|
||||
* throws the exception when the lookup fails. The exception is then
|
||||
* caught and forwarded on the return from NativeLookup::lookup() call
|
||||
* before the call to the native function. This might change in the future.
|
||||
*/
|
||||
JNI_ENTRY(void*, throw_unsatisfied_link_error(JNIEnv* env, ...))
|
||||
{
|
||||
THROW(vmSymbols::java_lang_UnsatisfiedLinkError());
|
||||
}
|
||||
JNI_END
|
||||
|
||||
JNI_ENTRY(void, throw_unsupported_operation_exception(JNIEnv* env, ...))
|
||||
{
|
||||
THROW(vmSymbols::java_lang_UnsupportedOperationException());
|
||||
// We return a bad value here to make sure that the exception is
|
||||
// forwarded before we look at the return value.
|
||||
THROW_(vmSymbols::java_lang_UnsatisfiedLinkError(), (void*)badJNIHandle);
|
||||
}
|
||||
JNI_END
|
||||
|
||||
@ -899,10 +907,6 @@ address SharedRuntime::native_method_throw_unsatisfied_link_error_entry() {
|
||||
return CAST_FROM_FN_PTR(address, &throw_unsatisfied_link_error);
|
||||
}
|
||||
|
||||
address SharedRuntime::native_method_throw_unsupported_operation_exception_entry() {
|
||||
return CAST_FROM_FN_PTR(address, &throw_unsupported_operation_exception);
|
||||
}
|
||||
|
||||
|
||||
#ifndef PRODUCT
|
||||
JRT_ENTRY(intptr_t, SharedRuntime::trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2))
|
||||
|
Loading…
x
Reference in New Issue
Block a user