Print this page
rev 4509 : 7196277: JSR 292: Two jck/runtime tests crash on java.lang.invoke.MethodHandle.invokeExact
Reviewed-by: jrose, kvn

Split Split Close
Expand all
Collapse all
          --- old/src/share/vm/prims/methodHandles.cpp
          +++ new/src/share/vm/prims/methodHandles.cpp
↓ open down ↓ 1179 lines elided ↑ open up ↑
1180 1180    Handle target   (THREAD, JNIHandles::resolve(target_jh));
1181 1181    {
1182 1182      // Walk all nmethods depending on this call site.
1183 1183      MutexLocker mu(Compile_lock, thread);
1184 1184      Universe::flush_dependents_on(call_site, target);
1185 1185      java_lang_invoke_CallSite::set_target_volatile(call_site(), target());
1186 1186    }
1187 1187  }
1188 1188  JVM_END
1189 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 +
1190 1212  /// JVM_RegisterMethodHandleMethods
1191 1213  
1192 1214  #undef CS  // Solaris builds complain
1193 1215  
1194 1216  #define LANG "Ljava/lang/"
1195 1217  #define JLINV "Ljava/lang/invoke/"
1196 1218  
1197 1219  #define OBJ   LANG"Object;"
1198 1220  #define CLS   LANG"Class;"
1199 1221  #define STRG  LANG"String;"
1200 1222  #define CS    JLINV"CallSite;"
1201 1223  #define MT    JLINV"MethodType;"
1202 1224  #define MH    JLINV"MethodHandle;"
1203 1225  #define MEM   JLINV"MemberName;"
1204 1226  
1205 1227  #define CC (char*)  /*cast a literal from (const char*)*/
1206 1228  #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
1207 1229  
1208 1230  // These are the native methods on java.lang.invoke.MethodHandleNatives.
1209      -static JNINativeMethod required_methods_JDK8[] = {
     1231 +static JNINativeMethod MHN_methods[] = {
1210 1232    {CC"init",                      CC"("MEM""OBJ")V",                     FN_PTR(MHN_init_Mem)},
1211 1233    {CC"expand",                    CC"("MEM")V",                          FN_PTR(MHN_expand_Mem)},
1212 1234    {CC"resolve",                   CC"("MEM""CLS")"MEM,                   FN_PTR(MHN_resolve_Mem)},
1213 1235    {CC"getConstant",               CC"(I)I",                              FN_PTR(MHN_getConstant)},
1214 1236    //  static native int getNamedCon(int which, Object[] name)
1215 1237    {CC"getNamedCon",               CC"(I["OBJ")I",                        FN_PTR(MHN_getNamedCon)},
1216 1238    //  static native int getMembers(Class<?> defc, String matchName, String matchSig,
1217 1239    //          int matchFlags, Class<?> caller, int skip, MemberName[] results);
1218 1240    {CC"getMembers",                CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)},
1219 1241    {CC"objectFieldOffset",         CC"("MEM")J",                          FN_PTR(MHN_objectFieldOffset)},
1220 1242    {CC"setCallSiteTargetNormal",   CC"("CS""MH")V",                       FN_PTR(MHN_setCallSiteTargetNormal)},
1221 1243    {CC"setCallSiteTargetVolatile", CC"("CS""MH")V",                       FN_PTR(MHN_setCallSiteTargetVolatile)},
1222 1244    {CC"staticFieldOffset",         CC"("MEM")J",                          FN_PTR(MHN_staticFieldOffset)},
1223 1245    {CC"staticFieldBase",           CC"("MEM")"OBJ,                        FN_PTR(MHN_staticFieldBase)},
1224 1246    {CC"getMemberVMInfo",           CC"("MEM")"OBJ,                        FN_PTR(MHN_getMemberVMInfo)}
1225 1247  };
1226 1248  
1227      -// This one function is exported, used by NativeLookup.
     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 +};
1228 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 + */
1229 1271  JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
1230 1272    if (!EnableInvokeDynamic) {
1231 1273      warning("JSR 292 is disabled in this JVM.  Use -XX:+UnlockDiagnosticVMOptions -XX:+EnableInvokeDynamic to enable.");
1232 1274      return;  // bind nothing
1233 1275    }
1234 1276  
1235 1277    assert(!MethodHandles::enabled(), "must not be enabled");
1236 1278    bool enable_MH = true;
1237 1279  
1238 1280    jclass MH_class = NULL;
1239 1281    if (SystemDictionary::MethodHandle_klass() == NULL) {
1240 1282      enable_MH = false;
1241 1283    } else {
1242 1284      oop mirror = Klass::cast(SystemDictionary::MethodHandle_klass())->java_mirror();
1243 1285      MH_class = (jclass) JNIHandles::make_local(env, mirror);
1244 1286    }
1245 1287  
1246      -  int status;
1247      -
1248 1288    if (enable_MH) {
1249 1289      ThreadToNativeFromVM ttnfv(thread);
1250 1290  
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();
     1291 +    if (enable_MH) {
     1292 +      enable_MH = register_natives(env, MHN_class, MHN_methods, sizeof(MHN_methods)/sizeof(JNINativeMethod));
1256 1293      }
     1294 +    if (enable_MH) {
     1295 +      enable_MH = register_natives(env, MH_class, MH_methods, sizeof(MH_methods)/sizeof(JNINativeMethod));
     1296 +    }
1257 1297    }
1258 1298  
1259 1299    if (TraceInvokeDynamic) {
1260 1300      tty->print_cr("MethodHandle support loaded (using LambdaForms)");
1261 1301    }
1262 1302  
1263 1303    if (enable_MH) {
1264 1304      MethodHandles::generate_adapters();
1265 1305      MethodHandles::set_enabled(true);
1266 1306    }
1267 1307  }
1268 1308  JVM_END
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX