136 // convention: expect aberrant index in register G3_scratch, then shuffle the 137 // index to G4_scratch for the VM call 138 __ mov(G3_scratch, G4_scratch); 139 __ set((intptr_t)name, G3_scratch); 140 __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException), G3_scratch, G4_scratch); 141 __ should_not_reach_here(); 142 return entry; 143 } 144 145 146 address TemplateInterpreterGenerator::generate_StackOverflowError_handler() { 147 address entry = __ pc(); 148 // expression stack must be empty before entering the VM if an exception happened 149 __ empty_expression_stack(); 150 __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_StackOverflowError)); 151 __ should_not_reach_here(); 152 return entry; 153 } 154 155 156 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) { 157 TosState incoming_state = state; 158 159 Label cont; 160 address compiled_entry = __ pc(); 161 162 address entry = __ pc(); 163 #if !defined(_LP64) && defined(COMPILER2) 164 // All return values are where we want them, except for Longs. C2 returns 165 // longs in G1 in the 32-bit build whereas the interpreter wants them in O0/O1. 166 // Since the interpreter will return longs in G1 and O0/O1 in the 32bit 167 // build even if we are returning from interpreted we just do a little 168 // stupid shuffing. 169 // Note: I tried to make c2 return longs in O0/O1 and G1 so we wouldn't have to 170 // do this here. Unfortunately if we did a rethrow we'd see an machepilog node 171 // first which would move g1 -> O0/O1 and destroy the exception we were throwing. 172 173 if (incoming_state == ltos) { 174 __ srl (G1, 0, O1); 175 __ srlx(G1, 32, O0); 176 } 177 #endif // !_LP64 && COMPILER2 178 179 __ bind(cont); 180 181 // The callee returns with the stack possibly adjusted by adapter transition 182 // We remove that possible adjustment here. 183 // All interpreter local registers are untouched. Any result is passed back 184 // in the O0/O1 or float registers. Before continuing, the arguments must be 185 // popped from the java expression stack; i.e., Lesp must be adjusted. 186 187 __ mov(Llast_SP, SP); // Remove any adapter added stack space. 188 189 Label L_got_cache, L_giant_index; 190 const Register cache = G3_scratch; 191 const Register size = G1_scratch; 192 if (EnableInvokeDynamic) { 193 __ ldub(Address(Lbcp, 0), G1_scratch); // Load current bytecode. 194 __ cmp_and_br_short(G1_scratch, Bytecodes::_invokedynamic, Assembler::equal, Assembler::pn, L_giant_index); 195 } 196 __ get_cache_and_index_at_bcp(cache, G1_scratch, 1); 197 __ bind(L_got_cache); 198 __ ld_ptr(cache, ConstantPoolCache::base_offset() + 199 ConstantPoolCacheEntry::flags_offset(), size); 200 __ and3(size, 0xFF, size); // argument size in words 201 __ sll(size, Interpreter::logStackElementSize, size); // each argument size in bytes 202 __ add(Lesp, size, Lesp); // pop arguments 203 __ dispatch_next(state, step); 204 205 // out of the main line of code... 206 if (EnableInvokeDynamic) { 207 __ bind(L_giant_index); 208 __ get_cache_and_index_at_bcp(cache, G1_scratch, 1, sizeof(u4)); 209 __ ba_short(L_got_cache); 210 } 211 212 return entry; 213 } 214 215 216 address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) { 217 address entry = __ pc(); 218 __ get_constant_pool_cache(LcpoolCache); // load LcpoolCache 219 { Label L; 220 Address exception_addr(G2_thread, Thread::pending_exception_offset()); 221 __ ld_ptr(exception_addr, Gtemp); // Load pending exception. 222 __ br_null_short(Gtemp, Assembler::pt, L); 223 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_pending_exception)); 224 __ should_not_reach_here(); 225 __ bind(L); 226 } 227 __ dispatch_next(state, step); 228 return entry; 229 } 230 | 136 // convention: expect aberrant index in register G3_scratch, then shuffle the 137 // index to G4_scratch for the VM call 138 __ mov(G3_scratch, G4_scratch); 139 __ set((intptr_t)name, G3_scratch); 140 __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ArrayIndexOutOfBoundsException), G3_scratch, G4_scratch); 141 __ should_not_reach_here(); 142 return entry; 143 } 144 145 146 address TemplateInterpreterGenerator::generate_StackOverflowError_handler() { 147 address entry = __ pc(); 148 // expression stack must be empty before entering the VM if an exception happened 149 __ empty_expression_stack(); 150 __ call_VM(Oexception, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_StackOverflowError)); 151 __ should_not_reach_here(); 152 return entry; 153 } 154 155 156 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size) { 157 address entry = __ pc(); 158 159 #if !defined(_LP64) && defined(COMPILER2) 160 // All return values are where we want them, except for Longs. C2 returns 161 // longs in G1 in the 32-bit build whereas the interpreter wants them in O0/O1. 162 // Since the interpreter will return longs in G1 and O0/O1 in the 32bit 163 // build even if we are returning from interpreted we just do a little 164 // stupid shuffing. 165 // Note: I tried to make c2 return longs in O0/O1 and G1 so we wouldn't have to 166 // do this here. Unfortunately if we did a rethrow we'd see an machepilog node 167 // first which would move g1 -> O0/O1 and destroy the exception we were throwing. 168 169 if (state == ltos) { 170 __ srl (G1, 0, O1); 171 __ srlx(G1, 32, O0); 172 } 173 #endif // !_LP64 && COMPILER2 174 175 // The callee returns with the stack possibly adjusted by adapter transition 176 // We remove that possible adjustment here. 177 // All interpreter local registers are untouched. Any result is passed back 178 // in the O0/O1 or float registers. Before continuing, the arguments must be 179 // popped from the java expression stack; i.e., Lesp must be adjusted. 180 181 __ mov(Llast_SP, SP); // Remove any adapter added stack space. 182 183 const Register cache = G3_scratch; 184 const Register index = G1_scratch; 185 __ get_cache_and_index_at_bcp(cache, index, 1, index_size); 186 187 const Register flags = cache; 188 __ ld_ptr(cache, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset(), flags); 189 const Register parameter_size = flags; 190 __ and3(flags, ConstantPoolCacheEntry::parameter_size_mask, parameter_size); // argument size in words 191 __ sll(parameter_size, Interpreter::logStackElementSize, parameter_size); // each argument size in bytes 192 __ add(Lesp, parameter_size, Lesp); // pop arguments 193 __ dispatch_next(state, step); 194 195 return entry; 196 } 197 198 199 address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) { 200 address entry = __ pc(); 201 __ get_constant_pool_cache(LcpoolCache); // load LcpoolCache 202 { Label L; 203 Address exception_addr(G2_thread, Thread::pending_exception_offset()); 204 __ ld_ptr(exception_addr, Gtemp); // Load pending exception. 205 __ br_null_short(Gtemp, Assembler::pt, L); 206 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_pending_exception)); 207 __ should_not_reach_here(); 208 __ bind(L); 209 } 210 __ dispatch_next(state, step); 211 return entry; 212 } 213 |