src/share/vm/prims/methodHandles.cpp
Print this page
rev 4509 : 7196277: JSR 292: Two jck/runtime tests crash on java.lang.invoke.MethodHandle.invokeExact
Reviewed-by: jrose, kvn
*** 1185,1194 ****
--- 1185,1216 ----
java_lang_invoke_CallSite::set_target_volatile(call_site(), target());
}
}
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
#define LANG "Ljava/lang/"
*** 1204,1214 ****
#define CC (char*) /*cast a literal from (const char*)*/
#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[] = {
{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)},
{CC"getConstant", CC"(I)I", FN_PTR(MHN_getConstant)},
// static native int getNamedCon(int which, Object[] name)
--- 1226,1236 ----
#define CC (char*) /*cast a literal from (const char*)*/
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
// These are the native methods on java.lang.invoke.MethodHandleNatives.
! 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)},
{CC"getConstant", CC"(I)I", FN_PTR(MHN_getConstant)},
// static native int getNamedCon(int which, Object[] name)
*** 1222,1233 ****
{CC"staticFieldOffset", CC"("MEM")J", FN_PTR(MHN_staticFieldOffset)},
{CC"staticFieldBase", CC"("MEM")"OBJ, FN_PTR(MHN_staticFieldBase)},
{CC"getMemberVMInfo", CC"("MEM")"OBJ, FN_PTR(MHN_getMemberVMInfo)}
};
! // 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.");
return; // bind nothing
}
--- 1244,1275 ----
{CC"staticFieldOffset", CC"("MEM")J", FN_PTR(MHN_staticFieldOffset)},
{CC"staticFieldBase", CC"("MEM")"OBJ, FN_PTR(MHN_staticFieldBase)},
{CC"getMemberVMInfo", CC"("MEM")"OBJ, FN_PTR(MHN_getMemberVMInfo)}
};
! 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.");
return; // bind nothing
}
*** 1241,1262 ****
} else {
oop mirror = Klass::cast(SystemDictionary::MethodHandle_klass())->java_mirror();
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 (TraceInvokeDynamic) {
tty->print_cr("MethodHandle support loaded (using LambdaForms)");
}
--- 1283,1302 ----
} else {
oop mirror = Klass::cast(SystemDictionary::MethodHandle_klass())->java_mirror();
MH_class = (jclass) JNIHandles::make_local(env, mirror);
}
if (enable_MH) {
ThreadToNativeFromVM ttnfv(thread);
! 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));
}
+ }
if (TraceInvokeDynamic) {
tty->print_cr("MethodHandle support loaded (using LambdaForms)");
}