< prev index next >

src/hotspot/share/prims/methodHandles.cpp

Print this page

   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 

  25 #include "classfile/javaClasses.inline.hpp"
  26 #include "classfile/stringTable.hpp"
  27 #include "classfile/symbolTable.hpp"
  28 #include "classfile/systemDictionary.hpp"

  29 #include "classfile/vmClasses.hpp"
  30 #include "code/codeCache.hpp"
  31 #include "code/dependencyContext.hpp"
  32 #include "compiler/compileBroker.hpp"
  33 #include "interpreter/interpreter.hpp"
  34 #include "interpreter/oopMapCache.hpp"
  35 #include "interpreter/linkResolver.hpp"
  36 #include "jvm_io.h"
  37 #include "logging/log.hpp"
  38 #include "logging/logStream.hpp"
  39 #include "memory/allocation.inline.hpp"
  40 #include "memory/oopFactory.hpp"
  41 #include "memory/resourceArea.hpp"
  42 #include "memory/universe.hpp"
  43 #include "oops/klass.inline.hpp"
  44 #include "oops/objArrayKlass.hpp"
  45 #include "oops/objArrayOop.inline.hpp"
  46 #include "oops/oop.inline.hpp"
  47 #include "oops/typeArrayOop.inline.hpp"
  48 #include "prims/methodHandles.hpp"
  49 #include "runtime/deoptimization.hpp"
  50 #include "runtime/fieldDescriptor.inline.hpp"
  51 #include "runtime/handles.inline.hpp"
  52 #include "runtime/interfaceSupport.inline.hpp"

  53 #include "runtime/javaCalls.hpp"
  54 #include "runtime/jniHandles.inline.hpp"

  55 #include "runtime/timerTrace.hpp"
  56 #include "runtime/reflection.hpp"
  57 #include "runtime/safepointVerifiers.hpp"
  58 #include "runtime/signature.hpp"
  59 #include "runtime/stubRoutines.hpp"
  60 #include "sanitizers/leak.hpp"

  61 #include "utilities/exceptions.hpp"
  62 
  63 
  64 /*
  65  * JSR 292 reference implementation: method handles
  66  * The JDK 7 reference implementation represented method handle
  67  * combinations as chains.  Each link in the chain had a "vmentry"
  68  * field which pointed at a bit of assembly code which performed
  69  * one transformation before dispatching to the next link in the chain.
  70  *
  71  * The current reference implementation pushes almost all code generation
  72  * responsibility to (trusted) Java code.  A method handle contains a
  73  * pointer to its "LambdaForm", which embodies all details of the method
  74  * handle's behavior.  The LambdaForm is a normal Java object, managed
  75  * by a runtime coded in Java.
  76  */
  77 
  78 bool MethodHandles::_enabled = false; // set true after successful native linkage
  79 MethodHandlesAdapterBlob* MethodHandles::_adapter_code = nullptr;
  80 

1018   int count = 0;
1019 #define INC_COUNT(scope,value) \
1020   ++count;
1021 #define CHECK_REQ(req_expr) \
1022   if (which < count)  return ok; \
1023   ok = (req_expr);
1024   EACH_NAMED_CON(INC_COUNT, CHECK_REQ);
1025 #undef INC_COUNT
1026 #undef CHECK_REQ
1027   assert(count == con_value_count, "");
1028   if (which < count)  return ok;
1029   return false;
1030 }
1031 
1032 #undef ONE_PLUS
1033 #undef VALUE_COMMA
1034 #undef STRING_NULL
1035 #undef EACH_NAMED_CON
1036 #endif // PRODUCT
1037 
1038 JVM_ENTRY(jint, MHN_getNamedCon(JNIEnv *env, jobject igcls, jint which, jobjectArray box_jh)) {
1039 #ifndef PRODUCT
1040   if (advertise_con_value(which)) {
1041     assert(which >= 0 && which < con_value_count, "");
1042     int con = con_values[which];
1043     objArrayHandle box(THREAD, (objArrayOop) JNIHandles::resolve(box_jh));
1044     if (box.not_null() && box->klass() == Universe::objectArrayKlass() && box->length() > 0) {
1045       const char* str = &con_names[0];
1046       for (int i = 0; i < which; i++)
1047         str += strlen(str) + 1;   // skip name and null
1048       oop name = java_lang_String::create_oop_from_str(str, CHECK_0);  // possible safepoint
1049       box->obj_at_put(0, name);
1050     }
1051     return con;
1052   }
1053 #endif
1054   return 0;
1055 }
1056 JVM_END
1057 
1058 // void init(MemberName self, AccessibleObject ref)
1059 JVM_ENTRY(void, MHN_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) {
1060   if (mname_jh == nullptr) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); }
1061   if (target_jh == nullptr) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); }
1062   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
1063   Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
1064   MethodHandles::init_MemberName(mname, target, CHECK);
1065 }
1066 JVM_END
1067 
1068 // void expand(MemberName self)
1069 JVM_ENTRY(void, MHN_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) {
1070   if (mname_jh == nullptr) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); }
1071   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
1072   MethodHandles::expand_MemberName(mname, 0, CHECK);
1073 }
1074 JVM_END
1075 
1076 // void resolve(MemberName self, Class<?> caller)
1077 JVM_ENTRY(jobject, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh,
1078     jint lookup_mode, jboolean speculative_resolve)) {
1079   if (mname_jh == nullptr) { THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "mname is null"); }
1080   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
1081 
1082   // The trusted Java code that calls this method should already have performed
1083   // access checks on behalf of the given caller.  But, we can verify this.
1084   // This only verifies from the context of the lookup class.  It does not
1085   // verify the lookup context for a Lookup object teleported from one module
1086   // to another. Such Lookup object can only access the intersection of the set
1087   // of accessible classes from both lookup class and previous lookup class.
1088   if (VerifyMethodHandles && (lookup_mode & LM_TRUSTED) == LM_TRUSTED && caller_jh != nullptr &&
1089       java_lang_invoke_MemberName::clazz(mname()) != nullptr) {
1090     Klass* reference_klass = java_lang_Class::as_Klass(java_lang_invoke_MemberName::clazz(mname()));
1091     if (reference_klass != nullptr && reference_klass->is_objArray_klass()) {
1092       reference_klass = ObjArrayKlass::cast(reference_klass)->bottom_klass();
1093     }
1094 
1095     // Reflection::verify_class_access can only handle instance classes.
1096     if (reference_klass != nullptr && reference_klass->is_instance_klass()) {
1097       // Emulate LinkResolver::check_klass_accessability.

1143 
1144 static jlong find_member_field_offset(oop mname, bool must_be_static, TRAPS) {
1145   if (mname == nullptr ||
1146       java_lang_invoke_MemberName::clazz(mname) == nullptr) {
1147     THROW_MSG_0(vmSymbols::java_lang_InternalError(), "mname not resolved");
1148   } else {
1149     int flags = java_lang_invoke_MemberName::flags(mname);
1150     if ((flags & IS_FIELD) != 0 &&
1151         (must_be_static
1152          ? (flags & JVM_ACC_STATIC) != 0
1153          : (flags & JVM_ACC_STATIC) == 0)) {
1154       intptr_t vmindex = java_lang_invoke_MemberName::vmindex(mname);
1155       return (jlong) vmindex;
1156     }
1157   }
1158   const char* msg = (must_be_static ? "static field required" : "non-static field required");
1159   THROW_MSG_0(vmSymbols::java_lang_InternalError(), msg);
1160   return 0;
1161 }
1162 
1163 JVM_ENTRY(jlong, MHN_objectFieldOffset(JNIEnv *env, jobject igcls, jobject mname_jh)) {
1164   return find_member_field_offset(JNIHandles::resolve(mname_jh), false, THREAD);
1165 }
1166 JVM_END
1167 
1168 JVM_ENTRY(jlong, MHN_staticFieldOffset(JNIEnv *env, jobject igcls, jobject mname_jh)) {
1169   return find_member_field_offset(JNIHandles::resolve(mname_jh), true, THREAD);
1170 }
1171 JVM_END
1172 
1173 JVM_ENTRY(jobject, MHN_staticFieldBase(JNIEnv *env, jobject igcls, jobject mname_jh)) {
1174   // use the other function to perform sanity checks:
1175   jlong ignore = find_member_field_offset(JNIHandles::resolve(mname_jh), true, CHECK_NULL);
1176   oop clazz = java_lang_invoke_MemberName::clazz(JNIHandles::resolve_non_null(mname_jh));
1177   return JNIHandles::make_local(THREAD, clazz);
1178 }
1179 JVM_END
1180 
1181 JVM_ENTRY(jobject, MHN_getMemberVMInfo(JNIEnv *env, jobject igcls, jobject mname_jh)) {
1182   if (mname_jh == nullptr)  return nullptr;
1183   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
1184   intptr_t vmindex  = java_lang_invoke_MemberName::vmindex(mname());
1185   objArrayHandle result = oopFactory::new_objArray_handle(vmClasses::Object_klass(), 2, CHECK_NULL);
1186   jvalue vmindex_value; vmindex_value.j = (long)vmindex;
1187   oop x = java_lang_boxing_object::create(T_LONG, &vmindex_value, CHECK_NULL);
1188   result->obj_at_put(0, x);
1189 
1190   int flags = java_lang_invoke_MemberName::flags(mname());
1191   if ((flags & IS_FIELD) != 0) {
1192     x = java_lang_invoke_MemberName::clazz(mname());
1193   } else {
1194     Method* vmtarget = java_lang_invoke_MemberName::vmtarget(mname());
1195     assert(vmtarget != nullptr && vmtarget->is_method(), "vmtarget is only method");
1196     x = mname();
1197   }
1198   result->obj_at_put(1, x);
1199   return JNIHandles::make_local(THREAD, result());
1200 }
1201 JVM_END
1202 
1203 JVM_ENTRY(void, MHN_setCallSiteTargetNormal(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
1204   Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
1205   Handle target   (THREAD, JNIHandles::resolve_non_null(target_jh));
1206   DeoptimizationScope deopt_scope;
1207   {
1208     // Walk all nmethods depending on this call site.
1209     MutexLocker mu(thread, Compile_lock);
1210     MethodHandles::mark_dependent_nmethods(&deopt_scope, call_site, target);
1211     java_lang_invoke_CallSite::set_target(call_site(), target());
1212     // This is assumed to be an 'atomic' operation by verification.
1213     // So keep it under lock for now.
1214     deopt_scope.deoptimize_marked();
1215   }
1216 }
1217 JVM_END
1218 
1219 JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
































1220   Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
1221   Handle target   (THREAD, JNIHandles::resolve_non_null(target_jh));
1222   DeoptimizationScope deopt_scope;
1223   {
1224     // Walk all nmethods depending on this call site.
1225     MutexLocker mu(thread, Compile_lock);
1226     MethodHandles::mark_dependent_nmethods(&deopt_scope, call_site, target);
1227     java_lang_invoke_CallSite::set_target_volatile(call_site(), target());
1228     // This is assumed to be an 'atomic' operation by verification.
1229     // So keep it under lock for now.
1230     deopt_scope.deoptimize_marked();
1231   }
1232 }
1233 JVM_END
1234 
1235 JVM_ENTRY(void, MHN_copyOutBootstrapArguments(JNIEnv* env, jobject igcls,
1236                                               jobject caller_jh, jintArray index_info_jh,
1237                                               jint start, jint end,
1238                                               jobjectArray buf_jh, jint pos,
1239                                               jboolean resolve, jobject ifna_jh)) {
1240   Klass* caller_k = java_lang_Class::as_Klass(JNIHandles::resolve(caller_jh));
1241   if (caller_k == nullptr || !caller_k->is_instance_klass()) {
1242       THROW_MSG(vmSymbols::java_lang_InternalError(), "bad caller");
1243   }
1244   InstanceKlass* caller = InstanceKlass::cast(caller_k);
1245   typeArrayOop index_info_oop = (typeArrayOop) JNIHandles::resolve(index_info_jh);
1246   if (index_info_oop == nullptr ||
1247       index_info_oop->klass() != Universe::intArrayKlass() ||
1248       typeArrayOop(index_info_oop)->length() < 2) {
1249       THROW_MSG(vmSymbols::java_lang_InternalError(), "bad index info (0)");
1250   }
1251   typeArrayHandle index_info(THREAD, index_info_oop);
1252   int bss_index_in_pool = index_info->int_at(1);
1253   // While we are here, take a quick look at the index info:
1254   if (bss_index_in_pool <= 0 ||
1255       bss_index_in_pool >= caller->constants()->length() ||

1301         // Store the pseudo-argument, and advance the pointers.
1302         buf->obj_at_put(pos++, pseudo_arg);
1303         ++start;
1304       }
1305     }
1306     // When we are done with this there may be regular arguments to process too.
1307   }
1308   Handle ifna(THREAD, JNIHandles::resolve(ifna_jh));
1309   caller->constants()->
1310     copy_bootstrap_arguments_at(bss_index_in_pool,
1311                                 start, end, buf, pos,
1312                                 (resolve == JNI_TRUE), ifna, CHECK);
1313 }
1314 JVM_END
1315 
1316 /**
1317  * Throws a java/lang/UnsupportedOperationException unconditionally.
1318  * This is required by the specification of MethodHandle.invoke if
1319  * invoked directly.
1320  */
1321 JVM_ENTRY(jobject, MH_invoke_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
1322   THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invoke cannot be invoked reflectively");
1323   return nullptr;
1324 }
1325 JVM_END
1326 
1327 /**
1328  * Throws a java/lang/UnsupportedOperationException unconditionally.
1329  * This is required by the specification of MethodHandle.invokeExact if
1330  * invoked directly.
1331  */
1332 JVM_ENTRY(jobject, MH_invokeExact_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
1333   THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invokeExact cannot be invoked reflectively");
1334   return nullptr;
1335 }
1336 JVM_END
1337 
1338 /**
1339  * Throws a java/lang/UnsupportedOperationException unconditionally.
1340  * This is required by the specification of VarHandle.{access-mode} if
1341  * invoked directly.
1342  */
1343 JVM_ENTRY(jobject, VH_UOE(JNIEnv* env, jobject vh, jobjectArray args)) {
1344   THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "VarHandle access mode methods cannot be invoked reflectively");
1345   return nullptr;
1346 }
1347 JVM_END
1348 
1349 
1350 /// JVM_RegisterMethodHandleMethods
1351 
1352 #define LANG "Ljava/lang/"

1405   {CC "getAndSet",                  CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1406   {CC "getAndSetAcquire",           CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1407   {CC "getAndSetRelease",           CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1408   {CC "getAndAdd",                  CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1409   {CC "getAndAddAcquire",           CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1410   {CC "getAndAddRelease",           CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1411   {CC "getAndBitwiseOr",            CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1412   {CC "getAndBitwiseOrAcquire",     CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1413   {CC "getAndBitwiseOrRelease",     CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1414   {CC "getAndBitwiseAnd",           CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1415   {CC "getAndBitwiseAndAcquire",    CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1416   {CC "getAndBitwiseAndRelease",    CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1417   {CC "getAndBitwiseXor",           CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1418   {CC "getAndBitwiseXorAcquire",    CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1419   {CC "getAndBitwiseXorRelease",    CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)}
1420 };
1421 
1422 /**
1423  * This one function is exported, used by NativeLookup.
1424  */
1425 JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
1426   assert(!MethodHandles::enabled(), "must not be enabled");
1427   assert(vmClasses::MethodHandle_klass() != nullptr, "should be present");
1428   assert(vmClasses::VarHandle_klass() != nullptr, "should be present");
1429 
1430   oop mh_mirror = vmClasses::MethodHandle_klass()->java_mirror();
1431   oop vh_mirror = vmClasses::VarHandle_klass()->java_mirror();
1432   jclass MH_class = (jclass) JNIHandles::make_local(THREAD, mh_mirror);
1433   jclass VH_class = (jclass) JNIHandles::make_local(THREAD, vh_mirror);
1434 
1435   {
1436     ThreadToNativeFromVM ttnfv(thread);
1437 
1438     int status = env->RegisterNatives(MHN_class, MHN_methods, sizeof(MHN_methods)/sizeof(JNINativeMethod));
1439     guarantee(status == JNI_OK && !env->ExceptionCheck(),
1440               "register java.lang.invoke.MethodHandleNative natives");
1441 
1442     status = env->RegisterNatives(MH_class, MH_methods, sizeof(MH_methods)/sizeof(JNINativeMethod));
1443     guarantee(status == JNI_OK && !env->ExceptionCheck(),
1444               "register java.lang.invoke.MethodHandle natives");
1445 
1446     status = env->RegisterNatives(VH_class, VH_methods, sizeof(VH_methods)/sizeof(JNINativeMethod));
1447     guarantee(status == JNI_OK && !env->ExceptionCheck(),
1448               "register java.lang.invoke.VarHandle natives");
1449   }
1450 
1451   log_debug(methodhandles, indy)("MethodHandle support loaded (using LambdaForms)");
1452 
1453   MethodHandles::set_enabled(true);
1454 }
1455 JVM_END























































   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "cds/cds_globals.hpp"
  26 #include "classfile/javaClasses.inline.hpp"
  27 #include "classfile/stringTable.hpp"
  28 #include "classfile/symbolTable.hpp"
  29 #include "classfile/systemDictionary.hpp"
  30 #include "classfile/systemDictionaryShared.hpp"
  31 #include "classfile/vmClasses.hpp"
  32 #include "code/codeCache.hpp"
  33 #include "code/dependencyContext.hpp"
  34 #include "compiler/compileBroker.hpp"
  35 #include "interpreter/interpreter.hpp"
  36 #include "interpreter/oopMapCache.hpp"
  37 #include "interpreter/linkResolver.hpp"
  38 #include "jvm_io.h"
  39 #include "logging/log.hpp"
  40 #include "logging/logStream.hpp"
  41 #include "memory/allocation.inline.hpp"
  42 #include "memory/oopFactory.hpp"
  43 #include "memory/resourceArea.hpp"
  44 #include "memory/universe.hpp"
  45 #include "oops/klass.inline.hpp"
  46 #include "oops/objArrayKlass.hpp"
  47 #include "oops/objArrayOop.inline.hpp"
  48 #include "oops/oop.inline.hpp"
  49 #include "oops/typeArrayOop.inline.hpp"
  50 #include "prims/methodHandles.hpp"
  51 #include "runtime/deoptimization.hpp"
  52 #include "runtime/fieldDescriptor.inline.hpp"
  53 #include "runtime/handles.inline.hpp"
  54 #include "runtime/interfaceSupport.inline.hpp"
  55 #include "runtime/java.hpp"
  56 #include "runtime/javaCalls.hpp"
  57 #include "runtime/jniHandles.inline.hpp"
  58 #include "runtime/perfData.inline.hpp"
  59 #include "runtime/timerTrace.hpp"
  60 #include "runtime/reflection.hpp"
  61 #include "runtime/safepointVerifiers.hpp"
  62 #include "runtime/signature.hpp"
  63 #include "runtime/stubRoutines.hpp"
  64 #include "sanitizers/leak.hpp"
  65 #include "services/management.hpp"
  66 #include "utilities/exceptions.hpp"
  67 
  68 
  69 /*
  70  * JSR 292 reference implementation: method handles
  71  * The JDK 7 reference implementation represented method handle
  72  * combinations as chains.  Each link in the chain had a "vmentry"
  73  * field which pointed at a bit of assembly code which performed
  74  * one transformation before dispatching to the next link in the chain.
  75  *
  76  * The current reference implementation pushes almost all code generation
  77  * responsibility to (trusted) Java code.  A method handle contains a
  78  * pointer to its "LambdaForm", which embodies all details of the method
  79  * handle's behavior.  The LambdaForm is a normal Java object, managed
  80  * by a runtime coded in Java.
  81  */
  82 
  83 bool MethodHandles::_enabled = false; // set true after successful native linkage
  84 MethodHandlesAdapterBlob* MethodHandles::_adapter_code = nullptr;
  85 

1023   int count = 0;
1024 #define INC_COUNT(scope,value) \
1025   ++count;
1026 #define CHECK_REQ(req_expr) \
1027   if (which < count)  return ok; \
1028   ok = (req_expr);
1029   EACH_NAMED_CON(INC_COUNT, CHECK_REQ);
1030 #undef INC_COUNT
1031 #undef CHECK_REQ
1032   assert(count == con_value_count, "");
1033   if (which < count)  return ok;
1034   return false;
1035 }
1036 
1037 #undef ONE_PLUS
1038 #undef VALUE_COMMA
1039 #undef STRING_NULL
1040 #undef EACH_NAMED_CON
1041 #endif // PRODUCT
1042 
1043 JVM_ENTRY_PROF(jint, MHN_getNamedCon, MHN_getNamedCon(JNIEnv *env, jobject igcls, jint which, jobjectArray box_jh)) {
1044 #ifndef PRODUCT
1045   if (advertise_con_value(which)) {
1046     assert(which >= 0 && which < con_value_count, "");
1047     int con = con_values[which];
1048     objArrayHandle box(THREAD, (objArrayOop) JNIHandles::resolve(box_jh));
1049     if (box.not_null() && box->klass() == Universe::objectArrayKlass() && box->length() > 0) {
1050       const char* str = &con_names[0];
1051       for (int i = 0; i < which; i++)
1052         str += strlen(str) + 1;   // skip name and null
1053       oop name = java_lang_String::create_oop_from_str(str, CHECK_0);  // possible safepoint
1054       box->obj_at_put(0, name);
1055     }
1056     return con;
1057   }
1058 #endif
1059   return 0;
1060 }
1061 JVM_END
1062 
1063 // void init(MemberName self, AccessibleObject ref)
1064 JVM_ENTRY_PROF(void, MHN_init_Mem, MHN_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) {
1065   if (mname_jh == nullptr) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); }
1066   if (target_jh == nullptr) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); }
1067   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
1068   Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
1069   MethodHandles::init_MemberName(mname, target, CHECK);
1070 }
1071 JVM_END
1072 
1073 // void expand(MemberName self)
1074 JVM_ENTRY_PROF(void, MHN_expand_Mem, MHN_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) {
1075   if (mname_jh == nullptr) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); }
1076   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
1077   MethodHandles::expand_MemberName(mname, 0, CHECK);
1078 }
1079 JVM_END
1080 
1081 // void resolve(MemberName self, Class<?> caller)
1082 JVM_ENTRY_PROF(jobject, MHN_resolve_Mem, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh,
1083     jint lookup_mode, jboolean speculative_resolve)) {
1084   if (mname_jh == nullptr) { THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "mname is null"); }
1085   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
1086 
1087   // The trusted Java code that calls this method should already have performed
1088   // access checks on behalf of the given caller.  But, we can verify this.
1089   // This only verifies from the context of the lookup class.  It does not
1090   // verify the lookup context for a Lookup object teleported from one module
1091   // to another. Such Lookup object can only access the intersection of the set
1092   // of accessible classes from both lookup class and previous lookup class.
1093   if (VerifyMethodHandles && (lookup_mode & LM_TRUSTED) == LM_TRUSTED && caller_jh != nullptr &&
1094       java_lang_invoke_MemberName::clazz(mname()) != nullptr) {
1095     Klass* reference_klass = java_lang_Class::as_Klass(java_lang_invoke_MemberName::clazz(mname()));
1096     if (reference_klass != nullptr && reference_klass->is_objArray_klass()) {
1097       reference_klass = ObjArrayKlass::cast(reference_klass)->bottom_klass();
1098     }
1099 
1100     // Reflection::verify_class_access can only handle instance classes.
1101     if (reference_klass != nullptr && reference_klass->is_instance_klass()) {
1102       // Emulate LinkResolver::check_klass_accessability.

1148 
1149 static jlong find_member_field_offset(oop mname, bool must_be_static, TRAPS) {
1150   if (mname == nullptr ||
1151       java_lang_invoke_MemberName::clazz(mname) == nullptr) {
1152     THROW_MSG_0(vmSymbols::java_lang_InternalError(), "mname not resolved");
1153   } else {
1154     int flags = java_lang_invoke_MemberName::flags(mname);
1155     if ((flags & IS_FIELD) != 0 &&
1156         (must_be_static
1157          ? (flags & JVM_ACC_STATIC) != 0
1158          : (flags & JVM_ACC_STATIC) == 0)) {
1159       intptr_t vmindex = java_lang_invoke_MemberName::vmindex(mname);
1160       return (jlong) vmindex;
1161     }
1162   }
1163   const char* msg = (must_be_static ? "static field required" : "non-static field required");
1164   THROW_MSG_0(vmSymbols::java_lang_InternalError(), msg);
1165   return 0;
1166 }
1167 
1168 JVM_ENTRY_PROF(jlong, MHN_objectFieldOffset, MHN_objectFieldOffset(JNIEnv *env, jobject igcls, jobject mname_jh)) {
1169   return find_member_field_offset(JNIHandles::resolve(mname_jh), false, THREAD);
1170 }
1171 JVM_END
1172 
1173 JVM_ENTRY_PROF(jlong, MHN_staticFieldOffset, MHN_staticFieldOffset(JNIEnv *env, jobject igcls, jobject mname_jh)) {
1174   return find_member_field_offset(JNIHandles::resolve(mname_jh), true, THREAD);
1175 }
1176 JVM_END
1177 
1178 JVM_ENTRY_PROF(jobject, MHN_staticFieldBase, MHN_staticFieldBase(JNIEnv *env, jobject igcls, jobject mname_jh)) {
1179   // use the other function to perform sanity checks:
1180   jlong ignore = find_member_field_offset(JNIHandles::resolve(mname_jh), true, CHECK_NULL);
1181   oop clazz = java_lang_invoke_MemberName::clazz(JNIHandles::resolve_non_null(mname_jh));
1182   return JNIHandles::make_local(THREAD, clazz);
1183 }
1184 JVM_END
1185 
1186 JVM_ENTRY_PROF(jobject, MHN_getMemberVMInfo, MHN_getMemberVMInfo(JNIEnv *env, jobject igcls, jobject mname_jh)) {
1187   if (mname_jh == nullptr)  return nullptr;
1188   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
1189   intptr_t vmindex  = java_lang_invoke_MemberName::vmindex(mname());
1190   objArrayHandle result = oopFactory::new_objArray_handle(vmClasses::Object_klass(), 2, CHECK_NULL);
1191   jvalue vmindex_value; vmindex_value.j = (long)vmindex;
1192   oop x = java_lang_boxing_object::create(T_LONG, &vmindex_value, CHECK_NULL);
1193   result->obj_at_put(0, x);
1194 
1195   int flags = java_lang_invoke_MemberName::flags(mname());
1196   if ((flags & IS_FIELD) != 0) {
1197     x = java_lang_invoke_MemberName::clazz(mname());
1198   } else {
1199     Method* vmtarget = java_lang_invoke_MemberName::vmtarget(mname());
1200     assert(vmtarget != nullptr && vmtarget->is_method(), "vmtarget is only method");
1201     x = mname();
1202   }
1203   result->obj_at_put(1, x);
1204   return JNIHandles::make_local(THREAD, result());
1205 }
1206 JVM_END
1207 
1208 JVM_ENTRY_PROF(void, MHN_setCallSiteTargetNormal, MHN_setCallSiteTargetNormal(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
1209   Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
1210   Handle target   (THREAD, JNIHandles::resolve_non_null(target_jh));
1211   DeoptimizationScope deopt_scope;
1212   {
1213     // Walk all nmethods depending on this call site.
1214     MutexLocker mu(thread, Compile_lock);
1215     MethodHandles::mark_dependent_nmethods(&deopt_scope, call_site, target);
1216     java_lang_invoke_CallSite::set_target(call_site(), target());
1217     // This is assumed to be an 'atomic' operation by verification.
1218     // So keep it under lock for now.
1219     deopt_scope.deoptimize_marked();
1220   }
1221 }
1222 JVM_END
1223 
1224 // Make sure the class is linked. If the class cannot be verified, etc, an exception will be thrown.
1225 JVM_ENTRY_PROF(void, MHN_checkArchivable, MHN_checkArchivable(JNIEnv *env, jobject igcls, jclass klass_jh)) {
1226   if (klass_jh == nullptr) { THROW_MSG(vmSymbols::java_lang_InternalError(), "klass is null"); }
1227 
1228   if (CDSConfig::is_dumping_invokedynamic()) {
1229     Klass* klass = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(klass_jh));
1230     if (klass != nullptr && klass->is_instance_klass()) {
1231       // klass could be null during very early VM start-up
1232       InstanceKlass* ik = InstanceKlass::cast(klass);
1233       ik->link_class(THREAD); // exception will be thrown if unverifiable
1234       if (!ik->is_linked()) {
1235         assert(HAS_PENDING_EXCEPTION, "must be");
1236         ResourceMark rm;
1237         log_warning(cds)("Cannot use unverifiable class %s in MethodType",
1238                          klass->external_name());
1239         return;
1240       }
1241 
1242       if (SystemDictionaryShared::is_jfr_event_class(ik)) {
1243         ResourceMark rm;
1244         log_warning(cds)("Cannot use JFR event class %s in MethodType",
1245                          klass->external_name());
1246         Exceptions::fthrow(THREAD_AND_LOCATION,
1247                            vmSymbols::java_lang_NoClassDefFoundError(),
1248                            "Class %s, or one of its supertypes, is a JFR event class",
1249                            klass->external_name());
1250       }
1251     }
1252   }
1253 }
1254 JVM_END
1255 
1256 JVM_ENTRY_PROF(void, MHN_setCallSiteTargetVolatile, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) {
1257   Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh));
1258   Handle target   (THREAD, JNIHandles::resolve_non_null(target_jh));
1259   DeoptimizationScope deopt_scope;
1260   {
1261     // Walk all nmethods depending on this call site.
1262     MutexLocker mu(thread, Compile_lock);
1263     MethodHandles::mark_dependent_nmethods(&deopt_scope, call_site, target);
1264     java_lang_invoke_CallSite::set_target_volatile(call_site(), target());
1265     // This is assumed to be an 'atomic' operation by verification.
1266     // So keep it under lock for now.
1267     deopt_scope.deoptimize_marked();
1268   }
1269 }
1270 JVM_END
1271 
1272 JVM_ENTRY_PROF(void, MHN_copyOutBootstrapArguments, MHN_copyOutBootstrapArguments(JNIEnv* env, jobject igcls,
1273                                               jobject caller_jh, jintArray index_info_jh,
1274                                               jint start, jint end,
1275                                               jobjectArray buf_jh, jint pos,
1276                                               jboolean resolve, jobject ifna_jh)) {
1277   Klass* caller_k = java_lang_Class::as_Klass(JNIHandles::resolve(caller_jh));
1278   if (caller_k == nullptr || !caller_k->is_instance_klass()) {
1279       THROW_MSG(vmSymbols::java_lang_InternalError(), "bad caller");
1280   }
1281   InstanceKlass* caller = InstanceKlass::cast(caller_k);
1282   typeArrayOop index_info_oop = (typeArrayOop) JNIHandles::resolve(index_info_jh);
1283   if (index_info_oop == nullptr ||
1284       index_info_oop->klass() != Universe::intArrayKlass() ||
1285       typeArrayOop(index_info_oop)->length() < 2) {
1286       THROW_MSG(vmSymbols::java_lang_InternalError(), "bad index info (0)");
1287   }
1288   typeArrayHandle index_info(THREAD, index_info_oop);
1289   int bss_index_in_pool = index_info->int_at(1);
1290   // While we are here, take a quick look at the index info:
1291   if (bss_index_in_pool <= 0 ||
1292       bss_index_in_pool >= caller->constants()->length() ||

1338         // Store the pseudo-argument, and advance the pointers.
1339         buf->obj_at_put(pos++, pseudo_arg);
1340         ++start;
1341       }
1342     }
1343     // When we are done with this there may be regular arguments to process too.
1344   }
1345   Handle ifna(THREAD, JNIHandles::resolve(ifna_jh));
1346   caller->constants()->
1347     copy_bootstrap_arguments_at(bss_index_in_pool,
1348                                 start, end, buf, pos,
1349                                 (resolve == JNI_TRUE), ifna, CHECK);
1350 }
1351 JVM_END
1352 
1353 /**
1354  * Throws a java/lang/UnsupportedOperationException unconditionally.
1355  * This is required by the specification of MethodHandle.invoke if
1356  * invoked directly.
1357  */
1358 JVM_ENTRY_PROF(jobject, MH_invoke_UOE, MH_invoke_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
1359   THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invoke cannot be invoked reflectively");
1360   return nullptr;
1361 }
1362 JVM_END
1363 
1364 /**
1365  * Throws a java/lang/UnsupportedOperationException unconditionally.
1366  * This is required by the specification of MethodHandle.invokeExact if
1367  * invoked directly.
1368  */
1369 JVM_ENTRY_PROF(jobject, MH_invokeExact_UOE, MH_invokeExact_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
1370   THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invokeExact cannot be invoked reflectively");
1371   return nullptr;
1372 }
1373 JVM_END
1374 
1375 /**
1376  * Throws a java/lang/UnsupportedOperationException unconditionally.
1377  * This is required by the specification of VarHandle.{access-mode} if
1378  * invoked directly.
1379  */
1380 JVM_ENTRY(jobject, VH_UOE(JNIEnv* env, jobject vh, jobjectArray args)) {
1381   THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "VarHandle access mode methods cannot be invoked reflectively");
1382   return nullptr;
1383 }
1384 JVM_END
1385 
1386 
1387 /// JVM_RegisterMethodHandleMethods
1388 
1389 #define LANG "Ljava/lang/"

1442   {CC "getAndSet",                  CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1443   {CC "getAndSetAcquire",           CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1444   {CC "getAndSetRelease",           CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1445   {CC "getAndAdd",                  CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1446   {CC "getAndAddAcquire",           CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1447   {CC "getAndAddRelease",           CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1448   {CC "getAndBitwiseOr",            CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1449   {CC "getAndBitwiseOrAcquire",     CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1450   {CC "getAndBitwiseOrRelease",     CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1451   {CC "getAndBitwiseAnd",           CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1452   {CC "getAndBitwiseAndAcquire",    CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1453   {CC "getAndBitwiseAndRelease",    CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1454   {CC "getAndBitwiseXor",           CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1455   {CC "getAndBitwiseXorAcquire",    CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)},
1456   {CC "getAndBitwiseXorRelease",    CC "([" OBJ ")" OBJ,    FN_PTR(VH_UOE)}
1457 };
1458 
1459 /**
1460  * This one function is exported, used by NativeLookup.
1461  */
1462 JVM_ENTRY_PROF(void, JVM_RegisterMethodHandleMethods, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
1463   assert(!MethodHandles::enabled(), "must not be enabled");
1464   assert(vmClasses::MethodHandle_klass() != nullptr, "should be present");
1465   assert(vmClasses::VarHandle_klass() != nullptr, "should be present");
1466 
1467   oop mh_mirror = vmClasses::MethodHandle_klass()->java_mirror();
1468   oop vh_mirror = vmClasses::VarHandle_klass()->java_mirror();
1469   jclass MH_class = (jclass) JNIHandles::make_local(THREAD, mh_mirror);
1470   jclass VH_class = (jclass) JNIHandles::make_local(THREAD, vh_mirror);
1471 
1472   {
1473     ThreadToNativeFromVM ttnfv(thread);
1474 
1475     int status = env->RegisterNatives(MHN_class, MHN_methods, sizeof(MHN_methods)/sizeof(JNINativeMethod));
1476     guarantee(status == JNI_OK && !env->ExceptionCheck(),
1477               "register java.lang.invoke.MethodHandleNative natives");
1478 
1479     status = env->RegisterNatives(MH_class, MH_methods, sizeof(MH_methods)/sizeof(JNINativeMethod));
1480     guarantee(status == JNI_OK && !env->ExceptionCheck(),
1481               "register java.lang.invoke.MethodHandle natives");
1482 
1483     status = env->RegisterNatives(VH_class, VH_methods, sizeof(VH_methods)/sizeof(JNINativeMethod));
1484     guarantee(status == JNI_OK && !env->ExceptionCheck(),
1485               "register java.lang.invoke.VarHandle natives");
1486   }
1487 
1488   log_debug(methodhandles, indy)("MethodHandle support loaded (using LambdaForms)");
1489 
1490   MethodHandles::set_enabled(true);
1491 }
1492 JVM_END
1493 
1494 #define DO_COUNTERS(macro)             \
1495   macro(MHN_init_Mem)                  \
1496   macro(MHN_expand_Mem)                \
1497   macro(MHN_resolve_Mem)               \
1498   macro(MHN_checkArchivable)           \
1499   macro(MHN_getNamedCon)               \
1500   macro(MHN_objectFieldOffset)         \
1501   macro(MHN_setCallSiteTargetNormal)   \
1502   macro(MHN_setCallSiteTargetVolatile) \
1503   macro(MHN_copyOutBootstrapArguments) \
1504   macro(MHN_staticFieldOffset)         \
1505   macro(MHN_staticFieldBase)           \
1506   macro(MHN_getMemberVMInfo)           \
1507   macro(MH_invoke_UOE)                 \
1508   macro(MH_invokeExact_UOE)            \
1509   macro(JVM_RegisterMethodHandleMethods)
1510 
1511 #define INIT_COUNTER(name) \
1512     NEWPERFTICKCOUNTERS(_perf_##name##_timer, SUN_RT, #name); \
1513     NEWPERFEVENTCOUNTER(_perf_##name##_count, SUN_RT, #name "_count"); \
1514 
1515 void MethodHandles::init_counters() {
1516   if (UsePerfData) {
1517     EXCEPTION_MARK;
1518 
1519     DO_COUNTERS(INIT_COUNTER)
1520 
1521     if (HAS_PENDING_EXCEPTION) {
1522       vm_exit_during_initialization("perf_mhn_init failed unexpectedly");
1523     }
1524   }
1525 }
1526 
1527 #undef INIT_COUNTER
1528 
1529 #define PRINT_COUNTER(name) {\
1530   jlong count = _perf_##name##_count->get_value(); \
1531   if (count > 0) { \
1532     st->print_cr("  %-40s = " JLONG_FORMAT_W(6) "us (elapsed) " JLONG_FORMAT_W(6) "us (thread) (" JLONG_FORMAT_W(5) " events)", #name, \
1533                  _perf_##name##_timer->elapsed_counter_value_us(), \
1534                  _perf_##name##_timer->thread_counter_value_us(), \
1535                  count); \
1536   }}
1537 
1538 void MethodHandles::print_counters_on(outputStream* st) {
1539   if (ProfileVMCalls && UsePerfData) {
1540     DO_COUNTERS(PRINT_COUNTER)
1541   } else {
1542     st->print_cr("  MHN:  no info (%s is disabled)", (UsePerfData ? "ProfileVMCalls" : "UsePerfData"));
1543   }
1544 }
1545 
1546 #undef PRINT_COUNTER
< prev index next >