143 // convention: expect aberrant index in register G3_scratch, then shuffle the
144 // index to G4_scratch for the VM call
145 __ mov(G3_scratch, G4_scratch);
146 __ set((intptr_t)name, G3_scratch);
147 __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException), G3_scratch, G4_scratch);
148 __ should_not_reach_here();
149 return entry;
150 }
151
152
153 address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
154 address entry = __ pc();
155 // expression stack must be empty before entering the VM if an exception happened
156 __ empty_expression_stack();
157 __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_StackOverflowError));
158 __ should_not_reach_here();
159 return entry;
160 }
161
162
163 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) {
164 address compiled_entry = __ pc();
165 Label cont;
166
167 address entry = __ pc();
168 #if !defined(_LP64) && defined(COMPILER2)
169 // All return values are where we want them, except for Longs. C2 returns
170 // longs in G1 in the 32-bit build whereas the interpreter wants them in O0/O1.
171 // Since the interpreter will return longs in G1 and O0/O1 in the 32bit
172 // build even if we are returning from interpreted we just do a little
173 // stupid shuffing.
174 // Note: I tried to make c2 return longs in O0/O1 and G1 so we wouldn't have to
175 // do this here. Unfortunately if we did a rethrow we'd see an machepilog node
176 // first which would move g1 -> O0/O1 and destroy the exception we were throwing.
177
178 if( state == ltos ) {
179 __ srl (G1, 0,O1);
180 __ srlx(G1,32,O0);
181 }
182 #endif /* !_LP64 && COMPILER2 */
183
184
185 __ bind(cont);
186
187 // The callee returns with the stack possibly adjusted by adapter transition
188 // We remove that possible adjustment here.
189 // All interpreter local registers are untouched. Any result is passed back
190 // in the O0/O1 or float registers. Before continuing, the arguments must be
191 // popped from the java expression stack; i.e., Lesp must be adjusted.
192
193 __ mov(Llast_SP, SP); // Remove any adapter added stack space.
194
195
196 const Register cache = G3_scratch;
197 const Register size = G1_scratch;
198 __ get_cache_and_index_at_bcp(cache, G1_scratch, 1);
199 __ ld_ptr(Address(cache, 0, in_bytes(constantPoolCacheOopDesc::base_offset()) +
200 in_bytes(ConstantPoolCacheEntry::flags_offset())), size);
201 __ and3(size, 0xFF, size); // argument size in words
202 __ sll(size, Interpreter::logStackElementSize(), size); // each argument size in bytes
203 __ add(Lesp, size, Lesp); // pop arguments
204 __ dispatch_next(state, step);
205
206 return entry;
207 }
208
209
210 address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) {
211 address entry = __ pc();
212 __ get_constant_pool_cache(LcpoolCache); // load LcpoolCache
213 { Label L;
214 Address exception_addr (G2_thread, 0, in_bytes(Thread::pending_exception_offset()));
215
216 __ ld_ptr(exception_addr, Gtemp);
217 __ tst(Gtemp);
218 __ brx(Assembler::equal, false, Assembler::pt, L);
219 __ delayed()->nop();
220 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_pending_exception));
221 __ should_not_reach_here();
222 __ bind(L);
223 }
224 __ dispatch_next(state, step);
225 return entry;
|
143 // convention: expect aberrant index in register G3_scratch, then shuffle the
144 // index to G4_scratch for the VM call
145 __ mov(G3_scratch, G4_scratch);
146 __ set((intptr_t)name, G3_scratch);
147 __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException), G3_scratch, G4_scratch);
148 __ should_not_reach_here();
149 return entry;
150 }
151
152
153 address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
154 address entry = __ pc();
155 // expression stack must be empty before entering the VM if an exception happened
156 __ empty_expression_stack();
157 __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_StackOverflowError));
158 __ should_not_reach_here();
159 return entry;
160 }
161
162
163 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, bool unbox) {
164 TosState incoming_state = state;
165 if (InvokeDynamic) {
166 if (unbox) {
167 incoming_state = atos;
168 }
169 } else {
170 assert(!unbox, "old behavior");
171 }
172
173 address compiled_entry = __ pc();
174 Label cont;
175
176 address entry = __ pc();
177 #if !defined(_LP64) && defined(COMPILER2)
178 // All return values are where we want them, except for Longs. C2 returns
179 // longs in G1 in the 32-bit build whereas the interpreter wants them in O0/O1.
180 // Since the interpreter will return longs in G1 and O0/O1 in the 32bit
181 // build even if we are returning from interpreted we just do a little
182 // stupid shuffing.
183 // Note: I tried to make c2 return longs in O0/O1 and G1 so we wouldn't have to
184 // do this here. Unfortunately if we did a rethrow we'd see an machepilog node
185 // first which would move g1 -> O0/O1 and destroy the exception we were throwing.
186
187 if( incoming_state == ltos ) {
188 __ srl (G1, 0,O1);
189 __ srlx(G1,32,O0);
190 }
191 #endif /* !_LP64 && COMPILER2 */
192
193
194 __ bind(cont);
195
196 // The callee returns with the stack possibly adjusted by adapter transition
197 // We remove that possible adjustment here.
198 // All interpreter local registers are untouched. Any result is passed back
199 // in the O0/O1 or float registers. Before continuing, the arguments must be
200 // popped from the java expression stack; i.e., Lesp must be adjusted.
201
202 __ mov(Llast_SP, SP); // Remove any adapter added stack space.
203
204 if (unbox && state != atos) {
205 // cast and unbox
206 __ unimplemented();
207 }
208
209 const Register cache = G3_scratch;
210 const Register size = G1_scratch;
211 Label L_got_cache, L_giant_index;
212 if (InvokeDynamic) {
213 __ ldub(Lbcp, 0, size);
214 __ cmp(size, Bytecodes::_invokedynamic);
215 __ br(Assembler::equal, false, Assembler::pn, L_giant_index);
216 __ delayed()->nop();
217 }
218 __ get_cache_and_index_at_bcp(cache, G1_scratch, 1);
219 ////__ get_cache_and_index_at_bcp(cache, G1_scratch, 1, false);
220 __ bind(L_got_cache);
221 if (unbox && state == atos) {
222 // insert a casting conversion, to keep verifier sane
223 __ unimplemented();
224 }
225 __ ld_ptr(Address(cache, 0, in_bytes(constantPoolCacheOopDesc::base_offset()) +
226 in_bytes(ConstantPoolCacheEntry::flags_offset())), size);
227 __ and3(size, 0xFF, size); // argument size in words
228 __ sll(size, Interpreter::logStackElementSize(), size); // each argument size in bytes
229 __ add(Lesp, size, Lesp); // pop arguments
230 __ dispatch_next(state, step);
231
232 // out of the main line of code...
233 if (InvokeDynamic) {
234 __ bind(L_giant_index);
235 __ unimplemented();
236 ////__ get_cache_and_index_at_bcp(cache, G1_scratch, 1, true);
237 __ ba(false, L_got_cache);
238 __ delayed()->nop();
239 }
240
241 return entry;
242 }
243
244
245 address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) {
246 address entry = __ pc();
247 __ get_constant_pool_cache(LcpoolCache); // load LcpoolCache
248 { Label L;
249 Address exception_addr (G2_thread, 0, in_bytes(Thread::pending_exception_offset()));
250
251 __ ld_ptr(exception_addr, Gtemp);
252 __ tst(Gtemp);
253 __ brx(Assembler::equal, false, Assembler::pt, L);
254 __ delayed()->nop();
255 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_pending_exception));
256 __ should_not_reach_here();
257 __ bind(L);
258 }
259 __ dispatch_next(state, step);
260 return entry;
|