< prev index next >

src/hotspot/share/prims/methodHandles.cpp

Print this page
rev 49420 : 8200238: Reduce number of exceptions created when calling MemberName$Factory::resolveOrNull
Reviewed-by: lfoltan, acorn


 287     vmindex = Method::nonvirtual_vtable_index;
 288     if (m->is_static()) {
 289       flags |= IS_METHOD      | (JVM_REF_invokeStatic  << REFERENCE_KIND_SHIFT);
 290     } else if (m->is_initializer()) {
 291       flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
 292     } else {
 293       flags |= IS_METHOD      | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
 294     }
 295     break;
 296 
 297   default:  assert(false, "bad CallInfo");  return NULL;
 298   }
 299 
 300   // @CallerSensitive annotation detected
 301   if (m->caller_sensitive()) {
 302     flags |= CALLER_SENSITIVE;
 303   }
 304 
 305   Handle resolved_method = info.resolved_method_name();
 306   assert(java_lang_invoke_ResolvedMethodName::vmtarget(resolved_method()) == m(),
 307          "Should not change after link resolultion");
 308 
 309   oop mname_oop = mname();
 310   java_lang_invoke_MemberName::set_flags  (mname_oop, flags);
 311   java_lang_invoke_MemberName::set_method (mname_oop, resolved_method());
 312   java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex);   // vtable/itable index
 313   java_lang_invoke_MemberName::set_clazz  (mname_oop, m_klass->java_mirror());
 314   // Note:  name and type can be lazily computed by resolve_MemberName,
 315   // if Java code needs them as resolved String and MethodType objects.
 316   // If relevant, the vtable or itable value is stored as vmindex.
 317   // This is done eagerly, since it is readily available without
 318   // constructing any new objects.
 319   return mname();
 320 }
 321 
 322 oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) {
 323   int flags = (jushort)( fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS );
 324   flags |= IS_FIELD | ((fd.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT);
 325   if (is_setter)  flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT);
 326   int vmindex        = fd.offset();  // determines the field uniquely when combined with static bit
 327 


1168 
1169 // void init(MemberName self, AccessibleObject ref)
1170 JVM_ENTRY(void, MHN_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) {
1171   if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); }
1172   if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); }
1173   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
1174   Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
1175   MethodHandles::init_MemberName(mname, target, CHECK);
1176 }
1177 JVM_END
1178 
1179 // void expand(MemberName self)
1180 JVM_ENTRY(void, MHN_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) {
1181   if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); }
1182   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
1183   MethodHandles::expand_MemberName(mname, 0, CHECK);
1184 }
1185 JVM_END
1186 
1187 // void resolve(MemberName self, Class<?> caller)
1188 JVM_ENTRY(jobject, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) {

1189   if (mname_jh == NULL) { THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "mname is null"); }
1190   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
1191 
1192   // The trusted Java code that calls this method should already have performed
1193   // access checks on behalf of the given caller.  But, we can verify this.
1194   if (VerifyMethodHandles && caller_jh != NULL &&
1195       java_lang_invoke_MemberName::clazz(mname()) != NULL) {
1196     Klass* reference_klass = java_lang_Class::as_Klass(java_lang_invoke_MemberName::clazz(mname()));
1197     if (reference_klass != NULL && reference_klass->is_objArray_klass()) {
1198       reference_klass = ObjArrayKlass::cast(reference_klass)->bottom_klass();
1199     }
1200 
1201     // Reflection::verify_class_access can only handle instance classes.
1202     if (reference_klass != NULL && reference_klass->is_instance_klass()) {
1203       // Emulate LinkResolver::check_klass_accessability.
1204       Klass* caller = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(caller_jh));
1205       if (caller != SystemDictionary::Object_klass()
1206           && Reflection::verify_class_access(caller,
1207                                              InstanceKlass::cast(reference_klass),
1208                                              true) != Reflection::ACCESS_OK) {
1209         THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), reference_klass->external_name());
1210       }
1211     }
1212   }
1213 
1214   Klass* caller = caller_jh == NULL ? NULL :
1215                      java_lang_Class::as_Klass(JNIHandles::resolve_non_null(caller_jh));
1216   Handle resolved = MethodHandles::resolve_MemberName(mname, caller, CHECK_NULL);
1217 
1218   if (resolved.is_null()) {
1219     int flags = java_lang_invoke_MemberName::flags(mname());
1220     int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
1221     if (!MethodHandles::ref_kind_is_valid(ref_kind)) {
1222       THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "obsolete MemberName format");
1223     }



1224     if ((flags & ALL_KINDS) == IS_FIELD) {
1225       THROW_MSG_NULL(vmSymbols::java_lang_NoSuchFieldError(), "field resolution failed");
1226     } else if ((flags & ALL_KINDS) == IS_METHOD ||
1227                (flags & ALL_KINDS) == IS_CONSTRUCTOR) {
1228       THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(), "method resolution failed");
1229     } else {
1230       THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "resolution failed");
1231     }
1232   }
1233 
1234   return JNIHandles::make_local(THREAD, resolved());
1235 }
1236 JVM_END
1237 
1238 static jlong find_member_field_offset(oop mname, bool must_be_static, TRAPS) {
1239   if (mname == NULL ||
1240       java_lang_invoke_MemberName::clazz(mname) == NULL) {
1241     THROW_MSG_0(vmSymbols::java_lang_InternalError(), "mname not resolved");
1242   } else {
1243     int flags = java_lang_invoke_MemberName::flags(mname);


1495 
1496 #define LANG "Ljava/lang/"
1497 #define JLINV "Ljava/lang/invoke/"
1498 
1499 #define OBJ   LANG "Object;"
1500 #define CLS   LANG "Class;"
1501 #define STRG  LANG "String;"
1502 #define CS    JLINV "CallSite;"
1503 #define MT    JLINV "MethodType;"
1504 #define MH    JLINV "MethodHandle;"
1505 #define MEM   JLINV "MemberName;"
1506 #define CTX   JLINV "MethodHandleNatives$CallSiteContext;"
1507 
1508 #define CC (char*)  /*cast a literal from (const char*)*/
1509 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
1510 
1511 // These are the native methods on java.lang.invoke.MethodHandleNatives.
1512 static JNINativeMethod MHN_methods[] = {
1513   {CC "init",                      CC "(" MEM "" OBJ ")V",                   FN_PTR(MHN_init_Mem)},
1514   {CC "expand",                    CC "(" MEM ")V",                          FN_PTR(MHN_expand_Mem)},
1515   {CC "resolve",                   CC "(" MEM "" CLS ")" MEM,                FN_PTR(MHN_resolve_Mem)},
1516   //  static native int getNamedCon(int which, Object[] name)
1517   {CC "getNamedCon",               CC "(I[" OBJ ")I",                        FN_PTR(MHN_getNamedCon)},
1518   //  static native int getMembers(Class<?> defc, String matchName, String matchSig,
1519   //          int matchFlags, Class<?> caller, int skip, MemberName[] results);
1520   {CC "getMembers",                CC "(" CLS "" STRG "" STRG "I" CLS "I[" MEM ")I", FN_PTR(MHN_getMembers)},
1521   {CC "objectFieldOffset",         CC "(" MEM ")J",                          FN_PTR(MHN_objectFieldOffset)},
1522   {CC "setCallSiteTargetNormal",   CC "(" CS "" MH ")V",                     FN_PTR(MHN_setCallSiteTargetNormal)},
1523   {CC "setCallSiteTargetVolatile", CC "(" CS "" MH ")V",                     FN_PTR(MHN_setCallSiteTargetVolatile)},
1524   {CC "copyOutBootstrapArguments", CC "(" CLS "[III[" OBJ "IZ" OBJ ")V",     FN_PTR(MHN_copyOutBootstrapArguments)},
1525   {CC "clearCallSiteContext",      CC "(" CTX ")V",                          FN_PTR(MHN_clearCallSiteContext)},
1526   {CC "staticFieldOffset",         CC "(" MEM ")J",                          FN_PTR(MHN_staticFieldOffset)},
1527   {CC "staticFieldBase",           CC "(" MEM ")" OBJ,                        FN_PTR(MHN_staticFieldBase)},
1528   {CC "getMemberVMInfo",           CC "(" MEM ")" OBJ,                        FN_PTR(MHN_getMemberVMInfo)}
1529 };
1530 
1531 static JNINativeMethod MH_methods[] = {
1532   // UnsupportedOperationException throwers
1533   {CC "invoke",                    CC "([" OBJ ")" OBJ,                       FN_PTR(MH_invoke_UOE)},
1534   {CC "invokeExact",               CC "([" OBJ ")" OBJ,                       FN_PTR(MH_invokeExact_UOE)}
1535 };




 287     vmindex = Method::nonvirtual_vtable_index;
 288     if (m->is_static()) {
 289       flags |= IS_METHOD      | (JVM_REF_invokeStatic  << REFERENCE_KIND_SHIFT);
 290     } else if (m->is_initializer()) {
 291       flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
 292     } else {
 293       flags |= IS_METHOD      | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
 294     }
 295     break;
 296 
 297   default:  assert(false, "bad CallInfo");  return NULL;
 298   }
 299 
 300   // @CallerSensitive annotation detected
 301   if (m->caller_sensitive()) {
 302     flags |= CALLER_SENSITIVE;
 303   }
 304 
 305   Handle resolved_method = info.resolved_method_name();
 306   assert(java_lang_invoke_ResolvedMethodName::vmtarget(resolved_method()) == m(),
 307          "Should not change after link resolution");
 308 
 309   oop mname_oop = mname();
 310   java_lang_invoke_MemberName::set_flags  (mname_oop, flags);
 311   java_lang_invoke_MemberName::set_method (mname_oop, resolved_method());
 312   java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex);   // vtable/itable index
 313   java_lang_invoke_MemberName::set_clazz  (mname_oop, m_klass->java_mirror());
 314   // Note:  name and type can be lazily computed by resolve_MemberName,
 315   // if Java code needs them as resolved String and MethodType objects.
 316   // If relevant, the vtable or itable value is stored as vmindex.
 317   // This is done eagerly, since it is readily available without
 318   // constructing any new objects.
 319   return mname();
 320 }
 321 
 322 oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) {
 323   int flags = (jushort)( fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS );
 324   flags |= IS_FIELD | ((fd.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT);
 325   if (is_setter)  flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT);
 326   int vmindex        = fd.offset();  // determines the field uniquely when combined with static bit
 327 


1168 
1169 // void init(MemberName self, AccessibleObject ref)
1170 JVM_ENTRY(void, MHN_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) {
1171   if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); }
1172   if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); }
1173   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
1174   Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
1175   MethodHandles::init_MemberName(mname, target, CHECK);
1176 }
1177 JVM_END
1178 
1179 // void expand(MemberName self)
1180 JVM_ENTRY(void, MHN_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) {
1181   if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); }
1182   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
1183   MethodHandles::expand_MemberName(mname, 0, CHECK);
1184 }
1185 JVM_END
1186 
1187 // void resolve(MemberName self, Class<?> caller)
1188 JVM_ENTRY(jobject, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh,
1189     jboolean speculative_resolve)) {
1190   if (mname_jh == NULL) { THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "mname is null"); }
1191   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
1192 
1193   // The trusted Java code that calls this method should already have performed
1194   // access checks on behalf of the given caller.  But, we can verify this.
1195   if (VerifyMethodHandles && caller_jh != NULL &&
1196       java_lang_invoke_MemberName::clazz(mname()) != NULL) {
1197     Klass* reference_klass = java_lang_Class::as_Klass(java_lang_invoke_MemberName::clazz(mname()));
1198     if (reference_klass != NULL && reference_klass->is_objArray_klass()) {
1199       reference_klass = ObjArrayKlass::cast(reference_klass)->bottom_klass();
1200     }
1201 
1202     // Reflection::verify_class_access can only handle instance classes.
1203     if (reference_klass != NULL && reference_klass->is_instance_klass()) {
1204       // Emulate LinkResolver::check_klass_accessability.
1205       Klass* caller = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(caller_jh));
1206       if (caller != SystemDictionary::Object_klass()
1207           && Reflection::verify_class_access(caller,
1208                                              InstanceKlass::cast(reference_klass),
1209                                              true) != Reflection::ACCESS_OK) {
1210         THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), reference_klass->external_name());
1211       }
1212     }
1213   }
1214 
1215   Klass* caller = caller_jh == NULL ? NULL :
1216                      java_lang_Class::as_Klass(JNIHandles::resolve_non_null(caller_jh));
1217   Handle resolved = MethodHandles::resolve_MemberName(mname, caller, CHECK_NULL);
1218 
1219   if (resolved.is_null()) {
1220     int flags = java_lang_invoke_MemberName::flags(mname());
1221     int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
1222     if (!MethodHandles::ref_kind_is_valid(ref_kind)) {
1223       THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "obsolete MemberName format");
1224     }
1225     if (speculative_resolve) {
1226       return NULL;
1227     }
1228     if ((flags & ALL_KINDS) == IS_FIELD) {
1229       THROW_MSG_NULL(vmSymbols::java_lang_NoSuchFieldError(), "field resolution failed");
1230     } else if ((flags & ALL_KINDS) == IS_METHOD ||
1231                (flags & ALL_KINDS) == IS_CONSTRUCTOR) {
1232       THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(), "method resolution failed");
1233     } else {
1234       THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "resolution failed");
1235     }
1236   }
1237 
1238   return JNIHandles::make_local(THREAD, resolved());
1239 }
1240 JVM_END
1241 
1242 static jlong find_member_field_offset(oop mname, bool must_be_static, TRAPS) {
1243   if (mname == NULL ||
1244       java_lang_invoke_MemberName::clazz(mname) == NULL) {
1245     THROW_MSG_0(vmSymbols::java_lang_InternalError(), "mname not resolved");
1246   } else {
1247     int flags = java_lang_invoke_MemberName::flags(mname);


1499 
1500 #define LANG "Ljava/lang/"
1501 #define JLINV "Ljava/lang/invoke/"
1502 
1503 #define OBJ   LANG "Object;"
1504 #define CLS   LANG "Class;"
1505 #define STRG  LANG "String;"
1506 #define CS    JLINV "CallSite;"
1507 #define MT    JLINV "MethodType;"
1508 #define MH    JLINV "MethodHandle;"
1509 #define MEM   JLINV "MemberName;"
1510 #define CTX   JLINV "MethodHandleNatives$CallSiteContext;"
1511 
1512 #define CC (char*)  /*cast a literal from (const char*)*/
1513 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
1514 
1515 // These are the native methods on java.lang.invoke.MethodHandleNatives.
1516 static JNINativeMethod MHN_methods[] = {
1517   {CC "init",                      CC "(" MEM "" OBJ ")V",                   FN_PTR(MHN_init_Mem)},
1518   {CC "expand",                    CC "(" MEM ")V",                          FN_PTR(MHN_expand_Mem)},
1519   {CC "resolve",                   CC "(" MEM "" CLS "Z)" MEM,               FN_PTR(MHN_resolve_Mem)},
1520   //  static native int getNamedCon(int which, Object[] name)
1521   {CC "getNamedCon",               CC "(I[" OBJ ")I",                        FN_PTR(MHN_getNamedCon)},
1522   //  static native int getMembers(Class<?> defc, String matchName, String matchSig,
1523   //          int matchFlags, Class<?> caller, int skip, MemberName[] results);
1524   {CC "getMembers",                CC "(" CLS "" STRG "" STRG "I" CLS "I[" MEM ")I", FN_PTR(MHN_getMembers)},
1525   {CC "objectFieldOffset",         CC "(" MEM ")J",                          FN_PTR(MHN_objectFieldOffset)},
1526   {CC "setCallSiteTargetNormal",   CC "(" CS "" MH ")V",                     FN_PTR(MHN_setCallSiteTargetNormal)},
1527   {CC "setCallSiteTargetVolatile", CC "(" CS "" MH ")V",                     FN_PTR(MHN_setCallSiteTargetVolatile)},
1528   {CC "copyOutBootstrapArguments", CC "(" CLS "[III[" OBJ "IZ" OBJ ")V",     FN_PTR(MHN_copyOutBootstrapArguments)},
1529   {CC "clearCallSiteContext",      CC "(" CTX ")V",                          FN_PTR(MHN_clearCallSiteContext)},
1530   {CC "staticFieldOffset",         CC "(" MEM ")J",                          FN_PTR(MHN_staticFieldOffset)},
1531   {CC "staticFieldBase",           CC "(" MEM ")" OBJ,                        FN_PTR(MHN_staticFieldBase)},
1532   {CC "getMemberVMInfo",           CC "(" MEM ")" OBJ,                        FN_PTR(MHN_getMemberVMInfo)}
1533 };
1534 
1535 static JNINativeMethod MH_methods[] = {
1536   // UnsupportedOperationException throwers
1537   {CC "invoke",                    CC "([" OBJ ")" OBJ,                       FN_PTR(MH_invoke_UOE)},
1538   {CC "invokeExact",               CC "([" OBJ ")" OBJ,                       FN_PTR(MH_invokeExact_UOE)}
1539 };


< prev index next >