1171 const int n_shadow_pages = StackOverflow::stack_shadow_zone_size() / page_size;
1172 const int start_page = native_call ? n_shadow_pages : 1;
1173 BLOCK_COMMENT("bang_stack_shadow_pages:");
1174 for (int pages = start_page; pages <= n_shadow_pages; pages++) {
1175 __ bang_stack_with_offset(pages*page_size);
1176 }
1177 }
1178
1179 // Interpreter stub for calling a native method. (asm interpreter)
1180 // This sets up a somewhat different looking stack for calling the
1181 // native method than the typical interpreter frame setup.
1182 //
1183 // On entry:
1184 // R19_method - method
1185 // R16_thread - JavaThread*
1186 // R15_esp - intptr_t* sender tos
1187 //
1188 // abstract stack (grows up)
1189 // [ IJava (caller of JNI callee) ] <-- ASP
1190 // ...
1191 address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
1192
1193 address entry = __ pc();
1194
1195 const bool inc_counter = UseCompiler || CountCompiledCalls;
1196
1197 // -----------------------------------------------------------------------------
1198 // Allocate a new frame that represents the native callee (i2n frame).
1199 // This is not a full-blown interpreter frame, but in particular, the
1200 // following registers are valid after this:
1201 // - R19_method
1202 // - R18_local (points to start of arguments to native function)
1203 //
1204 // abstract stack (grows up)
1205 // [ IJava (caller of JNI callee) ] <-- ASP
1206 // ...
1207
1208 const Register signature_handler_fd = R11_scratch1;
1209 const Register pending_exception = R0;
1210 const Register result_handler_addr = R31;
1211 const Register native_method_fd = R12_scratch2; // preferred in MacroAssembler::branch_to
1630 __ mr(R4_ARG2/*issuing_pc*/, return_pc);
1631
1632 // Return to exception handler.
1633 __ blr();
1634
1635 //=============================================================================
1636 // Counter overflow.
1637
1638 if (inc_counter) {
1639 // Handle invocation counter overflow.
1640 __ bind(invocation_counter_overflow);
1641
1642 generate_counter_overflow(continue_after_compile);
1643 }
1644
1645 return entry;
1646 }
1647
1648 // Generic interpreted method entry to (asm) interpreter.
1649 //
1650 address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
1651 bool inc_counter = UseCompiler || CountCompiledCalls;
1652 address entry = __ pc();
1653 // Generate the code to allocate the interpreter stack frame.
1654 Register Rsize_of_parameters = R4_ARG2, // Written by generate_fixed_frame.
1655 Rsize_of_locals = R5_ARG3; // Written by generate_fixed_frame.
1656
1657 // Does also a stack check to assure this frame fits on the stack.
1658 generate_fixed_frame(false, Rsize_of_parameters, Rsize_of_locals);
1659
1660 // --------------------------------------------------------------------------
1661 // Zero out non-parameter locals.
1662 // Note: *Always* zero out non-parameter locals as Sparc does. It's not
1663 // worth to ask the flag, just do it.
1664 Register Rslot_addr = R6_ARG4,
1665 Rnum = R7_ARG5;
1666 Label Lno_locals, Lzero_loop;
1667
1668 // Set up the zeroing loop.
1669 __ subf(Rnum, Rsize_of_parameters, Rsize_of_locals);
1670 __ subf(Rslot_addr, Rsize_of_parameters, R18_locals);
2203 address& fep,
2204 address& dep,
2205 address& vep) {
2206 assert(t->is_valid() && t->tos_in() == vtos, "illegal template");
2207 Label L;
2208
2209 aep = __ pc(); __ push_ptr(); __ b(L);
2210 fep = __ pc(); __ push_f(); __ b(L);
2211 dep = __ pc(); __ push_d(); __ b(L);
2212 lep = __ pc(); __ push_l(); __ b(L);
2213 __ align(32, 12, 24); // align L
2214 bep = cep = sep =
2215 iep = __ pc(); __ push_i();
2216 vep = __ pc();
2217 __ bind(L);
2218 generate_and_dispatch(t);
2219 }
2220
2221 //-----------------------------------------------------------------------------
2222
2223 // Non-product code
2224 #ifndef PRODUCT
2225 address TemplateInterpreterGenerator::generate_trace_code(TosState state) {
2226 //__ flush_bundle();
2227 address entry = __ pc();
2228
2229 const char *bname = nullptr;
2230 uint tsize = 0;
2231 switch(state) {
2232 case ftos:
2233 bname = "trace_code_ftos {";
2234 tsize = 2;
2235 break;
2236 case btos:
2237 bname = "trace_code_btos {";
2238 tsize = 2;
2239 break;
2240 case ztos:
2241 bname = "trace_code_ztos {";
2242 tsize = 2;
2290 __ blt(CCR0, Lskip_vm_call);
2291 }
2292
2293 __ push(state);
2294 // Load 2 topmost expression stack values.
2295 __ ld(R6_ARG4, tsize*Interpreter::stackElementSize, R15_esp);
2296 __ ld(R5_ARG3, Interpreter::stackElementSize, R15_esp);
2297 __ mflr(R31);
2298 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::trace_bytecode), /* unused */ R4_ARG2, R5_ARG3, R6_ARG4, false);
2299 __ mtlr(R31);
2300 __ pop(state);
2301
2302 if (TraceBytecodesAt > 0 && TraceBytecodesAt < max_intx) {
2303 __ bind(Lskip_vm_call);
2304 }
2305 __ blr();
2306 BLOCK_COMMENT("} trace_code");
2307 return entry;
2308 }
2309
2310 void TemplateInterpreterGenerator::count_bytecode() {
2311 int offs = __ load_const_optimized(R11_scratch1, (address) &BytecodeCounter::_counter_value, R12_scratch2, true);
2312 __ lwz(R12_scratch2, offs, R11_scratch1);
2313 __ addi(R12_scratch2, R12_scratch2, 1);
2314 __ stw(R12_scratch2, offs, R11_scratch1);
2315 }
2316
2317 void TemplateInterpreterGenerator::histogram_bytecode(Template* t) {
2318 int offs = __ load_const_optimized(R11_scratch1, (address) &BytecodeHistogram::_counters[t->bytecode()], R12_scratch2, true);
2319 __ lwz(R12_scratch2, offs, R11_scratch1);
2320 __ addi(R12_scratch2, R12_scratch2, 1);
2321 __ stw(R12_scratch2, offs, R11_scratch1);
2322 }
2323
2324 void TemplateInterpreterGenerator::histogram_bytecode_pair(Template* t) {
2325 const Register addr = R11_scratch1,
2326 tmp = R12_scratch2;
2327 // Get index, shift out old bytecode, bring in new bytecode, and store it.
2328 // _index = (_index >> log2_number_of_codes) |
2329 // (bytecode << log2_number_of_codes);
2330 int offs1 = __ load_const_optimized(addr, (address)&BytecodePairHistogram::_index, tmp, true);
2331 __ lwz(tmp, offs1, addr);
2332 __ srwi(tmp, tmp, BytecodePairHistogram::log2_number_of_codes);
2333 __ ori(tmp, tmp, ((int) t->bytecode()) << BytecodePairHistogram::log2_number_of_codes);
2334 __ stw(tmp, offs1, addr);
2335
2336 // Bump bucket contents.
2337 // _counters[_index] ++;
2338 int offs2 = __ load_const_optimized(addr, (address)&BytecodePairHistogram::_counters, R0, true);
2339 __ sldi(tmp, tmp, LogBytesPerInt);
2340 __ add(addr, tmp, addr);
2341 __ lwz(tmp, offs2, addr);
2342 __ addi(tmp, tmp, 1);
2343 __ stw(tmp, offs2, addr);
|
1171 const int n_shadow_pages = StackOverflow::stack_shadow_zone_size() / page_size;
1172 const int start_page = native_call ? n_shadow_pages : 1;
1173 BLOCK_COMMENT("bang_stack_shadow_pages:");
1174 for (int pages = start_page; pages <= n_shadow_pages; pages++) {
1175 __ bang_stack_with_offset(pages*page_size);
1176 }
1177 }
1178
1179 // Interpreter stub for calling a native method. (asm interpreter)
1180 // This sets up a somewhat different looking stack for calling the
1181 // native method than the typical interpreter frame setup.
1182 //
1183 // On entry:
1184 // R19_method - method
1185 // R16_thread - JavaThread*
1186 // R15_esp - intptr_t* sender tos
1187 //
1188 // abstract stack (grows up)
1189 // [ IJava (caller of JNI callee) ] <-- ASP
1190 // ...
1191 address TemplateInterpreterGenerator::generate_native_entry(bool synchronized, bool runtime_upcalls) {
1192
1193 address entry = __ pc();
1194
1195 const bool inc_counter = UseCompiler || CountCompiledCalls;
1196
1197 // -----------------------------------------------------------------------------
1198 // Allocate a new frame that represents the native callee (i2n frame).
1199 // This is not a full-blown interpreter frame, but in particular, the
1200 // following registers are valid after this:
1201 // - R19_method
1202 // - R18_local (points to start of arguments to native function)
1203 //
1204 // abstract stack (grows up)
1205 // [ IJava (caller of JNI callee) ] <-- ASP
1206 // ...
1207
1208 const Register signature_handler_fd = R11_scratch1;
1209 const Register pending_exception = R0;
1210 const Register result_handler_addr = R31;
1211 const Register native_method_fd = R12_scratch2; // preferred in MacroAssembler::branch_to
1630 __ mr(R4_ARG2/*issuing_pc*/, return_pc);
1631
1632 // Return to exception handler.
1633 __ blr();
1634
1635 //=============================================================================
1636 // Counter overflow.
1637
1638 if (inc_counter) {
1639 // Handle invocation counter overflow.
1640 __ bind(invocation_counter_overflow);
1641
1642 generate_counter_overflow(continue_after_compile);
1643 }
1644
1645 return entry;
1646 }
1647
1648 // Generic interpreted method entry to (asm) interpreter.
1649 //
1650 address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized, bool runtime_upcalls) {
1651 bool inc_counter = UseCompiler || CountCompiledCalls;
1652 address entry = __ pc();
1653 // Generate the code to allocate the interpreter stack frame.
1654 Register Rsize_of_parameters = R4_ARG2, // Written by generate_fixed_frame.
1655 Rsize_of_locals = R5_ARG3; // Written by generate_fixed_frame.
1656
1657 // Does also a stack check to assure this frame fits on the stack.
1658 generate_fixed_frame(false, Rsize_of_parameters, Rsize_of_locals);
1659
1660 // --------------------------------------------------------------------------
1661 // Zero out non-parameter locals.
1662 // Note: *Always* zero out non-parameter locals as Sparc does. It's not
1663 // worth to ask the flag, just do it.
1664 Register Rslot_addr = R6_ARG4,
1665 Rnum = R7_ARG5;
1666 Label Lno_locals, Lzero_loop;
1667
1668 // Set up the zeroing loop.
1669 __ subf(Rnum, Rsize_of_parameters, Rsize_of_locals);
1670 __ subf(Rslot_addr, Rsize_of_parameters, R18_locals);
2203 address& fep,
2204 address& dep,
2205 address& vep) {
2206 assert(t->is_valid() && t->tos_in() == vtos, "illegal template");
2207 Label L;
2208
2209 aep = __ pc(); __ push_ptr(); __ b(L);
2210 fep = __ pc(); __ push_f(); __ b(L);
2211 dep = __ pc(); __ push_d(); __ b(L);
2212 lep = __ pc(); __ push_l(); __ b(L);
2213 __ align(32, 12, 24); // align L
2214 bep = cep = sep =
2215 iep = __ pc(); __ push_i();
2216 vep = __ pc();
2217 __ bind(L);
2218 generate_and_dispatch(t);
2219 }
2220
2221 //-----------------------------------------------------------------------------
2222
2223 void TemplateInterpreterGenerator::count_bytecode() {
2224 int offs = __ load_const_optimized(R11_scratch1, (address) &BytecodeCounter::_counter_value, R12_scratch2, true);
2225 __ lwz(R12_scratch2, offs, R11_scratch1);
2226 __ addi(R12_scratch2, R12_scratch2, 1);
2227 __ stw(R12_scratch2, offs, R11_scratch1);
2228 }
2229
2230 void TemplateInterpreterGenerator::histogram_bytecode(Template* t) {
2231 int offs = __ load_const_optimized(R11_scratch1, (address) &BytecodeHistogram::_counters[t->bytecode()], R12_scratch2, true);
2232 __ lwz(R12_scratch2, offs, R11_scratch1);
2233 __ addi(R12_scratch2, R12_scratch2, 1);
2234 __ stw(R12_scratch2, offs, R11_scratch1);
2235 }
2236
2237 // Non-product code
2238 #ifndef PRODUCT
2239 address TemplateInterpreterGenerator::generate_trace_code(TosState state) {
2240 //__ flush_bundle();
2241 address entry = __ pc();
2242
2243 const char *bname = nullptr;
2244 uint tsize = 0;
2245 switch(state) {
2246 case ftos:
2247 bname = "trace_code_ftos {";
2248 tsize = 2;
2249 break;
2250 case btos:
2251 bname = "trace_code_btos {";
2252 tsize = 2;
2253 break;
2254 case ztos:
2255 bname = "trace_code_ztos {";
2256 tsize = 2;
2304 __ blt(CCR0, Lskip_vm_call);
2305 }
2306
2307 __ push(state);
2308 // Load 2 topmost expression stack values.
2309 __ ld(R6_ARG4, tsize*Interpreter::stackElementSize, R15_esp);
2310 __ ld(R5_ARG3, Interpreter::stackElementSize, R15_esp);
2311 __ mflr(R31);
2312 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::trace_bytecode), /* unused */ R4_ARG2, R5_ARG3, R6_ARG4, false);
2313 __ mtlr(R31);
2314 __ pop(state);
2315
2316 if (TraceBytecodesAt > 0 && TraceBytecodesAt < max_intx) {
2317 __ bind(Lskip_vm_call);
2318 }
2319 __ blr();
2320 BLOCK_COMMENT("} trace_code");
2321 return entry;
2322 }
2323
2324 void TemplateInterpreterGenerator::histogram_bytecode_pair(Template* t) {
2325 const Register addr = R11_scratch1,
2326 tmp = R12_scratch2;
2327 // Get index, shift out old bytecode, bring in new bytecode, and store it.
2328 // _index = (_index >> log2_number_of_codes) |
2329 // (bytecode << log2_number_of_codes);
2330 int offs1 = __ load_const_optimized(addr, (address)&BytecodePairHistogram::_index, tmp, true);
2331 __ lwz(tmp, offs1, addr);
2332 __ srwi(tmp, tmp, BytecodePairHistogram::log2_number_of_codes);
2333 __ ori(tmp, tmp, ((int) t->bytecode()) << BytecodePairHistogram::log2_number_of_codes);
2334 __ stw(tmp, offs1, addr);
2335
2336 // Bump bucket contents.
2337 // _counters[_index] ++;
2338 int offs2 = __ load_const_optimized(addr, (address)&BytecodePairHistogram::_counters, R0, true);
2339 __ sldi(tmp, tmp, LogBytesPerInt);
2340 __ add(addr, tmp, addr);
2341 __ lwz(tmp, offs2, addr);
2342 __ addi(tmp, tmp, 1);
2343 __ stw(tmp, offs2, addr);
|