< prev index next >

src/hotspot/share/prims/methodHandles.cpp

Print this page

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

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

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

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

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

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
































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

1309           }
1310         }
1311 
1312         // Store the pseudo-argument, and advance the pointers.
1313         buf->obj_at_put(pos++, pseudo_arg);
1314         ++start;
1315       }
1316     }
1317     // When we are done with this there may be regular arguments to process too.
1318   }
1319   Handle ifna(THREAD, JNIHandles::resolve(ifna_jh));
1320   caller->constants()->
1321     copy_bootstrap_arguments_at(bss_index_in_pool,
1322                                 start, end, buf, pos,
1323                                 (resolve == JNI_TRUE), ifna, CHECK);
1324 }
1325 JVM_END
1326 
1327 // It is called by a Cleaner object which ensures that dropped CallSites properly
1328 // deallocate their dependency information.
1329 JVM_ENTRY(void, MHN_clearCallSiteContext(JNIEnv* env, jobject igcls, jobject context_jh)) {
1330   Handle context(THREAD, JNIHandles::resolve_non_null(context_jh));
1331   DeoptimizationScope deopt_scope;
1332   {
1333     NoSafepointVerifier nsv;
1334     MutexLocker ml(THREAD, CodeCache_lock, Mutex::_no_safepoint_check_flag);
1335     DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context());
1336     deps.remove_and_mark_for_deoptimization_all_dependents(&deopt_scope);
1337     // This is assumed to be an 'atomic' operation by verification.
1338     // So keep it under lock for now.
1339     deopt_scope.deoptimize_marked();
1340   }
1341 }
1342 JVM_END
1343 
1344 /**
1345  * Throws a java/lang/UnsupportedOperationException unconditionally.
1346  * This is required by the specification of MethodHandle.invoke if
1347  * invoked directly.
1348  */
1349 JVM_ENTRY(jobject, MH_invoke_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
1350   THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invoke cannot be invoked reflectively");
1351   return nullptr;
1352 }
1353 JVM_END
1354 
1355 /**
1356  * Throws a java/lang/UnsupportedOperationException unconditionally.
1357  * This is required by the specification of MethodHandle.invokeExact if
1358  * invoked directly.
1359  */
1360 JVM_ENTRY(jobject, MH_invokeExact_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
1361   THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invokeExact cannot be invoked reflectively");
1362   return nullptr;
1363 }
1364 JVM_END
1365 
1366 /// JVM_RegisterMethodHandleMethods
1367 
1368 #define LANG "Ljava/lang/"
1369 #define JLINV "Ljava/lang/invoke/"
1370 
1371 #define OBJ   LANG "Object;"
1372 #define CLS   LANG "Class;"
1373 #define STRG  LANG "String;"
1374 #define CS    JLINV "CallSite;"
1375 #define MT    JLINV "MethodType;"
1376 #define MH    JLINV "MethodHandle;"
1377 #define MEM   JLINV "MemberName;"
1378 #define CTX   JLINV "MethodHandleNatives$CallSiteContext;"
1379 
1380 #define CC (char*)  /*cast a literal from (const char*)*/
1381 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
1382 
1383 // These are the native methods on java.lang.invoke.MethodHandleNatives.
1384 static JNINativeMethod MHN_methods[] = {
1385   {CC "init",                      CC "(" MEM "" OBJ ")V",                   FN_PTR(MHN_init_Mem)},
1386   {CC "expand",                    CC "(" MEM ")V",                          FN_PTR(MHN_expand_Mem)},
1387   {CC "resolve",                   CC "(" MEM "" CLS "IZ)" MEM,              FN_PTR(MHN_resolve_Mem)},

1388   //  static native int getNamedCon(int which, Object[] name)
1389   {CC "getNamedCon",               CC "(I[" OBJ ")I",                        FN_PTR(MHN_getNamedCon)},
1390   {CC "objectFieldOffset",         CC "(" MEM ")J",                          FN_PTR(MHN_objectFieldOffset)},
1391   {CC "setCallSiteTargetNormal",   CC "(" CS "" MH ")V",                     FN_PTR(MHN_setCallSiteTargetNormal)},
1392   {CC "setCallSiteTargetVolatile", CC "(" CS "" MH ")V",                     FN_PTR(MHN_setCallSiteTargetVolatile)},
1393   {CC "copyOutBootstrapArguments", CC "(" CLS "[III[" OBJ "IZ" OBJ ")V",     FN_PTR(MHN_copyOutBootstrapArguments)},
1394   {CC "clearCallSiteContext",      CC "(" CTX ")V",                          FN_PTR(MHN_clearCallSiteContext)},
1395   {CC "staticFieldOffset",         CC "(" MEM ")J",                          FN_PTR(MHN_staticFieldOffset)},
1396   {CC "staticFieldBase",           CC "(" MEM ")" OBJ,                        FN_PTR(MHN_staticFieldBase)},
1397   {CC "getMemberVMInfo",           CC "(" MEM ")" OBJ,                       FN_PTR(MHN_getMemberVMInfo)}
1398 };
1399 
1400 static JNINativeMethod MH_methods[] = {
1401   // UnsupportedOperationException throwers
1402   {CC "invoke",                    CC "([" OBJ ")" OBJ,                       FN_PTR(MH_invoke_UOE)},
1403   {CC "invokeExact",               CC "([" OBJ ")" OBJ,                       FN_PTR(MH_invokeExact_UOE)}
1404 };
1405 
1406 /**
1407  * This one function is exported, used by NativeLookup.
1408  */
1409 JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
1410   assert(!MethodHandles::enabled(), "must not be enabled");
1411   assert(vmClasses::MethodHandle_klass() != nullptr, "should be present");
1412 
1413   oop mirror = vmClasses::MethodHandle_klass()->java_mirror();
1414   jclass MH_class = (jclass) JNIHandles::make_local(THREAD, mirror);
1415 
1416   {
1417     ThreadToNativeFromVM ttnfv(thread);
1418 
1419     int status = env->RegisterNatives(MHN_class, MHN_methods, sizeof(MHN_methods)/sizeof(JNINativeMethod));
1420     guarantee(status == JNI_OK && !env->ExceptionOccurred(),
1421               "register java.lang.invoke.MethodHandleNative natives");
1422 
1423     status = env->RegisterNatives(MH_class, MH_methods, sizeof(MH_methods)/sizeof(JNINativeMethod));
1424     guarantee(status == JNI_OK && !env->ExceptionOccurred(),
1425               "register java.lang.invoke.MethodHandle natives");
1426   }
1427 
1428   log_debug(methodhandles, indy)("MethodHandle support loaded (using LambdaForms)");
1429 
1430   MethodHandles::set_enabled(true);
1431 }
1432 JVM_END
























































   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 "precompiled.hpp"
  26 #include "cds/cds_globals.hpp"
  27 #include "classfile/javaClasses.inline.hpp"
  28 #include "classfile/stringTable.hpp"
  29 #include "classfile/symbolTable.hpp"
  30 #include "classfile/systemDictionary.hpp"
  31 #include "classfile/systemDictionaryShared.hpp"
  32 #include "classfile/vmClasses.hpp"
  33 #include "code/codeCache.hpp"
  34 #include "code/dependencyContext.hpp"
  35 #include "compiler/compileBroker.hpp"
  36 #include "interpreter/interpreter.hpp"
  37 #include "interpreter/oopMapCache.hpp"
  38 #include "interpreter/linkResolver.hpp"
  39 #include "jvm_io.h"
  40 #include "logging/log.hpp"
  41 #include "logging/logStream.hpp"
  42 #include "memory/allocation.inline.hpp"
  43 #include "memory/oopFactory.hpp"
  44 #include "memory/resourceArea.hpp"
  45 #include "memory/universe.hpp"
  46 #include "oops/klass.inline.hpp"
  47 #include "oops/objArrayKlass.hpp"
  48 #include "oops/objArrayOop.inline.hpp"
  49 #include "oops/oop.inline.hpp"
  50 #include "oops/typeArrayOop.inline.hpp"
  51 #include "prims/methodHandles.hpp"
  52 #include "runtime/deoptimization.hpp"
  53 #include "runtime/fieldDescriptor.inline.hpp"
  54 #include "runtime/handles.inline.hpp"
  55 #include "runtime/interfaceSupport.inline.hpp"
  56 #include "runtime/java.hpp"
  57 #include "runtime/javaCalls.hpp"
  58 #include "runtime/jniHandles.inline.hpp"
  59 #include "runtime/perfData.inline.hpp"
  60 #include "runtime/timerTrace.hpp"
  61 #include "runtime/reflection.hpp"
  62 #include "runtime/safepointVerifiers.hpp"
  63 #include "runtime/signature.hpp"
  64 #include "runtime/stubRoutines.hpp"
  65 #include "sanitizers/leak.hpp"
  66 #include "services/management.hpp"
  67 #include "utilities/exceptions.hpp"
  68 
  69 
  70 /*
  71  * JSR 292 reference implementation: method handles
  72  * The JDK 7 reference implementation represented method handle
  73  * combinations as chains.  Each link in the chain had a "vmentry"
  74  * field which pointed at a bit of assembly code which performed
  75  * one transformation before dispatching to the next link in the chain.
  76  *
  77  * The current reference implementation pushes almost all code generation
  78  * responsibility to (trusted) Java code.  A method handle contains a
  79  * pointer to its "LambdaForm", which embodies all details of the method
  80  * handle's behavior.  The LambdaForm is a normal Java object, managed
  81  * by a runtime coded in Java.
  82  */
  83 
  84 bool MethodHandles::_enabled = false; // set true after successful native linkage
  85 MethodHandlesAdapterBlob* MethodHandles::_adapter_code = nullptr;
  86 

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

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

1346           }
1347         }
1348 
1349         // Store the pseudo-argument, and advance the pointers.
1350         buf->obj_at_put(pos++, pseudo_arg);
1351         ++start;
1352       }
1353     }
1354     // When we are done with this there may be regular arguments to process too.
1355   }
1356   Handle ifna(THREAD, JNIHandles::resolve(ifna_jh));
1357   caller->constants()->
1358     copy_bootstrap_arguments_at(bss_index_in_pool,
1359                                 start, end, buf, pos,
1360                                 (resolve == JNI_TRUE), ifna, CHECK);
1361 }
1362 JVM_END
1363 
1364 // It is called by a Cleaner object which ensures that dropped CallSites properly
1365 // deallocate their dependency information.
1366 JVM_ENTRY_PROF(void, MHN_clearCallSiteContext, MHN_clearCallSiteContext(JNIEnv* env, jobject igcls, jobject context_jh)) {
1367   Handle context(THREAD, JNIHandles::resolve_non_null(context_jh));
1368   DeoptimizationScope deopt_scope;
1369   {
1370     NoSafepointVerifier nsv;
1371     MutexLocker ml(THREAD, CodeCache_lock, Mutex::_no_safepoint_check_flag);
1372     DependencyContext deps = java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(context());
1373     deps.remove_and_mark_for_deoptimization_all_dependents(&deopt_scope);
1374     // This is assumed to be an 'atomic' operation by verification.
1375     // So keep it under lock for now.
1376     deopt_scope.deoptimize_marked();
1377   }
1378 }
1379 JVM_END
1380 
1381 /**
1382  * Throws a java/lang/UnsupportedOperationException unconditionally.
1383  * This is required by the specification of MethodHandle.invoke if
1384  * invoked directly.
1385  */
1386 JVM_ENTRY_PROF(jobject, MH_invoke_UOE, MH_invoke_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
1387   THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invoke cannot be invoked reflectively");
1388   return nullptr;
1389 }
1390 JVM_END
1391 
1392 /**
1393  * Throws a java/lang/UnsupportedOperationException unconditionally.
1394  * This is required by the specification of MethodHandle.invokeExact if
1395  * invoked directly.
1396  */
1397 JVM_ENTRY_PROF(jobject, MH_invokeExact_UOE, MH_invokeExact_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
1398   THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invokeExact cannot be invoked reflectively");
1399   return nullptr;
1400 }
1401 JVM_END
1402 
1403 /// JVM_RegisterMethodHandleMethods
1404 
1405 #define LANG "Ljava/lang/"
1406 #define JLINV "Ljava/lang/invoke/"
1407 
1408 #define OBJ   LANG "Object;"
1409 #define CLS   LANG "Class;"
1410 #define STRG  LANG "String;"
1411 #define CS    JLINV "CallSite;"
1412 #define MT    JLINV "MethodType;"
1413 #define MH    JLINV "MethodHandle;"
1414 #define MEM   JLINV "MemberName;"
1415 #define CTX   JLINV "MethodHandleNatives$CallSiteContext;"
1416 
1417 #define CC (char*)  /*cast a literal from (const char*)*/
1418 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
1419 
1420 // These are the native methods on java.lang.invoke.MethodHandleNatives.
1421 static JNINativeMethod MHN_methods[] = {
1422   {CC "init",                      CC "(" MEM "" OBJ ")V",                   FN_PTR(MHN_init_Mem)},
1423   {CC "expand",                    CC "(" MEM ")V",                          FN_PTR(MHN_expand_Mem)},
1424   {CC "resolve",                   CC "(" MEM "" CLS "IZ)" MEM,              FN_PTR(MHN_resolve_Mem)},
1425   {CC "checkArchivable",           CC "(" CLS ")V",                          FN_PTR(MHN_checkArchivable)},
1426   //  static native int getNamedCon(int which, Object[] name)
1427   {CC "getNamedCon",               CC "(I[" OBJ ")I",                        FN_PTR(MHN_getNamedCon)},
1428   {CC "objectFieldOffset",         CC "(" MEM ")J",                          FN_PTR(MHN_objectFieldOffset)},
1429   {CC "setCallSiteTargetNormal",   CC "(" CS "" MH ")V",                     FN_PTR(MHN_setCallSiteTargetNormal)},
1430   {CC "setCallSiteTargetVolatile", CC "(" CS "" MH ")V",                     FN_PTR(MHN_setCallSiteTargetVolatile)},
1431   {CC "copyOutBootstrapArguments", CC "(" CLS "[III[" OBJ "IZ" OBJ ")V",     FN_PTR(MHN_copyOutBootstrapArguments)},
1432   {CC "clearCallSiteContext",      CC "(" CTX ")V",                          FN_PTR(MHN_clearCallSiteContext)},
1433   {CC "staticFieldOffset",         CC "(" MEM ")J",                          FN_PTR(MHN_staticFieldOffset)},
1434   {CC "staticFieldBase",           CC "(" MEM ")" OBJ,                        FN_PTR(MHN_staticFieldBase)},
1435   {CC "getMemberVMInfo",           CC "(" MEM ")" OBJ,                       FN_PTR(MHN_getMemberVMInfo)}
1436 };
1437 
1438 static JNINativeMethod MH_methods[] = {
1439   // UnsupportedOperationException throwers
1440   {CC "invoke",                    CC "([" OBJ ")" OBJ,                       FN_PTR(MH_invoke_UOE)},
1441   {CC "invokeExact",               CC "([" OBJ ")" OBJ,                       FN_PTR(MH_invokeExact_UOE)}
1442 };
1443 
1444 /**
1445  * This one function is exported, used by NativeLookup.
1446  */
1447 JVM_ENTRY_PROF(void, JVM_RegisterMethodHandleMethods, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
1448   assert(!MethodHandles::enabled(), "must not be enabled");
1449   assert(vmClasses::MethodHandle_klass() != nullptr, "should be present");
1450 
1451   oop mirror = vmClasses::MethodHandle_klass()->java_mirror();
1452   jclass MH_class = (jclass) JNIHandles::make_local(THREAD, mirror);
1453 
1454   {
1455     ThreadToNativeFromVM ttnfv(thread);
1456 
1457     int status = env->RegisterNatives(MHN_class, MHN_methods, sizeof(MHN_methods)/sizeof(JNINativeMethod));
1458     guarantee(status == JNI_OK && !env->ExceptionOccurred(),
1459               "register java.lang.invoke.MethodHandleNative natives");
1460 
1461     status = env->RegisterNatives(MH_class, MH_methods, sizeof(MH_methods)/sizeof(JNINativeMethod));
1462     guarantee(status == JNI_OK && !env->ExceptionOccurred(),
1463               "register java.lang.invoke.MethodHandle natives");
1464   }
1465 
1466   log_debug(methodhandles, indy)("MethodHandle support loaded (using LambdaForms)");
1467 
1468   MethodHandles::set_enabled(true);
1469 }
1470 JVM_END
1471 
1472 #define DO_COUNTERS(macro)             \
1473   macro(MHN_init_Mem)                  \
1474   macro(MHN_expand_Mem)                \
1475   macro(MHN_resolve_Mem)               \
1476   macro(MHN_checkArchivable)           \
1477   macro(MHN_getNamedCon)               \
1478   macro(MHN_objectFieldOffset)         \
1479   macro(MHN_setCallSiteTargetNormal)   \
1480   macro(MHN_setCallSiteTargetVolatile) \
1481   macro(MHN_copyOutBootstrapArguments) \
1482   macro(MHN_clearCallSiteContext)      \
1483   macro(MHN_staticFieldOffset)         \
1484   macro(MHN_staticFieldBase)           \
1485   macro(MHN_getMemberVMInfo)           \
1486   macro(MH_invoke_UOE)                 \
1487   macro(MH_invokeExact_UOE)            \
1488   macro(JVM_RegisterMethodHandleMethods)
1489 
1490 #define INIT_COUNTER(name) \
1491     NEWPERFTICKCOUNTERS(_perf_##name##_timer, SUN_RT, #name); \
1492     NEWPERFEVENTCOUNTER(_perf_##name##_count, SUN_RT, #name "_count"); \
1493 
1494 void MethodHandles::init_counters() {
1495   if (UsePerfData) {
1496     EXCEPTION_MARK;
1497 
1498     DO_COUNTERS(INIT_COUNTER)
1499 
1500     if (HAS_PENDING_EXCEPTION) {
1501       vm_exit_during_initialization("perf_mhn_init failed unexpectedly");
1502     }
1503   }
1504 }
1505 
1506 #undef INIT_COUNTER
1507 
1508 #define PRINT_COUNTER(name) {\
1509   jlong count = _perf_##name##_count->get_value(); \
1510   if (count > 0) { \
1511     st->print_cr("  %-40s = %4ldms (elapsed) %4ldms (thread) (%5ld events)", #name, \
1512                  _perf_##name##_timer->elapsed_counter_value_ms(), \
1513                  _perf_##name##_timer->thread_counter_value_ms(), \
1514                  count); \
1515   }}
1516 
1517 void MethodHandles::print_counters_on(outputStream* st) {
1518   if (ProfileVMCalls && UsePerfData) {
1519     DO_COUNTERS(PRINT_COUNTER)
1520   } else {
1521     st->print_cr("  MHN:  no info (%s is disabled)", (UsePerfData ? "ProfileVMCalls" : "UsePerfData"));
1522   }
1523 }
1524 
1525 #undef PRINT_COUNTER
< prev index next >