Mercurial > hg > graal-jvmci-8
comparison src/cpu/sparc/vm/methodHandles_sparc.cpp @ 1916:e62345fd6a46
6997459: JSR 292 after 6994093 getting: on return to interpreted call, restored SP is corrupted
Reviewed-by: kvn, jrose, never
author | twisti |
---|---|
date | Thu, 04 Nov 2010 12:16:58 -0700 |
parents | fff777a71346 |
children | f95d63e2154a |
comparison
equal
deleted
inserted
replaced
1915:885e464e1a40 | 1916:e62345fd6a46 |
---|---|
68 } | 68 } |
69 | 69 |
70 | 70 |
71 // Code generation | 71 // Code generation |
72 address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm) { | 72 address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm) { |
73 // I5_savedSP: sender SP (must preserve) | 73 // I5_savedSP/O5_savedSP: sender SP (must preserve) |
74 // G4 (Gargs): incoming argument list (must preserve) | 74 // G4 (Gargs): incoming argument list (must preserve) |
75 // G5_method: invoke methodOop; becomes method type. | 75 // G5_method: invoke methodOop |
76 // G3_method_handle: receiver method handle (must load from sp[MethodTypeForm.vmslots]) | 76 // G3_method_handle: receiver method handle (must load from sp[MethodTypeForm.vmslots]) |
77 // O0, O1: garbage temps, blown away | 77 // O0, O1, O2, O3, O4: garbage temps, blown away |
78 Register O0_argslot = O0; | 78 Register O0_mtype = O0; |
79 Register O1_scratch = O1; | 79 Register O1_scratch = O1; |
80 Register O2_scratch = O2; | 80 Register O2_scratch = O2; |
81 Register O3_scratch = O3; | 81 Register O3_scratch = O3; |
82 Register O4_argslot = O4; | |
82 Register O4_argbase = O4; | 83 Register O4_argbase = O4; |
83 Register O5_mtype = O5; | |
84 | 84 |
85 // emit WrongMethodType path first, to enable back-branch from main path | 85 // emit WrongMethodType path first, to enable back-branch from main path |
86 Label wrong_method_type; | 86 Label wrong_method_type; |
87 __ bind(wrong_method_type); | 87 __ bind(wrong_method_type); |
88 Label invoke_generic_slow_path; | 88 Label invoke_generic_slow_path; |
89 assert(methodOopDesc::intrinsic_id_size_in_bytes() == sizeof(u1), "");; | 89 assert(methodOopDesc::intrinsic_id_size_in_bytes() == sizeof(u1), "");; |
90 __ ldub(Address(G5_method, methodOopDesc::intrinsic_id_offset_in_bytes()), O1_scratch); | 90 __ ldub(Address(G5_method, methodOopDesc::intrinsic_id_offset_in_bytes()), O1_scratch); |
91 __ cmp(O1_scratch, (int) vmIntrinsics::_invokeExact); | 91 __ cmp(O1_scratch, (int) vmIntrinsics::_invokeExact); |
92 __ brx(Assembler::notEqual, false, Assembler::pt, invoke_generic_slow_path); | 92 __ brx(Assembler::notEqual, false, Assembler::pt, invoke_generic_slow_path); |
93 __ delayed()->nop(); | 93 __ delayed()->nop(); |
94 __ mov(O5_mtype, G5_method_type); // required by throw_WrongMethodType | 94 __ mov(O0_mtype, G5_method_type); // required by throw_WrongMethodType |
95 // mov(G3_method_handle, G3_method_handle); // already in this register | 95 // mov(G3_method_handle, G3_method_handle); // already in this register |
96 __ jump_to(AddressLiteral(Interpreter::throw_WrongMethodType_entry()), O1_scratch); | 96 __ jump_to(AddressLiteral(Interpreter::throw_WrongMethodType_entry()), O1_scratch); |
97 __ delayed()->nop(); | 97 __ delayed()->nop(); |
98 | 98 |
99 // here's where control starts out: | 99 // here's where control starts out: |
102 | 102 |
103 // fetch the MethodType from the method handle | 103 // fetch the MethodType from the method handle |
104 { | 104 { |
105 Register tem = G5_method; | 105 Register tem = G5_method; |
106 for (jint* pchase = methodOopDesc::method_type_offsets_chain(); (*pchase) != -1; pchase++) { | 106 for (jint* pchase = methodOopDesc::method_type_offsets_chain(); (*pchase) != -1; pchase++) { |
107 __ ld_ptr(Address(tem, *pchase), O5_mtype); | 107 __ ld_ptr(Address(tem, *pchase), O0_mtype); |
108 tem = O5_mtype; // in case there is another indirection | 108 tem = O0_mtype; // in case there is another indirection |
109 } | 109 } |
110 } | 110 } |
111 | 111 |
112 // given the MethodType, find out where the MH argument is buried | 112 // given the MethodType, find out where the MH argument is buried |
113 __ load_heap_oop(Address(O5_mtype, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, O1_scratch)), O0_argslot); | 113 __ load_heap_oop(Address(O0_mtype, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, O1_scratch)), O4_argslot); |
114 __ ldsw( Address(O0_argslot, __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, O1_scratch)), O0_argslot); | 114 __ ldsw( Address(O4_argslot, __ delayed_value(java_dyn_MethodTypeForm::vmslots_offset_in_bytes, O1_scratch)), O4_argslot); |
115 __ add(Gargs, __ argument_offset(O0_argslot, 1), O4_argbase); | 115 __ add(Gargs, __ argument_offset(O4_argslot, 1), O4_argbase); |
116 // Note: argument_address uses its input as a scratch register! | 116 // Note: argument_address uses its input as a scratch register! |
117 __ ld_ptr(Address(O4_argbase, -Interpreter::stackElementSize), G3_method_handle); | 117 __ ld_ptr(Address(O4_argbase, -Interpreter::stackElementSize), G3_method_handle); |
118 | 118 |
119 trace_method_handle(_masm, "invokeExact"); | 119 trace_method_handle(_masm, "invokeExact"); |
120 | 120 |
121 __ check_method_handle_type(O5_mtype, G3_method_handle, O1_scratch, wrong_method_type); | 121 __ check_method_handle_type(O0_mtype, G3_method_handle, O1_scratch, wrong_method_type); |
122 __ jump_to_method_handle_entry(G3_method_handle, O1_scratch); | 122 __ jump_to_method_handle_entry(G3_method_handle, O1_scratch); |
123 | 123 |
124 // for invokeGeneric (only), apply argument and result conversions on the fly | 124 // for invokeGeneric (only), apply argument and result conversions on the fly |
125 __ bind(invoke_generic_slow_path); | 125 __ bind(invoke_generic_slow_path); |
126 #ifdef ASSERT | 126 #ifdef ASSERT |
133 __ bind(L); | 133 __ bind(L); |
134 } | 134 } |
135 #endif //ASSERT | 135 #endif //ASSERT |
136 | 136 |
137 // make room on the stack for another pointer: | 137 // make room on the stack for another pointer: |
138 insert_arg_slots(_masm, 2 * stack_move_unit(), _INSERT_REF_MASK, | 138 insert_arg_slots(_masm, 2 * stack_move_unit(), _INSERT_REF_MASK, O4_argbase, O1_scratch, O2_scratch, O3_scratch); |
139 O4_argbase, O1_scratch, O2_scratch, O3_scratch); | |
140 // load up an adapter from the calling type (Java weaves this) | 139 // load up an adapter from the calling type (Java weaves this) |
141 Register O2_form = O2_scratch; | 140 Register O2_form = O2_scratch; |
142 Register O3_adapter = O3_scratch; | 141 Register O3_adapter = O3_scratch; |
143 __ load_heap_oop(Address(O5_mtype, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, O1_scratch)), O2_form); | 142 __ load_heap_oop(Address(O0_mtype, __ delayed_value(java_dyn_MethodType::form_offset_in_bytes, O1_scratch)), O2_form); |
144 // load_heap_oop(Address(O2_form, __ delayed_value(java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes, O1_scratch)), O3_adapter); | 143 // load_heap_oop(Address(O2_form, __ delayed_value(java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes, O1_scratch)), O3_adapter); |
145 // deal with old JDK versions: | 144 // deal with old JDK versions: |
146 __ add( Address(O2_form, __ delayed_value(java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes, O1_scratch)), O3_adapter); | 145 __ add( Address(O2_form, __ delayed_value(java_dyn_MethodTypeForm::genericInvoker_offset_in_bytes, O1_scratch)), O3_adapter); |
147 __ cmp(O3_adapter, O2_form); | 146 __ cmp(O3_adapter, O2_form); |
148 Label sorry_no_invoke_generic; | 147 Label sorry_no_invoke_generic; |
149 __ brx(Assembler::lessUnsigned, false, Assembler::pn, sorry_no_invoke_generic); | 148 __ brx(Assembler::lessUnsigned, false, Assembler::pn, sorry_no_invoke_generic); |
150 __ delayed()->nop(); | 149 __ delayed()->nop(); |
151 | 150 |
155 __ delayed()->nop(); | 154 __ delayed()->nop(); |
156 __ st_ptr(O3_adapter, Address(O4_argbase, 1 * Interpreter::stackElementSize)); | 155 __ st_ptr(O3_adapter, Address(O4_argbase, 1 * Interpreter::stackElementSize)); |
157 // As a trusted first argument, pass the type being called, so the adapter knows | 156 // As a trusted first argument, pass the type being called, so the adapter knows |
158 // the actual types of the arguments and return values. | 157 // the actual types of the arguments and return values. |
159 // (Generic invokers are shared among form-families of method-type.) | 158 // (Generic invokers are shared among form-families of method-type.) |
160 __ st_ptr(O5_mtype, Address(O4_argbase, 0 * Interpreter::stackElementSize)); | 159 __ st_ptr(O0_mtype, Address(O4_argbase, 0 * Interpreter::stackElementSize)); |
161 // FIXME: assert that O3_adapter is of the right method-type. | 160 // FIXME: assert that O3_adapter is of the right method-type. |
162 __ mov(O3_adapter, G3_method_handle); | 161 __ mov(O3_adapter, G3_method_handle); |
163 trace_method_handle(_masm, "invokeGeneric"); | 162 trace_method_handle(_masm, "invokeGeneric"); |
164 __ jump_to_method_handle_entry(G3_method_handle, O1_scratch); | 163 __ jump_to_method_handle_entry(G3_method_handle, O1_scratch); |
165 | 164 |
166 __ bind(sorry_no_invoke_generic); // no invokeGeneric implementation available! | 165 __ bind(sorry_no_invoke_generic); // no invokeGeneric implementation available! |
167 __ mov(O5_mtype, G5_method_type); // required by throw_WrongMethodType | 166 __ mov(O0_mtype, G5_method_type); // required by throw_WrongMethodType |
168 // mov(G3_method_handle, G3_method_handle); // already in this register | 167 // mov(G3_method_handle, G3_method_handle); // already in this register |
169 __ jump_to(AddressLiteral(Interpreter::throw_WrongMethodType_entry()), O1_scratch); | 168 __ jump_to(AddressLiteral(Interpreter::throw_WrongMethodType_entry()), O1_scratch); |
170 __ delayed()->nop(); | 169 __ delayed()->nop(); |
171 | 170 |
172 return entry_point; | 171 return entry_point; |