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


1170     // Walk all nmethods depending on this call site.
1171     MutexLocker mu(Compile_lock, thread);
1172     Universe::flush_dependents_on(call_site, target);
1173     java_lang_invoke_CallSite::set_target(call_site(), target());
1174   }
1175 }
1176 JVM_END
1177 
1178 JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
1179   Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
1180   Handle target   (THREAD, JNIHandles::resolve(target_jh));
1181   {
1182     // Walk all nmethods depending on this call site.
1183     MutexLocker mu(Compile_lock, thread);
1184     Universe::flush_dependents_on(call_site, target);
1185     java_lang_invoke_CallSite::set_target_volatile(call_site(), target());
1186   }
1187 }
1188 JVM_END
1189 






















1190 /// JVM_RegisterMethodHandleMethods
1191 
1192 #undef CS  // Solaris builds complain
1193 
1194 #define LANG "Ljava/lang/"
1195 #define JLINV "Ljava/lang/invoke/"
1196 
1197 #define OBJ   LANG"Object;"
1198 #define CLS   LANG"Class;"
1199 #define STRG  LANG"String;"
1200 #define CS    JLINV"CallSite;"
1201 #define MT    JLINV"MethodType;"
1202 #define MH    JLINV"MethodHandle;"
1203 #define MEM   JLINV"MemberName;"
1204 
1205 #define CC (char*)  /*cast a literal from (const char*)*/
1206 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
1207 
1208 // These are the native methods on java.lang.invoke.MethodHandleNatives.
1209 static JNINativeMethod required_methods_JDK8[] = {
1210   {CC"init",                      CC"("MEM""OBJ")V",                     FN_PTR(MHN_init_Mem)},
1211   {CC"expand",                    CC"("MEM")V",                          FN_PTR(MHN_expand_Mem)},
1212   {CC"resolve",                   CC"("MEM""CLS")"MEM,                   FN_PTR(MHN_resolve_Mem)},
1213   {CC"getConstant",               CC"(I)I",                              FN_PTR(MHN_getConstant)},
1214   //  static native int getNamedCon(int which, Object[] name)
1215   {CC"getNamedCon",               CC"(I["OBJ")I",                        FN_PTR(MHN_getNamedCon)},
1216   //  static native int getMembers(Class<?> defc, String matchName, String matchSig,
1217   //          int matchFlags, Class<?> caller, int skip, MemberName[] results);
1218   {CC"getMembers",                CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)},
1219   {CC"objectFieldOffset",         CC"("MEM")J",                          FN_PTR(MHN_objectFieldOffset)},
1220   {CC"setCallSiteTargetNormal",   CC"("CS""MH")V",                       FN_PTR(MHN_setCallSiteTargetNormal)},
1221   {CC"setCallSiteTargetVolatile", CC"("CS""MH")V",                       FN_PTR(MHN_setCallSiteTargetVolatile)},
1222   {CC"staticFieldOffset",         CC"("MEM")J",                          FN_PTR(MHN_staticFieldOffset)},
1223   {CC"staticFieldBase",           CC"("MEM")"OBJ,                        FN_PTR(MHN_staticFieldBase)},
1224   {CC"getMemberVMInfo",           CC"("MEM")"OBJ,                        FN_PTR(MHN_getMemberVMInfo)}
1225 };
1226 
1227 // This one function is exported, used by NativeLookup.




1228 
















1229 JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
1230   if (!EnableInvokeDynamic) {
1231     warning("JSR 292 is disabled in this JVM.  Use -XX:+UnlockDiagnosticVMOptions -XX:+EnableInvokeDynamic to enable.");
1232     return;  // bind nothing
1233   }
1234 
1235   assert(!MethodHandles::enabled(), "must not be enabled");
1236   bool enable_MH = true;
1237 
1238   jclass MH_class = NULL;
1239   if (SystemDictionary::MethodHandle_klass() == NULL) {
1240     enable_MH = false;
1241   } else {
1242     oop mirror = Klass::cast(SystemDictionary::MethodHandle_klass())->java_mirror();
1243     MH_class = (jclass) JNIHandles::make_local(env, mirror);
1244   }
1245 
1246   int status;
1247 
1248   if (enable_MH) {
1249     ThreadToNativeFromVM ttnfv(thread);
1250 
1251     status = env->RegisterNatives(MHN_class, required_methods_JDK8, sizeof(required_methods_JDK8)/sizeof(JNINativeMethod));
1252     if (status != JNI_OK || env->ExceptionOccurred()) {
1253       warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
1254       enable_MH = false;
1255       env->ExceptionClear();
1256     }


1257   }

1258 
1259   if (TraceInvokeDynamic) {
1260     tty->print_cr("MethodHandle support loaded (using LambdaForms)");
1261   }
1262 
1263   if (enable_MH) {
1264     MethodHandles::generate_adapters();
1265     MethodHandles::set_enabled(true);
1266   }
1267 }
1268 JVM_END


1170     // Walk all nmethods depending on this call site.
1171     MutexLocker mu(Compile_lock, thread);
1172     Universe::flush_dependents_on(call_site, target);
1173     java_lang_invoke_CallSite::set_target(call_site(), target());
1174   }
1175 }
1176 JVM_END
1177 
1178 JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
1179   Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
1180   Handle target   (THREAD, JNIHandles::resolve(target_jh));
1181   {
1182     // Walk all nmethods depending on this call site.
1183     MutexLocker mu(Compile_lock, thread);
1184     Universe::flush_dependents_on(call_site, target);
1185     java_lang_invoke_CallSite::set_target_volatile(call_site(), target());
1186   }
1187 }
1188 JVM_END
1189 
1190 /**
1191  * Throws a java/lang/UnsupportedOperationException unconditionally.
1192  * This is required by the specification of MethodHandle.invoke if
1193  * invoked directly.
1194  */
1195 JVM_ENTRY(jobject, MH_invoke_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
1196   THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invoke cannot be invoked reflectively");
1197   return NULL;
1198 }
1199 JVM_END
1200 
1201 /**
1202  * Throws a java/lang/UnsupportedOperationException unconditionally.
1203  * This is required by the specification of MethodHandle.invokeExact if
1204  * invoked directly.
1205  */
1206 JVM_ENTRY(jobject, MH_invokeExact_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
1207   THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invokeExact cannot be invoked reflectively");
1208   return NULL;
1209 }
1210 JVM_END
1211 
1212 /// JVM_RegisterMethodHandleMethods
1213 
1214 #undef CS  // Solaris builds complain
1215 
1216 #define LANG "Ljava/lang/"
1217 #define JLINV "Ljava/lang/invoke/"
1218 
1219 #define OBJ   LANG"Object;"
1220 #define CLS   LANG"Class;"
1221 #define STRG  LANG"String;"
1222 #define CS    JLINV"CallSite;"
1223 #define MT    JLINV"MethodType;"
1224 #define MH    JLINV"MethodHandle;"
1225 #define MEM   JLINV"MemberName;"
1226 
1227 #define CC (char*)  /*cast a literal from (const char*)*/
1228 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
1229 
1230 // These are the native methods on java.lang.invoke.MethodHandleNatives.
1231 static JNINativeMethod MHN_methods[] = {
1232   {CC"init",                      CC"("MEM""OBJ")V",                     FN_PTR(MHN_init_Mem)},
1233   {CC"expand",                    CC"("MEM")V",                          FN_PTR(MHN_expand_Mem)},
1234   {CC"resolve",                   CC"("MEM""CLS")"MEM,                   FN_PTR(MHN_resolve_Mem)},
1235   {CC"getConstant",               CC"(I)I",                              FN_PTR(MHN_getConstant)},
1236   //  static native int getNamedCon(int which, Object[] name)
1237   {CC"getNamedCon",               CC"(I["OBJ")I",                        FN_PTR(MHN_getNamedCon)},
1238   //  static native int getMembers(Class<?> defc, String matchName, String matchSig,
1239   //          int matchFlags, Class<?> caller, int skip, MemberName[] results);
1240   {CC"getMembers",                CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)},
1241   {CC"objectFieldOffset",         CC"("MEM")J",                          FN_PTR(MHN_objectFieldOffset)},
1242   {CC"setCallSiteTargetNormal",   CC"("CS""MH")V",                       FN_PTR(MHN_setCallSiteTargetNormal)},
1243   {CC"setCallSiteTargetVolatile", CC"("CS""MH")V",                       FN_PTR(MHN_setCallSiteTargetVolatile)},
1244   {CC"staticFieldOffset",         CC"("MEM")J",                          FN_PTR(MHN_staticFieldOffset)},
1245   {CC"staticFieldBase",           CC"("MEM")"OBJ,                        FN_PTR(MHN_staticFieldBase)},
1246   {CC"getMemberVMInfo",           CC"("MEM")"OBJ,                        FN_PTR(MHN_getMemberVMInfo)}
1247 };
1248 
1249 static JNINativeMethod MH_methods[] = {
1250   // UnsupportedOperationException throwers
1251   {CC"invoke",                    CC"(["OBJ")"OBJ,                       FN_PTR(MH_invoke_UOE)},
1252   {CC"invokeExact",               CC"(["OBJ")"OBJ,                       FN_PTR(MH_invokeExact_UOE)}
1253 };
1254 
1255 /**
1256  * Helper method to register native methods.
1257  */
1258 static bool register_natives(JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods) {
1259   int status = env->RegisterNatives(clazz, methods, nMethods);
1260   if (status != JNI_OK || env->ExceptionOccurred()) {
1261     warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
1262     env->ExceptionClear();
1263     return false;
1264   }
1265   return true;
1266 }
1267 
1268 /**
1269  * This one function is exported, used by NativeLookup.
1270  */
1271 JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
1272   if (!EnableInvokeDynamic) {
1273     warning("JSR 292 is disabled in this JVM.  Use -XX:+UnlockDiagnosticVMOptions -XX:+EnableInvokeDynamic to enable.");
1274     return;  // bind nothing
1275   }
1276 
1277   assert(!MethodHandles::enabled(), "must not be enabled");
1278   bool enable_MH = true;
1279 
1280   jclass MH_class = NULL;
1281   if (SystemDictionary::MethodHandle_klass() == NULL) {
1282     enable_MH = false;
1283   } else {
1284     oop mirror = Klass::cast(SystemDictionary::MethodHandle_klass())->java_mirror();
1285     MH_class = (jclass) JNIHandles::make_local(env, mirror);
1286   }
1287 


1288   if (enable_MH) {
1289     ThreadToNativeFromVM ttnfv(thread);
1290 
1291     if (enable_MH) {
1292       enable_MH = register_natives(env, MHN_class, MHN_methods, sizeof(MHN_methods)/sizeof(JNINativeMethod));



1293     }
1294     if (enable_MH) {
1295       enable_MH = register_natives(env, MH_class, MH_methods, sizeof(MH_methods)/sizeof(JNINativeMethod));
1296     }
1297   }
1298 
1299   if (TraceInvokeDynamic) {
1300     tty->print_cr("MethodHandle support loaded (using LambdaForms)");
1301   }
1302 
1303   if (enable_MH) {
1304     MethodHandles::generate_adapters();
1305     MethodHandles::set_enabled(true);
1306   }
1307 }
1308 JVM_END