Mercurial > hg > graal-compiler
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) \ |