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;