1303 |
1303 |
1304 void MethodHandles::verify_vmargslot(Handle mh, int argnum, int argslot, TRAPS) { |
1304 void MethodHandles::verify_vmargslot(Handle mh, int argnum, int argslot, TRAPS) { |
1305 // Verify that argslot points at the given argnum. |
1305 // Verify that argslot points at the given argnum. |
1306 int check_slot = argument_slot(java_lang_invoke_MethodHandle::type(mh()), argnum); |
1306 int check_slot = argument_slot(java_lang_invoke_MethodHandle::type(mh()), argnum); |
1307 if (argslot != check_slot || argslot < 0) { |
1307 if (argslot != check_slot || argslot < 0) { |
|
1308 ResourceMark rm; |
1308 const char* fmt = "for argnum of %d, vmargslot is %d, should be %d"; |
1309 const char* fmt = "for argnum of %d, vmargslot is %d, should be %d"; |
1309 size_t msglen = strlen(fmt) + 3*11 + 1; |
1310 size_t msglen = strlen(fmt) + 3*11 + 1; |
1310 char* msg = NEW_RESOURCE_ARRAY(char, msglen); |
1311 char* msg = NEW_RESOURCE_ARRAY(char, msglen); |
1311 jio_snprintf(msg, msglen, fmt, argnum, argslot, check_slot); |
1312 jio_snprintf(msg, msglen, fmt, argnum, argslot, check_slot); |
1312 THROW_MSG(vmSymbols::java_lang_InternalError(), msg); |
1313 THROW_MSG(vmSymbols::java_lang_InternalError(), msg); |
1827 // are binding the receiver, cut out the middle-man. |
1828 // are binding the receiver, cut out the middle-man. |
1828 // Do this by decoding the DMH and using its methodOop directly as vmtarget. |
1829 // Do this by decoding the DMH and using its methodOop directly as vmtarget. |
1829 bool direct_to_method = false; |
1830 bool direct_to_method = false; |
1830 if (OptimizeMethodHandles && |
1831 if (OptimizeMethodHandles && |
1831 target->klass() == SystemDictionary::DirectMethodHandle_klass() && |
1832 target->klass() == SystemDictionary::DirectMethodHandle_klass() && |
|
1833 (argnum != 0 || java_lang_invoke_BoundMethodHandle::argument(mh()) != NULL) && |
1832 (argnum == 0 || java_lang_invoke_DirectMethodHandle::vmindex(target()) < 0)) { |
1834 (argnum == 0 || java_lang_invoke_DirectMethodHandle::vmindex(target()) < 0)) { |
1833 KlassHandle receiver_limit; int decode_flags = 0; |
1835 KlassHandle receiver_limit; int decode_flags = 0; |
1834 methodHandle m = decode_method(target(), receiver_limit, decode_flags); |
1836 methodHandle m = decode_method(target(), receiver_limit, decode_flags); |
1835 if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "DMH failed to decode"); } |
1837 if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "DMH failed to decode"); } |
1836 DEBUG_ONLY(int m_vmslots = m->size_of_parameters() - slots_pushed); // pos. of 1st arg. |
1838 DEBUG_ONLY(int m_vmslots = m->size_of_parameters() - slots_pushed); // pos. of 1st arg. |
1978 { |
1980 { |
1979 if (!src || src != dest) { |
1981 if (!src || src != dest) { |
1980 err = "adapter requires src/dest conversion subfields for swap"; break; |
1982 err = "adapter requires src/dest conversion subfields for swap"; break; |
1981 } |
1983 } |
1982 int swap_size = type2size[src]; |
1984 int swap_size = type2size[src]; |
1983 int slot_limit = java_lang_invoke_MethodHandle::vmslots(target()); |
|
1984 int src_slot = argslot; |
1985 int src_slot = argslot; |
1985 int dest_slot = vminfo; |
1986 int dest_slot = vminfo; |
1986 bool rotate_up = (src_slot > dest_slot); // upward rotation |
1987 bool rotate_up = (src_slot > dest_slot); // upward rotation |
1987 int src_arg = argnum; |
1988 int src_arg = argnum; |
1988 int dest_arg = argument_slot_to_argnum(dst_mtype(), dest_slot); |
1989 int dest_arg = argument_slot_to_argnum(dst_mtype(), dest_slot); |
2331 |
2332 |
2332 case _adapter_swap_args: |
2333 case _adapter_swap_args: |
2333 case _adapter_rot_args: |
2334 case _adapter_rot_args: |
2334 { |
2335 { |
2335 int swap_slots = type2size[src]; |
2336 int swap_slots = type2size[src]; |
2336 int slot_limit = java_lang_invoke_AdapterMethodHandle::vmslots(mh()); |
|
2337 int src_slot = argslot; |
2337 int src_slot = argslot; |
2338 int dest_slot = vminfo; |
2338 int dest_slot = vminfo; |
2339 int rotate = (ek_orig == _adapter_swap_args) ? 0 : (src_slot > dest_slot) ? 1 : -1; |
2339 int rotate = (ek_orig == _adapter_swap_args) ? 0 : (src_slot > dest_slot) ? 1 : -1; |
2340 switch (swap_slots) { |
2340 switch (swap_slots) { |
2341 case 1: |
2341 case 1: |
2659 JVM_ENTRY(void, MHN_init_DMH(JNIEnv *env, jobject igcls, jobject mh_jh, |
2659 JVM_ENTRY(void, MHN_init_DMH(JNIEnv *env, jobject igcls, jobject mh_jh, |
2660 jobject target_jh, jboolean do_dispatch, jobject caller_jh)) { |
2660 jobject target_jh, jboolean do_dispatch, jobject caller_jh)) { |
2661 ResourceMark rm; // for error messages |
2661 ResourceMark rm; // for error messages |
2662 |
2662 |
2663 // This is the guy we are initializing: |
2663 // This is the guy we are initializing: |
2664 if (mh_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2664 if (mh_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "self is null"); } |
2665 Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh)); |
2665 Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh)); |
2666 |
2666 |
2667 // Early returns out of this method leave the DMH in an unfinished state. |
2667 // Early returns out of this method leave the DMH in an unfinished state. |
2668 assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null"); |
2668 assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null"); |
2669 |
2669 |
2670 // which method are we really talking about? |
2670 // which method are we really talking about? |
2671 if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2671 if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); } |
2672 Handle target(THREAD, JNIHandles::resolve_non_null(target_jh)); |
2672 Handle target(THREAD, JNIHandles::resolve_non_null(target_jh)); |
2673 if (java_lang_invoke_MemberName::is_instance(target()) && |
2673 if (java_lang_invoke_MemberName::is_instance(target()) && |
2674 java_lang_invoke_MemberName::vmindex(target()) == VM_INDEX_UNINITIALIZED) { |
2674 java_lang_invoke_MemberName::vmindex(target()) == VM_INDEX_UNINITIALIZED) { |
2675 MethodHandles::resolve_MemberName(target, CHECK); |
2675 MethodHandles::resolve_MemberName(target, CHECK); |
2676 } |
2676 } |
2720 JVM_ENTRY(void, MHN_init_BMH(JNIEnv *env, jobject igcls, jobject mh_jh, |
2720 JVM_ENTRY(void, MHN_init_BMH(JNIEnv *env, jobject igcls, jobject mh_jh, |
2721 jobject target_jh, int argnum)) { |
2721 jobject target_jh, int argnum)) { |
2722 ResourceMark rm; // for error messages |
2722 ResourceMark rm; // for error messages |
2723 |
2723 |
2724 // This is the guy we are initializing: |
2724 // This is the guy we are initializing: |
2725 if (mh_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2725 if (mh_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "self is null"); } |
2726 Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh)); |
2726 Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh)); |
2727 |
2727 |
2728 // Early returns out of this method leave the BMH in an unfinished state. |
2728 // Early returns out of this method leave the BMH in an unfinished state. |
2729 assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null"); |
2729 assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null"); |
2730 |
2730 |
2731 if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2731 if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); } |
2732 Handle target(THREAD, JNIHandles::resolve_non_null(target_jh)); |
2732 Handle target(THREAD, JNIHandles::resolve_non_null(target_jh)); |
2733 |
2733 |
2734 if (!java_lang_invoke_MethodHandle::is_instance(target())) { |
2734 if (!java_lang_invoke_MethodHandle::is_instance(target())) { |
2735 // Target object is a reflective method. (%%% Do we need this alternate path?) |
2735 // Target object is a reflective method. (%%% Do we need this alternate path?) |
2736 Untested("init_BMH of non-MH"); |
2736 Untested("init_BMH of non-MH"); |
2751 |
2751 |
2752 // adapter method handles |
2752 // adapter method handles |
2753 JVM_ENTRY(void, MHN_init_AMH(JNIEnv *env, jobject igcls, jobject mh_jh, |
2753 JVM_ENTRY(void, MHN_init_AMH(JNIEnv *env, jobject igcls, jobject mh_jh, |
2754 jobject target_jh, int argnum)) { |
2754 jobject target_jh, int argnum)) { |
2755 // This is the guy we are initializing: |
2755 // This is the guy we are initializing: |
2756 if (mh_jh == NULL || target_jh == NULL) { |
2756 if (mh_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "self is null"); } |
2757 THROW(vmSymbols::java_lang_InternalError()); |
2757 if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); } |
2758 } |
|
2759 Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh)); |
2758 Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh)); |
2760 Handle target(THREAD, JNIHandles::resolve_non_null(target_jh)); |
2759 Handle target(THREAD, JNIHandles::resolve_non_null(target_jh)); |
2761 |
2760 |
2762 // Early returns out of this method leave the AMH in an unfinished state. |
2761 // Early returns out of this method leave the AMH in an unfinished state. |
2763 assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null"); |
2762 assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null"); |
2888 } |
2887 } |
2889 JVM_END |
2888 JVM_END |
2890 |
2889 |
2891 // void init(MemberName self, AccessibleObject ref) |
2890 // void init(MemberName self, AccessibleObject ref) |
2892 JVM_ENTRY(void, MHN_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) { |
2891 JVM_ENTRY(void, MHN_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) { |
2893 if (mname_jh == NULL || target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2892 if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); } |
|
2893 if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); } |
2894 Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); |
2894 Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); |
2895 oop target_oop = JNIHandles::resolve_non_null(target_jh); |
2895 oop target_oop = JNIHandles::resolve_non_null(target_jh); |
2896 MethodHandles::init_MemberName(mname(), target_oop); |
2896 MethodHandles::init_MemberName(mname(), target_oop); |
2897 } |
2897 } |
2898 JVM_END |
2898 JVM_END |
2899 |
2899 |
2900 // void expand(MemberName self) |
2900 // void expand(MemberName self) |
2901 JVM_ENTRY(void, MHN_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) { |
2901 JVM_ENTRY(void, MHN_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) { |
2902 if (mname_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2902 if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); } |
2903 Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); |
2903 Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); |
2904 MethodHandles::expand_MemberName(mname, 0, CHECK); |
2904 MethodHandles::expand_MemberName(mname, 0, CHECK); |
2905 } |
2905 } |
2906 JVM_END |
2906 JVM_END |
2907 |
2907 |
2908 // void resolve(MemberName self, Class<?> caller) |
2908 // void resolve(MemberName self, Class<?> caller) |
2909 JVM_ENTRY(void, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) { |
2909 JVM_ENTRY(void, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) { |
2910 if (mname_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } |
2910 if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); } |
2911 Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); |
2911 Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); |
2912 |
2912 |
2913 // The trusted Java code that calls this method should already have performed |
2913 // The trusted Java code that calls this method should already have performed |
2914 // access checks on behalf of the given caller. But, we can verify this. |
2914 // access checks on behalf of the given caller. But, we can verify this. |
2915 if (VerifyMethodHandles && caller_jh != NULL) { |
2915 if (VerifyMethodHandles && caller_jh != NULL) { |