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)"); }