< prev index next >

src/share/vm/prims/methodHandles.cpp

Print this page




 923       if (rskip > 0) {
 924         --rskip;
 925       } else if (rfill < rlimit) {
 926         Handle result(thread, results->obj_at(rfill++));
 927         if (!java_lang_invoke_MemberName::is_instance(result()))
 928           return -99;  // caller bug!
 929         CallInfo info(m);
 930         oop saved = MethodHandles::init_method_MemberName(result, info);
 931         if (saved != result())
 932           results->obj_at_put(rfill-1, saved);  // show saved instance to user
 933       } else if (++overflow >= overflow_limit) {
 934         match_flags = 0; break; // got tired of looking at overflow
 935       }
 936     }
 937   }
 938 
 939   // return number of elements we at leasted wanted to initialize
 940   return rfill + overflow;
 941 }
 942 
 943 // Get context class for a CallSite instance: either extract existing context or use default one.
 944 InstanceKlass* MethodHandles::get_call_site_context(oop call_site) {
 945   // In order to extract a context the following traversal is performed:
 946   //   CallSite.context => Cleaner.referent => Class._klass => Klass
 947   assert(java_lang_invoke_CallSite::is_instance(call_site), "");
 948   oop context_oop = java_lang_invoke_CallSite::context_volatile(call_site);
 949   if (oopDesc::is_null(context_oop)) {
 950     return NULL; // The context hasn't been initialized yet.
 951   }
 952   oop context_class_oop = java_lang_ref_Reference::referent(context_oop);
 953   if (oopDesc::is_null(context_class_oop)) {
 954     // The context reference was cleared by GC, so current dependency context
 955     // isn't usable anymore. Context should be fetched from CallSite again.
 956     return NULL;



































 957   }
 958   return InstanceKlass::cast(java_lang_Class::as_Klass(context_class_oop));
 959 }
 960 
 961 //------------------------------------------------------------------------------
 962 // MemberNameTable
 963 //
 964 
 965 MemberNameTable::MemberNameTable(int methods_cnt)
 966                   : GrowableArray<jweak>(methods_cnt, true) {
 967   assert_locked_or_safepoint(MemberNameTable_lock);
 968 }
 969 
 970 MemberNameTable::~MemberNameTable() {
 971   assert_locked_or_safepoint(MemberNameTable_lock);
 972   int len = this->length();
 973 
 974   for (int idx = 0; idx < len; idx++) {
 975     jweak ref = this->at(idx);
 976     JNIHandles::destroy_weak_global(ref);
 977   }
 978 }


1257   }
1258 
1259   if (name != NULL && sig != NULL && results.not_null()) {
1260     // try a direct resolve
1261     // %%% TO DO
1262   }
1263 
1264   int res = MethodHandles::find_MemberNames(k, name, sig, mflags,
1265                                             caller, skip, results);
1266   // TO DO: expand at least some of the MemberNames, to avoid massive callbacks
1267   return res;
1268 }
1269 JVM_END
1270 
1271 JVM_ENTRY(void, MHN_setCallSiteTargetNormal(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
1272   Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
1273   Handle target   (THREAD, JNIHandles::resolve_non_null(target_jh));
1274   {
1275     // Walk all nmethods depending on this call site.
1276     MutexLocker mu(Compile_lock, thread);
1277     CodeCache::flush_dependents_on(call_site, target);
1278     java_lang_invoke_CallSite::set_target(call_site(), target());
1279   }
1280 }
1281 JVM_END
1282 
1283 JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
1284   Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
1285   Handle target   (THREAD, JNIHandles::resolve_non_null(target_jh));
1286   {
1287     // Walk all nmethods depending on this call site.
1288     MutexLocker mu(Compile_lock, thread);
1289     CodeCache::flush_dependents_on(call_site, target);
1290     java_lang_invoke_CallSite::set_target_volatile(call_site(), target());
1291   }
1292 }
1293 JVM_END
1294 
1295 JVM_ENTRY(void, MHN_invalidateDependentNMethods(JNIEnv* env, jobject igcls, jobject call_site_jh)) {
1296   Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
1297   {
1298     // Walk all nmethods depending on this call site.
1299     MutexLocker mu1(Compile_lock, thread);
1300 
1301     CallSiteDepChange changes(call_site(), Handle());
1302 
1303     InstanceKlass* ctxk = MethodHandles::get_call_site_context(call_site());
1304     if (ctxk == NULL) {
1305       return; // No dependencies to invalidate yet.
1306     }
1307     int marked = 0;
1308     {
1309       MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
1310       marked = ctxk->mark_dependent_nmethods(changes);











1311     }
1312     java_lang_invoke_CallSite::set_context_volatile(call_site(), NULL); // Reset call site to initial state
1313     if (marked > 0) {
1314       // At least one nmethod has been marked for deoptimization
1315       VM_Deoptimize op;
1316       VMThread::execute(&op);
1317     }
1318   }
1319 }
1320 JVM_END
1321 
1322 /**
1323  * Throws a java/lang/UnsupportedOperationException unconditionally.
1324  * This is required by the specification of MethodHandle.invoke if
1325  * invoked directly.
1326  */
1327 JVM_ENTRY(jobject, MH_invoke_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
1328   THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invoke cannot be invoked reflectively");
1329   return NULL;
1330 }
1331 JVM_END
1332 


1335  * This is required by the specification of MethodHandle.invokeExact if
1336  * invoked directly.
1337  */
1338 JVM_ENTRY(jobject, MH_invokeExact_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
1339   THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invokeExact cannot be invoked reflectively");
1340   return NULL;
1341 }
1342 JVM_END
1343 
1344 /// JVM_RegisterMethodHandleMethods
1345 
1346 #undef CS  // Solaris builds complain
1347 
1348 #define LANG "Ljava/lang/"
1349 #define JLINV "Ljava/lang/invoke/"
1350 
1351 #define OBJ   LANG"Object;"
1352 #define CLS   LANG"Class;"
1353 #define STRG  LANG"String;"
1354 #define CS    JLINV"CallSite;"

1355 #define MT    JLINV"MethodType;"
1356 #define MH    JLINV"MethodHandle;"
1357 #define MEM   JLINV"MemberName;"
1358 
1359 #define CC (char*)  /*cast a literal from (const char*)*/
1360 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
1361 
1362 // These are the native methods on java.lang.invoke.MethodHandleNatives.
1363 static JNINativeMethod MHN_methods[] = {
1364   {CC"init",                      CC"("MEM""OBJ")V",                     FN_PTR(MHN_init_Mem)},
1365   {CC"expand",                    CC"("MEM")V",                          FN_PTR(MHN_expand_Mem)},
1366   {CC"resolve",                   CC"("MEM""CLS")"MEM,                   FN_PTR(MHN_resolve_Mem)},
1367   //  static native int getNamedCon(int which, Object[] name)
1368   {CC"getNamedCon",               CC"(I["OBJ")I",                        FN_PTR(MHN_getNamedCon)},
1369   //  static native int getMembers(Class<?> defc, String matchName, String matchSig,
1370   //          int matchFlags, Class<?> caller, int skip, MemberName[] results);
1371   {CC"getMembers",                CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)},
1372   {CC"objectFieldOffset",         CC"("MEM")J",                          FN_PTR(MHN_objectFieldOffset)},
1373   {CC"setCallSiteTargetNormal",   CC"("CS""MH")V",                       FN_PTR(MHN_setCallSiteTargetNormal)},
1374   {CC"setCallSiteTargetVolatile", CC"("CS""MH")V",                       FN_PTR(MHN_setCallSiteTargetVolatile)},
1375   {CC"invalidateDependentNMethods", CC"("CS")V",                         FN_PTR(MHN_invalidateDependentNMethods)},
1376   {CC"staticFieldOffset",         CC"("MEM")J",                          FN_PTR(MHN_staticFieldOffset)},
1377   {CC"staticFieldBase",           CC"("MEM")"OBJ,                        FN_PTR(MHN_staticFieldBase)},
1378   {CC"getMemberVMInfo",           CC"("MEM")"OBJ,                        FN_PTR(MHN_getMemberVMInfo)}
1379 };
1380 
1381 static JNINativeMethod MH_methods[] = {
1382   // UnsupportedOperationException throwers
1383   {CC"invoke",                    CC"(["OBJ")"OBJ,                       FN_PTR(MH_invoke_UOE)},
1384   {CC"invokeExact",               CC"(["OBJ")"OBJ,                       FN_PTR(MH_invokeExact_UOE)}
1385 };
1386 
1387 /**
1388  * Helper method to register native methods.
1389  */
1390 static bool register_natives(JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods) {
1391   int status = env->RegisterNatives(clazz, methods, nMethods);
1392   if (status != JNI_OK || env->ExceptionOccurred()) {
1393     warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
1394     env->ExceptionClear();
1395     return false;




 923       if (rskip > 0) {
 924         --rskip;
 925       } else if (rfill < rlimit) {
 926         Handle result(thread, results->obj_at(rfill++));
 927         if (!java_lang_invoke_MemberName::is_instance(result()))
 928           return -99;  // caller bug!
 929         CallInfo info(m);
 930         oop saved = MethodHandles::init_method_MemberName(result, info);
 931         if (saved != result())
 932           results->obj_at_put(rfill-1, saved);  // show saved instance to user
 933       } else if (++overflow >= overflow_limit) {
 934         match_flags = 0; break; // got tired of looking at overflow
 935       }
 936     }
 937   }
 938 
 939   // return number of elements we at leasted wanted to initialize
 940   return rfill + overflow;
 941 }
 942 
 943 void MethodHandles::add_dependent_nmethod(oop call_site, nmethod* nm) {
 944   assert_locked_or_safepoint(CodeCache_lock);
 945 
 946   oop context = java_lang_invoke_CallSite::context(call_site);
 947   nmethodBucket* deps = java_lang_invoke_CallSite_Context::dependencies(context);
 948 
 949   nmethodBucket* new_deps = nmethodBucket::add_dependent_nmethod(deps, nm);
 950   if (deps != new_deps) {
 951     java_lang_invoke_CallSite_Context::set_dependencies(context, new_deps);
 952   }
 953 }
 954 
 955 void MethodHandles::remove_dependent_nmethod(oop call_site, nmethod* nm) {
 956   assert_locked_or_safepoint(CodeCache_lock);
 957 
 958   oop context = java_lang_invoke_CallSite::context(call_site);
 959   nmethodBucket* deps = java_lang_invoke_CallSite_Context::dependencies(context);
 960 
 961   if (nmethodBucket::remove_dependent_nmethod(deps, nm)) {
 962     nmethodBucket* new_deps = nmethodBucket::clean_dependent_nmethods(deps);
 963     if (deps != new_deps) {
 964       java_lang_invoke_CallSite_Context::set_dependencies(context, new_deps);
 965     }
 966   }
 967 }
 968 
 969 void MethodHandles::flush_dependent_nmethods(Handle call_site, Handle target) {
 970   assert_lock_strong(Compile_lock);
 971 
 972   int marked = 0;
 973   CallSiteDepChange changes(call_site(), target());
 974   {
 975     MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
 976 
 977     oop context = java_lang_invoke_CallSite::context(call_site());
 978     nmethodBucket* deps = java_lang_invoke_CallSite_Context::dependencies(context);
 979 
 980     marked = nmethodBucket::mark_dependent_nmethods(deps, changes);
 981     if (marked > 0) {
 982       nmethodBucket* new_deps = nmethodBucket::clean_dependent_nmethods(deps);
 983       if (deps != new_deps) {
 984         java_lang_invoke_CallSite_Context::set_dependencies(context, new_deps);
 985       }
 986     }
 987   }
 988   if (marked > 0) {
 989     // At least one nmethod has been marked for deoptimization
 990     VM_Deoptimize op;
 991     VMThread::execute(&op);
 992   }

 993 }
 994 
 995 //------------------------------------------------------------------------------
 996 // MemberNameTable
 997 //
 998 
 999 MemberNameTable::MemberNameTable(int methods_cnt)
1000                   : GrowableArray<jweak>(methods_cnt, true) {
1001   assert_locked_or_safepoint(MemberNameTable_lock);
1002 }
1003 
1004 MemberNameTable::~MemberNameTable() {
1005   assert_locked_or_safepoint(MemberNameTable_lock);
1006   int len = this->length();
1007 
1008   for (int idx = 0; idx < len; idx++) {
1009     jweak ref = this->at(idx);
1010     JNIHandles::destroy_weak_global(ref);
1011   }
1012 }


1291   }
1292 
1293   if (name != NULL && sig != NULL && results.not_null()) {
1294     // try a direct resolve
1295     // %%% TO DO
1296   }
1297 
1298   int res = MethodHandles::find_MemberNames(k, name, sig, mflags,
1299                                             caller, skip, results);
1300   // TO DO: expand at least some of the MemberNames, to avoid massive callbacks
1301   return res;
1302 }
1303 JVM_END
1304 
1305 JVM_ENTRY(void, MHN_setCallSiteTargetNormal(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
1306   Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
1307   Handle target   (THREAD, JNIHandles::resolve_non_null(target_jh));
1308   {
1309     // Walk all nmethods depending on this call site.
1310     MutexLocker mu(Compile_lock, thread);
1311     MethodHandles::flush_dependent_nmethods(call_site, target);
1312     java_lang_invoke_CallSite::set_target(call_site(), target());
1313   }
1314 }
1315 JVM_END
1316 
1317 JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
1318   Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
1319   Handle target   (THREAD, JNIHandles::resolve_non_null(target_jh));
1320   {
1321     // Walk all nmethods depending on this call site.
1322     MutexLocker mu(Compile_lock, thread);
1323     MethodHandles::flush_dependent_nmethods(call_site, target);
1324     java_lang_invoke_CallSite::set_target_volatile(call_site(), target());
1325   }
1326 }
1327 JVM_END
1328 
1329 JVM_ENTRY(void, MHN_clearCallSiteContext(JNIEnv* env, jobject igcls, jobject context_jh)) {
1330   Handle context(THREAD, JNIHandles::resolve_non_null(context_jh));
1331   {
1332     // Walk all nmethods depending on this call site.
1333     MutexLocker mu1(Compile_lock, thread);
1334 






1335     int marked = 0;
1336     {
1337       MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
1338       nmethodBucket* b = java_lang_invoke_CallSite_Context::dependencies(context());
1339       while(b != NULL) {
1340         nmethod* nm = b->get_nmethod();
1341         if (b->count() > 0 && nm->is_alive() && !nm->is_marked_for_deoptimization()) {
1342           nm->mark_for_deoptimization();
1343           marked++;
1344         }
1345         nmethodBucket* next = b->next();
1346         delete b;
1347         b = next;
1348       }
1349       java_lang_invoke_CallSite_Context::set_dependencies(context(), NULL); // reset context
1350     }

1351     if (marked > 0) {
1352       // At least one nmethod has been marked for deoptimization
1353       VM_Deoptimize op;
1354       VMThread::execute(&op);
1355     }
1356   }
1357 }
1358 JVM_END
1359 
1360 /**
1361  * Throws a java/lang/UnsupportedOperationException unconditionally.
1362  * This is required by the specification of MethodHandle.invoke if
1363  * invoked directly.
1364  */
1365 JVM_ENTRY(jobject, MH_invoke_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
1366   THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invoke cannot be invoked reflectively");
1367   return NULL;
1368 }
1369 JVM_END
1370 


1373  * This is required by the specification of MethodHandle.invokeExact if
1374  * invoked directly.
1375  */
1376 JVM_ENTRY(jobject, MH_invokeExact_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
1377   THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invokeExact cannot be invoked reflectively");
1378   return NULL;
1379 }
1380 JVM_END
1381 
1382 /// JVM_RegisterMethodHandleMethods
1383 
1384 #undef CS  // Solaris builds complain
1385 
1386 #define LANG "Ljava/lang/"
1387 #define JLINV "Ljava/lang/invoke/"
1388 
1389 #define OBJ   LANG"Object;"
1390 #define CLS   LANG"Class;"
1391 #define STRG  LANG"String;"
1392 #define CS    JLINV"CallSite;"
1393 #define CTX   JLINV"CallSite$Context;"
1394 #define MT    JLINV"MethodType;"
1395 #define MH    JLINV"MethodHandle;"
1396 #define MEM   JLINV"MemberName;"
1397 
1398 #define CC (char*)  /*cast a literal from (const char*)*/
1399 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
1400 
1401 // These are the native methods on java.lang.invoke.MethodHandleNatives.
1402 static JNINativeMethod MHN_methods[] = {
1403   {CC"init",                      CC"("MEM""OBJ")V",                     FN_PTR(MHN_init_Mem)},
1404   {CC"expand",                    CC"("MEM")V",                          FN_PTR(MHN_expand_Mem)},
1405   {CC"resolve",                   CC"("MEM""CLS")"MEM,                   FN_PTR(MHN_resolve_Mem)},
1406   //  static native int getNamedCon(int which, Object[] name)
1407   {CC"getNamedCon",               CC"(I["OBJ")I",                        FN_PTR(MHN_getNamedCon)},
1408   //  static native int getMembers(Class<?> defc, String matchName, String matchSig,
1409   //          int matchFlags, Class<?> caller, int skip, MemberName[] results);
1410   {CC"getMembers",                CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)},
1411   {CC"objectFieldOffset",         CC"("MEM")J",                          FN_PTR(MHN_objectFieldOffset)},
1412   {CC"setCallSiteTargetNormal",   CC"("CS""MH")V",                       FN_PTR(MHN_setCallSiteTargetNormal)},
1413   {CC"setCallSiteTargetVolatile", CC"("CS""MH")V",                       FN_PTR(MHN_setCallSiteTargetVolatile)},
1414   {CC"clearCallSiteContext",      CC"("CTX")V",                          FN_PTR(MHN_clearCallSiteContext)},
1415   {CC"staticFieldOffset",         CC"("MEM")J",                          FN_PTR(MHN_staticFieldOffset)},
1416   {CC"staticFieldBase",           CC"("MEM")"OBJ,                        FN_PTR(MHN_staticFieldBase)},
1417   {CC"getMemberVMInfo",           CC"("MEM")"OBJ,                        FN_PTR(MHN_getMemberVMInfo)}
1418 };
1419 
1420 static JNINativeMethod MH_methods[] = {
1421   // UnsupportedOperationException throwers
1422   {CC"invoke",                    CC"(["OBJ")"OBJ,                       FN_PTR(MH_invoke_UOE)},
1423   {CC"invokeExact",               CC"(["OBJ")"OBJ,                       FN_PTR(MH_invokeExact_UOE)}
1424 };
1425 
1426 /**
1427  * Helper method to register native methods.
1428  */
1429 static bool register_natives(JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods) {
1430   int status = env->RegisterNatives(clazz, methods, nMethods);
1431   if (status != JNI_OK || env->ExceptionOccurred()) {
1432     warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
1433     env->ExceptionClear();
1434     return false;


< prev index next >