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
|