< 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 


 663     return java_lang_Class::primitive_mirror(bt);
 664   }
 665   // Here are some more short cuts for common types.
 666   // They are optional, since reference types can be resolved lazily.
 667   if (bt == T_OBJECT) {
 668     if (s == vmSymbols::object_signature()) {
 669       return object_java_mirror();
 670     } else if (s == vmSymbols::class_signature()) {
 671       return SystemDictionary::Class_klass()->java_mirror();
 672     } else if (s == vmSymbols::string_signature()) {
 673       return SystemDictionary::String_klass()->java_mirror();
 674     }
 675   }
 676   return NULL;
 677 }
 678 
 679 
 680 // An unresolved member name is a mere symbolic reference.
 681 // Resolving it plants a vmtarget/vmindex in it,
 682 // which refers directly to JVM internals.
 683 Handle MethodHandles::resolve_MemberName(Handle mname, Klass* caller, TRAPS) {

 684   Handle empty;
 685   assert(java_lang_invoke_MemberName::is_instance(mname()), "");
 686 
 687   if (java_lang_invoke_MemberName::vmtarget(mname()) != NULL) {
 688     // Already resolved.
 689     DEBUG_ONLY(int vmindex = java_lang_invoke_MemberName::vmindex(mname()));
 690     assert(vmindex >= Method::nonvirtual_vtable_index, "");
 691     return mname;
 692   }
 693 
 694   Handle defc_oop(THREAD, java_lang_invoke_MemberName::clazz(mname()));
 695   Handle name_str(THREAD, java_lang_invoke_MemberName::name( mname()));
 696   Handle type_str(THREAD, java_lang_invoke_MemberName::type( mname()));
 697   int    flags    =       java_lang_invoke_MemberName::flags(mname());
 698   int    ref_kind =       (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
 699   if (!ref_kind_is_valid(ref_kind)) {
 700     THROW_MSG_(vmSymbols::java_lang_InternalError(), "obsolete MemberName format", empty);
 701   }
 702 
 703   DEBUG_ONLY(int old_vmindex);


 762         assert(!HAS_PENDING_EXCEPTION, "");
 763         if (ref_kind == JVM_REF_invokeStatic) {
 764           LinkResolver::resolve_static_call(result,
 765                         link_info, false, THREAD);
 766         } else if (ref_kind == JVM_REF_invokeInterface) {
 767           LinkResolver::resolve_interface_call(result, Handle(), defc,
 768                         link_info, false, THREAD);
 769         } else if (mh_invoke_id != vmIntrinsics::_none) {
 770           assert(!is_signature_polymorphic_static(mh_invoke_id), "");
 771           LinkResolver::resolve_handle_call(result, link_info, THREAD);
 772         } else if (ref_kind == JVM_REF_invokeSpecial) {
 773           LinkResolver::resolve_special_call(result, Handle(),
 774                         link_info, THREAD);
 775         } else if (ref_kind == JVM_REF_invokeVirtual) {
 776           LinkResolver::resolve_virtual_call(result, Handle(), defc,
 777                         link_info, false, THREAD);
 778         } else {
 779           assert(false, "ref_kind=%d", ref_kind);
 780         }
 781         if (HAS_PENDING_EXCEPTION) {



 782           return empty;
 783         }
 784       }
 785       if (result.resolved_appendix().not_null()) {
 786         // The resolved MemberName must not be accompanied by an appendix argument,
 787         // since there is no way to bind this value into the MemberName.
 788         // Caller is responsible to prevent this from happening.
 789         THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty);
 790       }
 791       result.set_resolved_method_name(CHECK_(empty));
 792       oop mname2 = init_method_MemberName(mname, result);
 793       return Handle(THREAD, mname2);
 794     }
 795   case IS_CONSTRUCTOR:
 796     {
 797       CallInfo result;
 798       LinkInfo link_info(defc, name, type, caller, access_check);
 799       {
 800         assert(!HAS_PENDING_EXCEPTION, "");
 801         if (name == vmSymbols::object_initializer_name()) {
 802           LinkResolver::resolve_special_call(result, Handle(), link_info, THREAD);
 803         } else {
 804           break;                // will throw after end of switch
 805         }
 806         if (HAS_PENDING_EXCEPTION) {



 807           return empty;
 808         }
 809       }
 810       assert(result.is_statically_bound(), "");
 811       result.set_resolved_method_name(CHECK_(empty));
 812       oop mname2 = init_method_MemberName(mname, result);
 813       return Handle(THREAD, mname2);
 814     }
 815   case IS_FIELD:
 816     {
 817       fieldDescriptor result; // find_field initializes fd if found
 818       {
 819         assert(!HAS_PENDING_EXCEPTION, "");
 820         LinkInfo link_info(defc, name, type, caller, LinkInfo::skip_access_check);
 821         LinkResolver::resolve_field(result, link_info, Bytecodes::_nop, false, THREAD);
 822         if (HAS_PENDING_EXCEPTION) {



 823           return empty;
 824         }
 825       }
 826       oop mname2 = init_field_MemberName(mname, result, ref_kind_is_setter(ref_kind));
 827       return Handle(THREAD, mname2);
 828     }
 829   default:
 830     THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format", empty);
 831   }
 832 
 833   return empty;
 834 }
 835 
 836 // Conversely, a member name which is only initialized from JVM internals
 837 // may have null defc, name, and type fields.
 838 // Resolving it plants a vmtarget/vmindex in it,
 839 // which refers directly to JVM internals.
 840 void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) {
 841   assert(java_lang_invoke_MemberName::is_instance(mname()), "");
 842 


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 


 663     return java_lang_Class::primitive_mirror(bt);
 664   }
 665   // Here are some more short cuts for common types.
 666   // They are optional, since reference types can be resolved lazily.
 667   if (bt == T_OBJECT) {
 668     if (s == vmSymbols::object_signature()) {
 669       return object_java_mirror();
 670     } else if (s == vmSymbols::class_signature()) {
 671       return SystemDictionary::Class_klass()->java_mirror();
 672     } else if (s == vmSymbols::string_signature()) {
 673       return SystemDictionary::String_klass()->java_mirror();
 674     }
 675   }
 676   return NULL;
 677 }
 678 
 679 
 680 // An unresolved member name is a mere symbolic reference.
 681 // Resolving it plants a vmtarget/vmindex in it,
 682 // which refers directly to JVM internals.
 683 Handle MethodHandles::resolve_MemberName(Handle mname, Klass* caller,
 684                                          bool speculative_resolve, TRAPS) {
 685   Handle empty;
 686   assert(java_lang_invoke_MemberName::is_instance(mname()), "");
 687 
 688   if (java_lang_invoke_MemberName::vmtarget(mname()) != NULL) {
 689     // Already resolved.
 690     DEBUG_ONLY(int vmindex = java_lang_invoke_MemberName::vmindex(mname()));
 691     assert(vmindex >= Method::nonvirtual_vtable_index, "");
 692     return mname;
 693   }
 694 
 695   Handle defc_oop(THREAD, java_lang_invoke_MemberName::clazz(mname()));
 696   Handle name_str(THREAD, java_lang_invoke_MemberName::name( mname()));
 697   Handle type_str(THREAD, java_lang_invoke_MemberName::type( mname()));
 698   int    flags    =       java_lang_invoke_MemberName::flags(mname());
 699   int    ref_kind =       (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
 700   if (!ref_kind_is_valid(ref_kind)) {
 701     THROW_MSG_(vmSymbols::java_lang_InternalError(), "obsolete MemberName format", empty);
 702   }
 703 
 704   DEBUG_ONLY(int old_vmindex);


 763         assert(!HAS_PENDING_EXCEPTION, "");
 764         if (ref_kind == JVM_REF_invokeStatic) {
 765           LinkResolver::resolve_static_call(result,
 766                         link_info, false, THREAD);
 767         } else if (ref_kind == JVM_REF_invokeInterface) {
 768           LinkResolver::resolve_interface_call(result, Handle(), defc,
 769                         link_info, false, THREAD);
 770         } else if (mh_invoke_id != vmIntrinsics::_none) {
 771           assert(!is_signature_polymorphic_static(mh_invoke_id), "");
 772           LinkResolver::resolve_handle_call(result, link_info, THREAD);
 773         } else if (ref_kind == JVM_REF_invokeSpecial) {
 774           LinkResolver::resolve_special_call(result, Handle(),
 775                         link_info, THREAD);
 776         } else if (ref_kind == JVM_REF_invokeVirtual) {
 777           LinkResolver::resolve_virtual_call(result, Handle(), defc,
 778                         link_info, false, THREAD);
 779         } else {
 780           assert(false, "ref_kind=%d", ref_kind);
 781         }
 782         if (HAS_PENDING_EXCEPTION) {
 783           if (speculative_resolve) {
 784             CLEAR_PENDING_EXCEPTION;
 785           }
 786           return empty;
 787         }
 788       }
 789       if (result.resolved_appendix().not_null()) {
 790         // The resolved MemberName must not be accompanied by an appendix argument,
 791         // since there is no way to bind this value into the MemberName.
 792         // Caller is responsible to prevent this from happening.
 793         THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty);
 794       }
 795       result.set_resolved_method_name(CHECK_(empty));
 796       oop mname2 = init_method_MemberName(mname, result);
 797       return Handle(THREAD, mname2);
 798     }
 799   case IS_CONSTRUCTOR:
 800     {
 801       CallInfo result;
 802       LinkInfo link_info(defc, name, type, caller, access_check);
 803       {
 804         assert(!HAS_PENDING_EXCEPTION, "");
 805         if (name == vmSymbols::object_initializer_name()) {
 806           LinkResolver::resolve_special_call(result, Handle(), link_info, THREAD);
 807         } else {
 808           break;                // will throw after end of switch
 809         }
 810         if (HAS_PENDING_EXCEPTION) {
 811           if (speculative_resolve) {
 812             CLEAR_PENDING_EXCEPTION;
 813           }
 814           return empty;
 815         }
 816       }
 817       assert(result.is_statically_bound(), "");
 818       result.set_resolved_method_name(CHECK_(empty));
 819       oop mname2 = init_method_MemberName(mname, result);
 820       return Handle(THREAD, mname2);
 821     }
 822   case IS_FIELD:
 823     {
 824       fieldDescriptor result; // find_field initializes fd if found
 825       {
 826         assert(!HAS_PENDING_EXCEPTION, "");
 827         LinkInfo link_info(defc, name, type, caller, LinkInfo::skip_access_check);
 828         LinkResolver::resolve_field(result, link_info, Bytecodes::_nop, false, THREAD);
 829         if (HAS_PENDING_EXCEPTION) {
 830           if (speculative_resolve) {
 831             CLEAR_PENDING_EXCEPTION;
 832           }
 833           return empty;
 834         }
 835       }
 836       oop mname2 = init_field_MemberName(mname, result, ref_kind_is_setter(ref_kind));
 837       return Handle(THREAD, mname2);
 838     }
 839   default:
 840     THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format", empty);
 841   }
 842 
 843   return empty;
 844 }
 845 
 846 // Conversely, a member name which is only initialized from JVM internals
 847 // may have null defc, name, and type fields.
 848 // Resolving it plants a vmtarget/vmindex in it,
 849 // which refers directly to JVM internals.
 850 void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) {
 851   assert(java_lang_invoke_MemberName::is_instance(mname()), "");
 852 


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


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


< prev index next >