comparison src/share/vm/prims/methodHandles.cpp @ 3757:f8c9417e3571

7052219: JSR 292: Crash in ~BufferBlob::MethodHandles adapters Reviewed-by: twisti, kvn, jrose
author never
date Tue, 14 Jun 2011 14:41:33 -0700
parents cba7b5c2d53f
children 38fa55e5e792
comparison
equal deleted inserted replaced
3755:5cf771a79037 3757:f8c9417e3571
203 if (_adapter_code == NULL) 203 if (_adapter_code == NULL)
204 vm_exit_out_of_memory(adapter_code_size, "CodeCache: no room for MethodHandles adapters"); 204 vm_exit_out_of_memory(adapter_code_size, "CodeCache: no room for MethodHandles adapters");
205 CodeBuffer code(_adapter_code); 205 CodeBuffer code(_adapter_code);
206 MethodHandlesAdapterGenerator g(&code); 206 MethodHandlesAdapterGenerator g(&code);
207 g.generate(); 207 g.generate();
208
209 // Transfer code comments
210 _adapter_code->set_comments(code.comments());
211 } 208 }
212 209
213 //------------------------------------------------------------------------------ 210 //------------------------------------------------------------------------------
214 // MethodHandlesAdapterGenerator::generate 211 // MethodHandlesAdapterGenerator::generate
215 // 212 //
1978 if (!is_java_primitive(src) || dest != T_OBJECT) { 1975 if (!is_java_primitive(src) || dest != T_OBJECT) {
1979 err = "adapter requires primitive src conversion subfield"; break; 1976 err = "adapter requires primitive src conversion subfield"; break;
1980 } 1977 }
1981 break; 1978 break;
1982 case _adapter_swap_args: 1979 case _adapter_swap_args:
1983 case _adapter_rot_args:
1984 { 1980 {
1985 if (!src || src != dest) { 1981 if (!src || !dest) {
1986 err = "adapter requires src/dest conversion subfields for swap"; break; 1982 err = "adapter requires src/dest conversion subfields for swap"; break;
1987 } 1983 }
1988 int swap_size = type2size[src]; 1984 int src_size = type2size[src];
1985 if (src_size != type2size[dest]) {
1986 err = "adapter requires equal sizes for src/dest"; break;
1987 }
1989 int src_slot = argslot; 1988 int src_slot = argslot;
1990 int dest_slot = vminfo; 1989 int dest_slot = vminfo;
1991 bool rotate_up = (src_slot > dest_slot); // upward rotation
1992 int src_arg = argnum; 1990 int src_arg = argnum;
1993 int dest_arg = argument_slot_to_argnum(dst_mtype(), dest_slot); 1991 int dest_arg = argument_slot_to_argnum(src_mtype(), dest_slot);
1994 verify_vmargslot(target, dest_arg, dest_slot, CHECK); 1992 verify_vmargslot(mh, dest_arg, dest_slot, CHECK);
1995 if (!(dest_slot >= src_slot + swap_size) && 1993 if (!(dest_slot >= src_slot + src_size) &&
1996 !(src_slot >= dest_slot + swap_size)) { 1994 !(src_slot >= dest_slot + src_size)) {
1997 err = "source, destination slots must be distinct"; 1995 err = "source, destination slots must be distinct"; break;
1998 } else if (ek == _adapter_swap_args && !(src_slot > dest_slot)) { 1996 } else if (!(src_slot > dest_slot)) {
1999 err = "source of swap must be deeper in stack"; 1997 err = "source of swap must be deeper in stack"; break;
2000 } else if (ek == _adapter_swap_args) {
2001 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), dest_arg),
2002 java_lang_invoke_MethodType::ptype(dst_mtype(), src_arg),
2003 dest_arg);
2004 } else if (ek == _adapter_rot_args) {
2005 if (rotate_up) {
2006 assert((src_slot > dest_slot) && (src_arg < dest_arg), "");
2007 // rotate up: [dest_slot..src_slot-ss] --> [dest_slot+ss..src_slot]
2008 // that is: [src_arg+1..dest_arg] --> [src_arg..dest_arg-1]
2009 for (int i = src_arg+1; i <= dest_arg && err == NULL; i++) {
2010 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), i),
2011 java_lang_invoke_MethodType::ptype(dst_mtype(), i-1),
2012 i);
2013 }
2014 } else { // rotate down
2015 assert((src_slot < dest_slot) && (src_arg > dest_arg), "");
2016 // rotate down: [src_slot+ss..dest_slot] --> [src_slot..dest_slot-ss]
2017 // that is: [dest_arg..src_arg-1] --> [dst_arg+1..src_arg]
2018 for (int i = dest_arg; i <= src_arg-1 && err == NULL; i++) {
2019 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), i),
2020 java_lang_invoke_MethodType::ptype(dst_mtype(), i+1),
2021 i);
2022 }
2023 }
2024 } 1998 }
1999 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), dest_arg),
2000 java_lang_invoke_MethodType::ptype(dst_mtype(), src_arg),
2001 dest_arg);
2025 if (err == NULL) 2002 if (err == NULL)
2026 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), src_arg), 2003 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), src_arg),
2027 java_lang_invoke_MethodType::ptype(dst_mtype(), dest_arg), 2004 java_lang_invoke_MethodType::ptype(dst_mtype(), dest_arg),
2028 src_arg); 2005 src_arg);
2006 break;
2007 }
2008 case _adapter_rot_args:
2009 {
2010 if (!src || !dest) {
2011 err = "adapter requires src/dest conversion subfields for rotate"; break;
2012 }
2013 int src_slot = argslot;
2014 int limit_raw = vminfo;
2015 bool rot_down = (src_slot < limit_raw);
2016 int limit_bias = (rot_down ? MethodHandles::OP_ROT_ARGS_DOWN_LIMIT_BIAS : 0);
2017 int limit_slot = limit_raw - limit_bias;
2018 int src_arg = argnum;
2019 int limit_arg = argument_slot_to_argnum(src_mtype(), limit_slot);
2020 verify_vmargslot(mh, limit_arg, limit_slot, CHECK);
2021 if (src_slot == limit_slot) {
2022 err = "source, destination slots must be distinct"; break;
2023 }
2024 if (!rot_down) { // rotate slots up == shift arguments left
2025 // limit_slot is an inclusive lower limit
2026 assert((src_slot > limit_slot) && (src_arg < limit_arg), "");
2027 // rotate up: [limit_slot..src_slot-ss] --> [limit_slot+ss..src_slot]
2028 // that is: [src_arg+1..limit_arg] --> [src_arg..limit_arg-1]
2029 for (int i = src_arg+1; i <= limit_arg && err == NULL; i++) {
2030 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), i),
2031 java_lang_invoke_MethodType::ptype(dst_mtype(), i-1),
2032 i);
2033 }
2034 } else { // rotate slots down == shfit arguments right
2035 // limit_slot is an exclusive upper limit
2036 assert((src_slot < limit_slot - limit_bias) && (src_arg > limit_arg + limit_bias), "");
2037 // rotate down: [src_slot+ss..limit_slot) --> [src_slot..limit_slot-ss)
2038 // that is: (limit_arg..src_arg-1] --> (dst_arg+1..src_arg]
2039 for (int i = limit_arg+1; i <= src_arg-1 && err == NULL; i++) {
2040 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), i),
2041 java_lang_invoke_MethodType::ptype(dst_mtype(), i+1),
2042 i);
2043 }
2044 }
2045 if (err == NULL) {
2046 int dest_arg = (rot_down ? limit_arg+1 : limit_arg);
2047 err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), src_arg),
2048 java_lang_invoke_MethodType::ptype(dst_mtype(), dest_arg),
2049 src_arg);
2050 }
2029 } 2051 }
2030 break; 2052 break;
2031 case _adapter_spread_args: 2053 case _adapter_spread_args:
2032 case _adapter_collect_args: 2054 case _adapter_collect_args:
2033 case _adapter_fold_args: 2055 case _adapter_fold_args:
2811 case MethodHandles::GC_JVM_STACK_MOVE_UNIT: 2833 case MethodHandles::GC_JVM_STACK_MOVE_UNIT:
2812 // return number of words per slot, signed according to stack direction 2834 // return number of words per slot, signed according to stack direction
2813 return MethodHandles::stack_move_unit(); 2835 return MethodHandles::stack_move_unit();
2814 case MethodHandles::GC_CONV_OP_IMPLEMENTED_MASK: 2836 case MethodHandles::GC_CONV_OP_IMPLEMENTED_MASK:
2815 return MethodHandles::adapter_conversion_ops_supported_mask(); 2837 return MethodHandles::adapter_conversion_ops_supported_mask();
2838 case MethodHandles::GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS:
2839 return MethodHandles::OP_ROT_ARGS_DOWN_LIMIT_BIAS;
2816 } 2840 }
2817 return 0; 2841 return 0;
2818 } 2842 }
2819 JVM_END 2843 JVM_END
2820 2844
2822 #define EACH_NAMED_CON(template) \ 2846 #define EACH_NAMED_CON(template) \
2823 /* hold back this one until JDK stabilizes */ \ 2847 /* hold back this one until JDK stabilizes */ \
2824 /* template(MethodHandles,GC_JVM_PUSH_LIMIT) */ \ 2848 /* template(MethodHandles,GC_JVM_PUSH_LIMIT) */ \
2825 /* hold back this one until JDK stabilizes */ \ 2849 /* hold back this one until JDK stabilizes */ \
2826 /* template(MethodHandles,GC_JVM_STACK_MOVE_UNIT) */ \ 2850 /* template(MethodHandles,GC_JVM_STACK_MOVE_UNIT) */ \
2851 /* hold back this one until JDK stabilizes */ \
2852 /* template(MethodHandles,GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS) */ \
2827 template(MethodHandles,ETF_HANDLE_OR_METHOD_NAME) \ 2853 template(MethodHandles,ETF_HANDLE_OR_METHOD_NAME) \
2828 template(MethodHandles,ETF_DIRECT_HANDLE) \ 2854 template(MethodHandles,ETF_DIRECT_HANDLE) \
2829 template(MethodHandles,ETF_METHOD_NAME) \ 2855 template(MethodHandles,ETF_METHOD_NAME) \
2830 template(MethodHandles,ETF_REFLECT_METHOD) \ 2856 template(MethodHandles,ETF_REFLECT_METHOD) \
2831 template(java_lang_invoke_MemberName,MN_IS_METHOD) \ 2857 template(java_lang_invoke_MemberName,MN_IS_METHOD) \