Mercurial > hg > graal-jvmci-8
comparison src/share/vm/prims/methodHandles.cpp @ 3412:88559690c95a
7047961: JSR 292 MethodHandleWalk swap args doesn't handle T_LONG and T_DOUBLE properly
Reviewed-by: kvn, jrose
author | never |
---|---|
date | Thu, 26 May 2011 14:44:41 -0700 |
parents | b79e8b4ecd76 |
children | ba550512d3b2 |
comparison
equal
deleted
inserted
replaced
3411:ea0da5474c23 | 3412:88559690c95a |
---|---|
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) { |