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) {