< prev index next >

src/hotspot/share/prims/methodHandles.cpp

Print this page
rev 52749 : Bootstrap method consolidation
* clean up and simplify JDK support code for BSM invocation
* simplify JVM bootstrap handshake: use BootstrapCallInfo only
* remove unused JVM paths and data fields
* move bootstrap argument processing from MethodHandleNatives to ConstantPool
* remove ConstantGroup; merge argument access into BootstrapCallInfo
* adjust BSM argument access: remove copyArguments, add argumentRef API
* add metadata-free BSM modes, including symbolic arguments from CP


 135   } else if (ref_kind_is_method(ref_kind)) {
 136     flags |= IS_METHOD;
 137   } else if (ref_kind == JVM_REF_newInvokeSpecial) {
 138     flags |= IS_CONSTRUCTOR;
 139   }
 140   return flags;
 141 }
 142 
 143 Handle MethodHandles::resolve_MemberName_type(Handle mname, Klass* caller, TRAPS) {
 144   Handle empty;
 145   Handle type(THREAD, java_lang_invoke_MemberName::type(mname()));
 146   if (!java_lang_String::is_instance_inlined(type())) {
 147     return type; // already resolved
 148   }
 149   Symbol* signature = java_lang_String::as_symbol_or_null(type());
 150   if (signature == NULL) {
 151     return empty;  // no such signature exists in the VM
 152   }
 153   Handle resolved;
 154   int flags = java_lang_invoke_MemberName::flags(mname());

 155   switch (flags & ALL_KINDS) {
 156     case IS_METHOD:
 157     case IS_CONSTRUCTOR:
 158       resolved = SystemDictionary::find_method_handle_type(signature, caller, CHECK_(empty));
 159       break;
 160     case IS_FIELD:
 161       resolved = SystemDictionary::find_field_handle_type(signature, caller, CHECK_(empty));
 162       break;
 163     default:
 164       THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format", empty);
 165   }
 166   if (resolved.is_null()) {
 167     THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad MemberName type", empty);
 168   }
 169   return resolved;
 170 }
 171 
 172 oop MethodHandles::init_MemberName(Handle mname, Handle target, TRAPS) {
 173   // This method is used from java.lang.invoke.MemberName constructors.
 174   // It fills in the new MemberName from a java.lang.reflect.Member.
 175   Thread* thread = Thread::current();
 176   oop target_oop = target();
 177   Klass* target_klass = target_oop->klass();
 178   if (target_klass == SystemDictionary::reflect_Field_klass()) {
 179     oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder()
 180     int slot  = java_lang_reflect_Field::slot(target_oop);  // fd.index()
 181     Klass* k = java_lang_Class::as_Klass(clazz);


1126       else
1127         suffix = "/private";
1128     }
1129     jio_snprintf(qname, len, "MethodHandle::interpreter_entry::%s%s", name, suffix);
1130     trace_method_handle(_masm, qname);
1131     // Note:  Don't free the allocated char array because it's used
1132     // during runtime.
1133   }
1134 }
1135 
1136 //
1137 // Here are the native methods in java.lang.invoke.MethodHandleNatives
1138 // They are the private interface between this JVM and the HotSpot-specific
1139 // Java code that implements JSR 292 method handles.
1140 //
1141 // Note:  We use a JVM_ENTRY macro to define each of these, for this is the way
1142 // that intrinsic (non-JNI) native methods are defined in HotSpot.
1143 //
1144 
1145 #ifndef PRODUCT











1146 #define EACH_NAMED_CON(template, requirement) \
1147     template(java_lang_invoke_MemberName,MN_IS_METHOD) \
1148     template(java_lang_invoke_MemberName,MN_IS_CONSTRUCTOR) \
1149     template(java_lang_invoke_MemberName,MN_IS_FIELD) \
1150     template(java_lang_invoke_MemberName,MN_IS_TYPE) \
1151     template(java_lang_invoke_MemberName,MN_CALLER_SENSITIVE) \
1152     template(java_lang_invoke_MemberName,MN_SEARCH_SUPERCLASSES) \
1153     template(java_lang_invoke_MemberName,MN_SEARCH_INTERFACES) \
1154     template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_SHIFT) \
1155     template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_MASK) \














1156     /*end*/
1157 

















1158 #define IGNORE_REQ(req_expr) /* req_expr */
1159 #define ONE_PLUS(scope,value) 1+
1160 static const int con_value_count = EACH_NAMED_CON(ONE_PLUS, IGNORE_REQ) 0;
1161 #define VALUE_COMMA(scope,value) scope::value,
1162 static const int con_values[con_value_count+1] = { EACH_NAMED_CON(VALUE_COMMA, IGNORE_REQ) 0 };
1163 #define STRING_NULL(scope,value) #value "\0"
1164 static const char con_names[] = { EACH_NAMED_CON(STRING_NULL, IGNORE_REQ) };
1165 
1166 static bool advertise_con_value(int which) {
1167   if (which < 0)  return false;
1168   bool ok = true;
1169   int count = 0;
1170 #define INC_COUNT(scope,value) \
1171   ++count;
1172 #define CHECK_REQ(req_expr) \
1173   if (which < count)  return ok; \
1174   ok = (req_expr);
1175   EACH_NAMED_CON(INC_COUNT, CHECK_REQ);
1176 #undef INC_COUNT
1177 #undef CHECK_REQ
1178   assert(count == con_value_count, "");
1179   if (which < count)  return ok;
1180   return false;
1181 }
1182 
1183 #undef ONE_PLUS
1184 #undef VALUE_COMMA
1185 #undef STRING_NULL
1186 #undef EACH_NAMED_CON
1187 #endif // PRODUCT

1188 
1189 JVM_ENTRY(jint, MHN_getNamedCon(JNIEnv *env, jobject igcls, jint which, jobjectArray box_jh)) {
1190 #ifndef PRODUCT
1191   if (advertise_con_value(which)) {
1192     assert(which >= 0 && which < con_value_count, "");
1193     int con = con_values[which];
1194     objArrayHandle box(THREAD, (objArrayOop) JNIHandles::resolve(box_jh));
1195     if (box.not_null() && box->klass() == Universe::objectArrayKlassObj() && box->length() > 0) {
1196       const char* str = &con_names[0];
1197       for (int i = 0; i < which; i++)
1198         str += strlen(str) + 1;   // skip name and null
1199       oop name = java_lang_String::create_oop_from_str(str, CHECK_0);  // possible safepoint
1200       box->obj_at_put(0, name);
1201     }
1202     return con;
1203   }
1204 #endif
1205   return 0;
1206 }
1207 JVM_END
1208 
1209 // void init(MemberName self, AccessibleObject ref)
1210 JVM_ENTRY(void, MHN_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) {


1390     // Walk all nmethods depending on this call site.
1391     MutexLocker mu(Compile_lock, thread);
1392     MethodHandles::flush_dependent_nmethods(call_site, target);
1393     java_lang_invoke_CallSite::set_target(call_site(), target());
1394   }
1395 }
1396 JVM_END
1397 
1398 JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
1399   Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
1400   Handle target   (THREAD, JNIHandles::resolve_non_null(target_jh));
1401   {
1402     // Walk all nmethods depending on this call site.
1403     MutexLocker mu(Compile_lock, thread);
1404     MethodHandles::flush_dependent_nmethods(call_site, target);
1405     java_lang_invoke_CallSite::set_target_volatile(call_site(), target());
1406   }
1407 }
1408 JVM_END
1409 
1410 JVM_ENTRY(void, MHN_copyOutBootstrapArguments(JNIEnv* env, jobject igcls,
1411                                               jobject caller_jh, jintArray index_info_jh,
1412                                               jint start, jint end,
1413                                               jobjectArray buf_jh, jint pos,
1414                                               jboolean resolve, jobject ifna_jh)) {
1415   Klass* caller_k = java_lang_Class::as_Klass(JNIHandles::resolve(caller_jh));
1416   if (caller_k == NULL || !caller_k->is_instance_klass()) {
1417       THROW_MSG(vmSymbols::java_lang_InternalError(), "bad caller");
1418   }
1419   InstanceKlass* caller = InstanceKlass::cast(caller_k);
1420   typeArrayOop index_info_oop = (typeArrayOop) JNIHandles::resolve(index_info_jh);
1421   if (index_info_oop == NULL ||
1422       index_info_oop->klass() != Universe::intArrayKlassObj() ||
1423       typeArrayOop(index_info_oop)->length() < 2) {
1424       THROW_MSG(vmSymbols::java_lang_InternalError(), "bad index info (0)");
1425   }
1426   typeArrayHandle index_info(THREAD, index_info_oop);
1427   int bss_index_in_pool = index_info->int_at(1);
1428   // While we are here, take a quick look at the index info:
1429   if (bss_index_in_pool <= 0 ||
1430       bss_index_in_pool >= caller->constants()->length() ||
1431       index_info->int_at(0)
1432       != caller->constants()->invoke_dynamic_argument_count_at(bss_index_in_pool)) {
1433       THROW_MSG(vmSymbols::java_lang_InternalError(), "bad index info (1)");
1434   }
1435   objArrayHandle buf(THREAD, (objArrayOop) JNIHandles::resolve(buf_jh));
1436   if (start < 0) {
1437     for (int pseudo_index = -4; pseudo_index < 0; pseudo_index++) {
1438       if (start == pseudo_index) {
1439         if (start >= end || 0 > pos || pos >= buf->length())  break;
1440         oop pseudo_arg = NULL;
1441         switch (pseudo_index) {
1442         case -4:  // bootstrap method
1443           {
1444             int bsm_index = caller->constants()->invoke_dynamic_bootstrap_method_ref_index_at(bss_index_in_pool);
1445             pseudo_arg = caller->constants()->resolve_possibly_cached_constant_at(bsm_index, CHECK);
1446             break;
1447           }
1448         case -3:  // name
1449           {
1450             Symbol* name = caller->constants()->name_ref_at(bss_index_in_pool);
1451             Handle str = java_lang_String::create_from_symbol(name, CHECK);
1452             pseudo_arg = str();
1453             break;
1454           }
1455         case -2:  // type
1456           {
1457             Symbol* type = caller->constants()->signature_ref_at(bss_index_in_pool);
1458             Handle th;
1459             if (type->byte_at(0) == '(') {
1460               th = SystemDictionary::find_method_handle_type(type, caller, CHECK);
1461             } else {
1462               th = SystemDictionary::find_java_mirror_for_type(type, caller, SignatureStream::NCDFError, CHECK);
1463             }
1464             pseudo_arg = th();
1465             break;
1466           }
1467         case -1:  // argument count
1468           {
1469             int argc = caller->constants()->invoke_dynamic_argument_count_at(bss_index_in_pool);
1470             jvalue argc_value; argc_value.i = (jint)argc;
1471             pseudo_arg = java_lang_boxing_object::create(T_INT, &argc_value, CHECK);
1472             break;
1473           }
1474         }
1475 
1476         // Store the pseudo-argument, and advance the pointers.
1477         buf->obj_at_put(pos++, pseudo_arg);
1478         ++start;
1479       }
1480     }
1481     // When we are done with this there may be regular arguments to process too.
1482   }
1483   Handle ifna(THREAD, JNIHandles::resolve(ifna_jh));
1484   caller->constants()->
1485     copy_bootstrap_arguments_at(bss_index_in_pool,
1486                                 start, end, buf, pos,
1487                                 (resolve == JNI_TRUE), ifna, CHECK);
1488 }
1489 JVM_END
1490 
1491 // It is called by a Cleaner object which ensures that dropped CallSites properly
1492 // deallocate their dependency information.
1493 JVM_ENTRY(void, MHN_clearCallSiteContext(JNIEnv* env, jobject igcls, jobject context_jh)) {
1494   Handle context(THREAD, JNIHandles::resolve_non_null(context_jh));
1495   {
1496     // Walk all nmethods depending on this call site.
1497     MutexLocker mu1(Compile_lock, thread);
1498 
1499     int marked = 0;
1500     {
1501       NoSafepointVerifier nsv;
1502       MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
1503       assert(safe_to_expunge(), "removal is not safe");
1504       DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context());
1505       marked = deps.remove_all_dependents();
1506     }
1507     if (marked > 0) {
1508       // At least one nmethod has been marked for deoptimization
1509       VM_Deoptimize op;
1510       VMThread::execute(&op);


1550 #define MH    JLINV "MethodHandle;"
1551 #define MEM   JLINV "MemberName;"
1552 #define CTX   JLINV "MethodHandleNatives$CallSiteContext;"
1553 
1554 #define CC (char*)  /*cast a literal from (const char*)*/
1555 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
1556 
1557 // These are the native methods on java.lang.invoke.MethodHandleNatives.
1558 static JNINativeMethod MHN_methods[] = {
1559   {CC "init",                      CC "(" MEM "" OBJ ")V",                   FN_PTR(MHN_init_Mem)},
1560   {CC "expand",                    CC "(" MEM ")V",                          FN_PTR(MHN_expand_Mem)},
1561   {CC "resolve",                   CC "(" MEM "" CLS "Z)" MEM,               FN_PTR(MHN_resolve_Mem)},
1562   //  static native int getNamedCon(int which, Object[] name)
1563   {CC "getNamedCon",               CC "(I[" OBJ ")I",                        FN_PTR(MHN_getNamedCon)},
1564   //  static native int getMembers(Class<?> defc, String matchName, String matchSig,
1565   //          int matchFlags, Class<?> caller, int skip, MemberName[] results);
1566   {CC "getMembers",                CC "(" CLS "" STRG "" STRG "I" CLS "I[" MEM ")I", FN_PTR(MHN_getMembers)},
1567   {CC "objectFieldOffset",         CC "(" MEM ")J",                          FN_PTR(MHN_objectFieldOffset)},
1568   {CC "setCallSiteTargetNormal",   CC "(" CS "" MH ")V",                     FN_PTR(MHN_setCallSiteTargetNormal)},
1569   {CC "setCallSiteTargetVolatile", CC "(" CS "" MH ")V",                     FN_PTR(MHN_setCallSiteTargetVolatile)},
1570   {CC "copyOutBootstrapArguments", CC "(" CLS "[III[" OBJ "IZ" OBJ ")V",     FN_PTR(MHN_copyOutBootstrapArguments)},
1571   {CC "clearCallSiteContext",      CC "(" CTX ")V",                          FN_PTR(MHN_clearCallSiteContext)},
1572   {CC "staticFieldOffset",         CC "(" MEM ")J",                          FN_PTR(MHN_staticFieldOffset)},
1573   {CC "staticFieldBase",           CC "(" MEM ")" OBJ,                        FN_PTR(MHN_staticFieldBase)},
1574   {CC "getMemberVMInfo",           CC "(" MEM ")" OBJ,                        FN_PTR(MHN_getMemberVMInfo)}
1575 };
1576 
1577 static JNINativeMethod MH_methods[] = {
1578   // UnsupportedOperationException throwers
1579   {CC "invoke",                    CC "([" OBJ ")" OBJ,                       FN_PTR(MH_invoke_UOE)},
1580   {CC "invokeExact",               CC "([" OBJ ")" OBJ,                       FN_PTR(MH_invokeExact_UOE)}
1581 };
1582 
1583 /**
1584  * This one function is exported, used by NativeLookup.
1585  */
1586 JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
1587   assert(!MethodHandles::enabled(), "must not be enabled");
1588   assert(SystemDictionary::MethodHandle_klass() != NULL, "should be present");
1589 
1590   oop mirror = SystemDictionary::MethodHandle_klass()->java_mirror();




 135   } else if (ref_kind_is_method(ref_kind)) {
 136     flags |= IS_METHOD;
 137   } else if (ref_kind == JVM_REF_newInvokeSpecial) {
 138     flags |= IS_CONSTRUCTOR;
 139   }
 140   return flags;
 141 }
 142 
 143 Handle MethodHandles::resolve_MemberName_type(Handle mname, Klass* caller, TRAPS) {
 144   Handle empty;
 145   Handle type(THREAD, java_lang_invoke_MemberName::type(mname()));
 146   if (!java_lang_String::is_instance_inlined(type())) {
 147     return type; // already resolved
 148   }
 149   Symbol* signature = java_lang_String::as_symbol_or_null(type());
 150   if (signature == NULL) {
 151     return empty;  // no such signature exists in the VM
 152   }
 153   Handle resolved;
 154   int flags = java_lang_invoke_MemberName::flags(mname());
 155   bool check_access = false;  // is this right?
 156   switch (flags & ALL_KINDS) {
 157     case IS_METHOD:
 158     case IS_CONSTRUCTOR:
 159       resolved = SystemDictionary::find_method_handle_type(signature, caller, CHECK_(empty));
 160       break;
 161     case IS_FIELD:
 162       resolved = SystemDictionary::find_java_mirror_for_type(signature, caller, SignatureStream::NCDFError, check_access, CHECK_(empty));
 163       break;
 164     default:
 165       THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format", empty);
 166   }
 167   if (resolved.is_null()) {
 168     THROW_MSG_(vmSymbols::java_lang_InternalError(), "bad MemberName type", empty);
 169   }
 170   return resolved;
 171 }
 172 
 173 oop MethodHandles::init_MemberName(Handle mname, Handle target, TRAPS) {
 174   // This method is used from java.lang.invoke.MemberName constructors.
 175   // It fills in the new MemberName from a java.lang.reflect.Member.
 176   Thread* thread = Thread::current();
 177   oop target_oop = target();
 178   Klass* target_klass = target_oop->klass();
 179   if (target_klass == SystemDictionary::reflect_Field_klass()) {
 180     oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder()
 181     int slot  = java_lang_reflect_Field::slot(target_oop);  // fd.index()
 182     Klass* k = java_lang_Class::as_Klass(clazz);


1127       else
1128         suffix = "/private";
1129     }
1130     jio_snprintf(qname, len, "MethodHandle::interpreter_entry::%s%s", name, suffix);
1131     trace_method_handle(_masm, qname);
1132     // Note:  Don't free the allocated char array because it's used
1133     // during runtime.
1134   }
1135 }
1136 
1137 //
1138 // Here are the native methods in java.lang.invoke.MethodHandleNatives
1139 // They are the private interface between this JVM and the HotSpot-specific
1140 // Java code that implements JSR 292 method handles.
1141 //
1142 // Note:  We use a JVM_ENTRY macro to define each of these, for this is the way
1143 // that intrinsic (non-JNI) native methods are defined in HotSpot.
1144 //
1145 
1146 #ifndef PRODUCT
1147 # ifndef ADVERTISE_CON_VALUES
1148 #   define ADVERTISE_CON_VALUES
1149 # endif
1150 #endif
1151 
1152 #ifdef ADVERTISE_CON_VALUES
1153 // The following macrology pushes a list of symbolic definitions,
1154 // all of integral type, up through getNamedCon, into the
1155 // verifyConstants method of jli.MethodHandleNatives.
1156 // In a debug build, and if the java -esa flag is thrown,
1157 // we make sure all of these names are kept in sync.
1158 #define EACH_NAMED_CON(template, requirement) \
1159     template(java_lang_invoke_MemberName,MN_IS_METHOD) \
1160     template(java_lang_invoke_MemberName,MN_IS_CONSTRUCTOR) \
1161     template(java_lang_invoke_MemberName,MN_IS_FIELD) \
1162     template(java_lang_invoke_MemberName,MN_IS_TYPE) \
1163     template(java_lang_invoke_MemberName,MN_CALLER_SENSITIVE) \
1164     template(java_lang_invoke_MemberName,MN_SEARCH_SUPERCLASSES) \
1165     template(java_lang_invoke_MemberName,MN_SEARCH_INTERFACES) \
1166     template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_SHIFT) \
1167     template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_MASK) \
1168     template(RefKind,REF_NONE) \
1169     template(RefKind,REF_getField) \
1170     template(RefKind,REF_getStatic) \
1171     template(RefKind,REF_putField) \
1172     template(RefKind,REF_putStatic) \
1173     template(RefKind,REF_invokeVirtual) \
1174     template(RefKind,REF_invokeStatic) \
1175     template(RefKind,REF_invokeSpecial) \
1176     template(RefKind,REF_newInvokeSpecial) \
1177     template(RefKind,REF_invokeInterface) \
1178     template(RefKind,REF_LIMIT) \
1179     template(ConstantPool,R_IFPRESENT) \
1180     template(ConstantPool,R_FORCE) \
1181     template(ConstantPool,R_SYMREF) \
1182     /*end*/
1183 
1184 class RefKind {
1185   public:
1186   enum {
1187     REF_NONE                    = 0,  // null value
1188     REF_getField                = 1,
1189     REF_getStatic               = 2,
1190     REF_putField                = 3,
1191     REF_putStatic               = 4,
1192     REF_invokeVirtual           = 5,
1193     REF_invokeStatic            = 6,
1194     REF_invokeSpecial           = 7,
1195     REF_newInvokeSpecial        = 8,
1196     REF_invokeInterface         = 9,
1197     REF_LIMIT                  = 10
1198   };
1199 };
1200 
1201 #define IGNORE_REQ(req_expr) /* req_expr */
1202 #define ONE_PLUS(scope,value) 1+
1203 static const int con_value_count = EACH_NAMED_CON(ONE_PLUS, IGNORE_REQ) 0;
1204 #define VALUE_COMMA(scope,value) scope::value,
1205 static const int con_values[con_value_count+1] = { EACH_NAMED_CON(VALUE_COMMA, IGNORE_REQ) 0 };
1206 #define STRING_NULL(scope,value) #value "\0"
1207 static const char con_names[] = { EACH_NAMED_CON(STRING_NULL, IGNORE_REQ) };
1208 
1209 static bool advertise_con_value(int which) {
1210   if (which < 0)  return false;
1211   bool ok = true;
1212   int count = 0;
1213 #define INC_COUNT(scope,value) \
1214   ++count;
1215 #define CHECK_REQ(req_expr) \
1216   if (which < count)  return ok; \
1217   ok = (req_expr);
1218   EACH_NAMED_CON(INC_COUNT, CHECK_REQ);
1219 #undef INC_COUNT
1220 #undef CHECK_REQ
1221   assert(count == con_value_count, "");
1222   if (which < count)  return ok;
1223   return false;
1224 }
1225 
1226 #undef ONE_PLUS
1227 #undef VALUE_COMMA
1228 #undef STRING_NULL
1229 #undef EACH_NAMED_CON
1230 
1231 #endif // ADVERTISE_CON_VALUES
1232 
1233 JVM_ENTRY(jint, MHN_getNamedCon(JNIEnv *env, jobject igcls, jint which, jobjectArray box_jh)) {
1234 #ifdef ADVERTISE_CON_VALUES
1235   if (advertise_con_value(which)) {
1236     assert(which >= 0 && which < con_value_count, "");
1237     int con = con_values[which];
1238     objArrayHandle box(THREAD, (objArrayOop) JNIHandles::resolve(box_jh));
1239     if (box.not_null() && box->klass() == Universe::objectArrayKlassObj() && box->length() > 0) {
1240       const char* str = &con_names[0];
1241       for (int i = 0; i < which; i++)
1242         str += strlen(str) + 1;   // skip name and null
1243       oop name = java_lang_String::create_oop_from_str(str, CHECK_0);  // possible safepoint
1244       box->obj_at_put(0, name);
1245     }
1246     return con;
1247   }
1248 #endif
1249   return 0;
1250 }
1251 JVM_END
1252 
1253 // void init(MemberName self, AccessibleObject ref)
1254 JVM_ENTRY(void, MHN_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) {


1434     // Walk all nmethods depending on this call site.
1435     MutexLocker mu(Compile_lock, thread);
1436     MethodHandles::flush_dependent_nmethods(call_site, target);
1437     java_lang_invoke_CallSite::set_target(call_site(), target());
1438   }
1439 }
1440 JVM_END
1441 
1442 JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
1443   Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
1444   Handle target   (THREAD, JNIHandles::resolve_non_null(target_jh));
1445   {
1446     // Walk all nmethods depending on this call site.
1447     MutexLocker mu(Compile_lock, thread);
1448     MethodHandles::flush_dependent_nmethods(call_site, target);
1449     java_lang_invoke_CallSite::set_target_volatile(call_site(), target());
1450   }
1451 }
1452 JVM_END
1453 

















































































1454 // It is called by a Cleaner object which ensures that dropped CallSites properly
1455 // deallocate their dependency information.
1456 JVM_ENTRY(void, MHN_clearCallSiteContext(JNIEnv* env, jobject igcls, jobject context_jh)) {
1457   Handle context(THREAD, JNIHandles::resolve_non_null(context_jh));
1458   {
1459     // Walk all nmethods depending on this call site.
1460     MutexLocker mu1(Compile_lock, thread);
1461 
1462     int marked = 0;
1463     {
1464       NoSafepointVerifier nsv;
1465       MutexLockerEx mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
1466       assert(safe_to_expunge(), "removal is not safe");
1467       DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context());
1468       marked = deps.remove_all_dependents();
1469     }
1470     if (marked > 0) {
1471       // At least one nmethod has been marked for deoptimization
1472       VM_Deoptimize op;
1473       VMThread::execute(&op);


1513 #define MH    JLINV "MethodHandle;"
1514 #define MEM   JLINV "MemberName;"
1515 #define CTX   JLINV "MethodHandleNatives$CallSiteContext;"
1516 
1517 #define CC (char*)  /*cast a literal from (const char*)*/
1518 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
1519 
1520 // These are the native methods on java.lang.invoke.MethodHandleNatives.
1521 static JNINativeMethod MHN_methods[] = {
1522   {CC "init",                      CC "(" MEM "" OBJ ")V",                   FN_PTR(MHN_init_Mem)},
1523   {CC "expand",                    CC "(" MEM ")V",                          FN_PTR(MHN_expand_Mem)},
1524   {CC "resolve",                   CC "(" MEM "" CLS "Z)" MEM,               FN_PTR(MHN_resolve_Mem)},
1525   //  static native int getNamedCon(int which, Object[] name)
1526   {CC "getNamedCon",               CC "(I[" OBJ ")I",                        FN_PTR(MHN_getNamedCon)},
1527   //  static native int getMembers(Class<?> defc, String matchName, String matchSig,
1528   //          int matchFlags, Class<?> caller, int skip, MemberName[] results);
1529   {CC "getMembers",                CC "(" CLS "" STRG "" STRG "I" CLS "I[" MEM ")I", FN_PTR(MHN_getMembers)},
1530   {CC "objectFieldOffset",         CC "(" MEM ")J",                          FN_PTR(MHN_objectFieldOffset)},
1531   {CC "setCallSiteTargetNormal",   CC "(" CS "" MH ")V",                     FN_PTR(MHN_setCallSiteTargetNormal)},
1532   {CC "setCallSiteTargetVolatile", CC "(" CS "" MH ")V",                     FN_PTR(MHN_setCallSiteTargetVolatile)},

1533   {CC "clearCallSiteContext",      CC "(" CTX ")V",                          FN_PTR(MHN_clearCallSiteContext)},
1534   {CC "staticFieldOffset",         CC "(" MEM ")J",                          FN_PTR(MHN_staticFieldOffset)},
1535   {CC "staticFieldBase",           CC "(" MEM ")" OBJ,                        FN_PTR(MHN_staticFieldBase)},
1536   {CC "getMemberVMInfo",           CC "(" MEM ")" OBJ,                        FN_PTR(MHN_getMemberVMInfo)}
1537 };
1538 
1539 static JNINativeMethod MH_methods[] = {
1540   // UnsupportedOperationException throwers
1541   {CC "invoke",                    CC "([" OBJ ")" OBJ,                       FN_PTR(MH_invoke_UOE)},
1542   {CC "invokeExact",               CC "([" OBJ ")" OBJ,                       FN_PTR(MH_invokeExact_UOE)}
1543 };
1544 
1545 /**
1546  * This one function is exported, used by NativeLookup.
1547  */
1548 JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
1549   assert(!MethodHandles::enabled(), "must not be enabled");
1550   assert(SystemDictionary::MethodHandle_klass() != NULL, "should be present");
1551 
1552   oop mirror = SystemDictionary::MethodHandle_klass()->java_mirror();


< prev index next >