< prev index next >

src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp

Print this page

1216   const int n_shadow_pages = StackOverflow::stack_shadow_zone_size() / page_size;
1217   const int start_page = native_call ? n_shadow_pages : 1;
1218   BLOCK_COMMENT("bang_stack_shadow_pages:");
1219   for (int pages = start_page; pages <= n_shadow_pages; pages++) {
1220     __ bang_stack_with_offset(pages*page_size);
1221   }
1222 }
1223 
1224 // Interpreter stub for calling a native method. (asm interpreter)
1225 // This sets up a somewhat different looking stack for calling the
1226 // native method than the typical interpreter frame setup.
1227 //
1228 // On entry:
1229 //   R19_method    - method
1230 //   R16_thread    - JavaThread*
1231 //   R15_esp       - intptr_t* sender tos
1232 //
1233 //   abstract stack (grows up)
1234 //     [  IJava (caller of JNI callee)  ]  <-- ASP
1235 //        ...
1236 address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
1237 
1238   address entry = __ pc();
1239 
1240   const bool inc_counter = UseCompiler || CountCompiledCalls;
1241 
1242   // -----------------------------------------------------------------------------
1243   // Allocate a new frame that represents the native callee (i2n frame).
1244   // This is not a full-blown interpreter frame, but in particular, the
1245   // following registers are valid after this:
1246   // - R19_method
1247   // - R18_local (points to start of arguments to native function)
1248   //
1249   //   abstract stack (grows up)
1250   //     [  IJava (caller of JNI callee)  ]  <-- ASP
1251   //        ...
1252 
1253   const Register signature_handler_fd = R11_scratch1;
1254   const Register pending_exception    = R0;
1255   const Register result_handler_addr  = R31;
1256   const Register native_method_fd     = R12_scratch2; // preferred in MacroAssembler::branch_to
1257   const Register access_flags         = R24_tmp4;
1258   const Register active_handles       = R11_scratch1; // R26_monitor saved to state.
1259   const Register sync_state           = R12_scratch2;
1260   const Register sync_state_addr      = sync_state;   // Address is dead after use.

1694   __ mr(R4_ARG2/*issuing_pc*/, return_pc);
1695 
1696   // Return to exception handler.
1697   __ blr();
1698 
1699   //=============================================================================
1700   // Counter overflow.
1701 
1702   if (inc_counter) {
1703     // Handle invocation counter overflow.
1704     __ bind(invocation_counter_overflow);
1705 
1706     generate_counter_overflow(continue_after_compile);
1707   }
1708 
1709   return entry;
1710 }
1711 
1712 // Generic interpreted method entry to (asm) interpreter.
1713 //
1714 address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
1715   bool inc_counter = UseCompiler || CountCompiledCalls;
1716   address entry = __ pc();
1717   // Generate the code to allocate the interpreter stack frame.
1718   Register Rsize_of_parameters = R4_ARG2, // Written by generate_fixed_frame.
1719            Rsize_of_locals     = R5_ARG3; // Written by generate_fixed_frame.
1720 
1721   // Does also a stack check to assure this frame fits on the stack.
1722   generate_fixed_frame(false, Rsize_of_parameters, Rsize_of_locals);
1723 
1724   // --------------------------------------------------------------------------
1725   // Zero out non-parameter locals.
1726   // Note: *Always* zero out non-parameter locals as Sparc does. It's not
1727   // worth to ask the flag, just do it.
1728   Register Rslot_addr = R6_ARG4,
1729            Rnum       = R7_ARG5;
1730   Label Lno_locals, Lzero_loop;
1731 
1732   // Set up the zeroing loop.
1733   __ subf(Rnum, Rsize_of_parameters, Rsize_of_locals);
1734   __ subf(Rslot_addr, Rsize_of_parameters, R18_locals);
1735   __ srdi_(Rnum, Rnum, Interpreter::logStackElementSize);

2357     __ cmpd(CR0, R12_scratch2, R11_scratch1);
2358     __ blt(CR0, Lskip_vm_call);
2359   }
2360 
2361   __ push(state);
2362   // Load 2 topmost expression stack values.
2363   __ ld(R6_ARG4, tsize*Interpreter::stackElementSize, R15_esp);
2364   __ ld(R5_ARG3, Interpreter::stackElementSize, R15_esp);
2365   __ mflr(R31);
2366   __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::trace_bytecode), /* unused */ R4_ARG2, R5_ARG3, R6_ARG4, false);
2367   __ mtlr(R31);
2368   __ pop(state);
2369 
2370   if (TraceBytecodesAt > 0) {
2371     __ bind(Lskip_vm_call);
2372   }
2373   __ blr();
2374   BLOCK_COMMENT("} trace_code");
2375   return entry;
2376 }

2377 
2378 void TemplateInterpreterGenerator::count_bytecode() {
2379   int offs = __ load_const_optimized(R11_scratch1, (address) &BytecodeCounter::_counter_value, R12_scratch2, true);
2380   __ ld(R12_scratch2, offs, R11_scratch1);
2381   __ addi(R12_scratch2, R12_scratch2, 1);
2382   __ std(R12_scratch2, offs, R11_scratch1);
2383 }
2384 
2385 void TemplateInterpreterGenerator::histogram_bytecode(Template* t) {
2386   int offs = __ load_const_optimized(R11_scratch1, (address) &BytecodeHistogram::_counters[t->bytecode()], R12_scratch2, true);
2387   __ lwz(R12_scratch2, offs, R11_scratch1);
2388   __ addi(R12_scratch2, R12_scratch2, 1);
2389   __ stw(R12_scratch2, offs, R11_scratch1);
2390 }
2391 

2392 void TemplateInterpreterGenerator::histogram_bytecode_pair(Template* t) {
2393   const Register addr = R11_scratch1,
2394                  tmp  = R12_scratch2;
2395   // Get index, shift out old bytecode, bring in new bytecode, and store it.
2396   // _index = (_index >> log2_number_of_codes) |
2397   //          (bytecode << log2_number_of_codes);
2398   int offs1 = __ load_const_optimized(addr, (address)&BytecodePairHistogram::_index, tmp, true);
2399   __ lwz(tmp, offs1, addr);
2400   __ srwi(tmp, tmp, BytecodePairHistogram::log2_number_of_codes);
2401   __ ori(tmp, tmp, ((int) t->bytecode()) << BytecodePairHistogram::log2_number_of_codes);
2402   __ stw(tmp, offs1, addr);
2403 
2404   // Bump bucket contents.
2405   // _counters[_index] ++;
2406   int offs2 = __ load_const_optimized(addr, (address)&BytecodePairHistogram::_counters, R0, true);
2407   __ sldi(tmp, tmp, LogBytesPerInt);
2408   __ add(addr, tmp, addr);
2409   __ lwz(tmp, offs2, addr);
2410   __ addi(tmp, tmp, 1);
2411   __ stw(tmp, offs2, addr);

1216   const int n_shadow_pages = StackOverflow::stack_shadow_zone_size() / page_size;
1217   const int start_page = native_call ? n_shadow_pages : 1;
1218   BLOCK_COMMENT("bang_stack_shadow_pages:");
1219   for (int pages = start_page; pages <= n_shadow_pages; pages++) {
1220     __ bang_stack_with_offset(pages*page_size);
1221   }
1222 }
1223 
1224 // Interpreter stub for calling a native method. (asm interpreter)
1225 // This sets up a somewhat different looking stack for calling the
1226 // native method than the typical interpreter frame setup.
1227 //
1228 // On entry:
1229 //   R19_method    - method
1230 //   R16_thread    - JavaThread*
1231 //   R15_esp       - intptr_t* sender tos
1232 //
1233 //   abstract stack (grows up)
1234 //     [  IJava (caller of JNI callee)  ]  <-- ASP
1235 //        ...
1236 address TemplateInterpreterGenerator::generate_native_entry(bool synchronized, bool runtime_upcalls) {
1237 
1238   address entry = __ pc();
1239 
1240   const bool inc_counter = (UseCompiler || CountCompiledCalls) && !PreloadOnly;
1241 
1242   // -----------------------------------------------------------------------------
1243   // Allocate a new frame that represents the native callee (i2n frame).
1244   // This is not a full-blown interpreter frame, but in particular, the
1245   // following registers are valid after this:
1246   // - R19_method
1247   // - R18_local (points to start of arguments to native function)
1248   //
1249   //   abstract stack (grows up)
1250   //     [  IJava (caller of JNI callee)  ]  <-- ASP
1251   //        ...
1252 
1253   const Register signature_handler_fd = R11_scratch1;
1254   const Register pending_exception    = R0;
1255   const Register result_handler_addr  = R31;
1256   const Register native_method_fd     = R12_scratch2; // preferred in MacroAssembler::branch_to
1257   const Register access_flags         = R24_tmp4;
1258   const Register active_handles       = R11_scratch1; // R26_monitor saved to state.
1259   const Register sync_state           = R12_scratch2;
1260   const Register sync_state_addr      = sync_state;   // Address is dead after use.

1694   __ mr(R4_ARG2/*issuing_pc*/, return_pc);
1695 
1696   // Return to exception handler.
1697   __ blr();
1698 
1699   //=============================================================================
1700   // Counter overflow.
1701 
1702   if (inc_counter) {
1703     // Handle invocation counter overflow.
1704     __ bind(invocation_counter_overflow);
1705 
1706     generate_counter_overflow(continue_after_compile);
1707   }
1708 
1709   return entry;
1710 }
1711 
1712 // Generic interpreted method entry to (asm) interpreter.
1713 //
1714 address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized, bool runtime_upcalls) {
1715   bool inc_counter = (UseCompiler || CountCompiledCalls) && !PreloadOnly;
1716   address entry = __ pc();
1717   // Generate the code to allocate the interpreter stack frame.
1718   Register Rsize_of_parameters = R4_ARG2, // Written by generate_fixed_frame.
1719            Rsize_of_locals     = R5_ARG3; // Written by generate_fixed_frame.
1720 
1721   // Does also a stack check to assure this frame fits on the stack.
1722   generate_fixed_frame(false, Rsize_of_parameters, Rsize_of_locals);
1723 
1724   // --------------------------------------------------------------------------
1725   // Zero out non-parameter locals.
1726   // Note: *Always* zero out non-parameter locals as Sparc does. It's not
1727   // worth to ask the flag, just do it.
1728   Register Rslot_addr = R6_ARG4,
1729            Rnum       = R7_ARG5;
1730   Label Lno_locals, Lzero_loop;
1731 
1732   // Set up the zeroing loop.
1733   __ subf(Rnum, Rsize_of_parameters, Rsize_of_locals);
1734   __ subf(Rslot_addr, Rsize_of_parameters, R18_locals);
1735   __ srdi_(Rnum, Rnum, Interpreter::logStackElementSize);

2357     __ cmpd(CR0, R12_scratch2, R11_scratch1);
2358     __ blt(CR0, Lskip_vm_call);
2359   }
2360 
2361   __ push(state);
2362   // Load 2 topmost expression stack values.
2363   __ ld(R6_ARG4, tsize*Interpreter::stackElementSize, R15_esp);
2364   __ ld(R5_ARG3, Interpreter::stackElementSize, R15_esp);
2365   __ mflr(R31);
2366   __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::trace_bytecode), /* unused */ R4_ARG2, R5_ARG3, R6_ARG4, false);
2367   __ mtlr(R31);
2368   __ pop(state);
2369 
2370   if (TraceBytecodesAt > 0) {
2371     __ bind(Lskip_vm_call);
2372   }
2373   __ blr();
2374   BLOCK_COMMENT("} trace_code");
2375   return entry;
2376 }
2377 #endif //PRODUCT
2378 
2379 void TemplateInterpreterGenerator::count_bytecode() {
2380   int offs = __ load_const_optimized(R11_scratch1, (address) &BytecodeCounter::_counter_value, R12_scratch2, true);
2381   __ ld(R12_scratch2, offs, R11_scratch1);
2382   __ addi(R12_scratch2, R12_scratch2, 1);
2383   __ std(R12_scratch2, offs, R11_scratch1);
2384 }
2385 
2386 void TemplateInterpreterGenerator::histogram_bytecode(Template* t) {
2387   int offs = __ load_const_optimized(R11_scratch1, (address) &BytecodeHistogram::_counters[t->bytecode()], R12_scratch2, true);
2388   __ lwz(R12_scratch2, offs, R11_scratch1);
2389   __ addi(R12_scratch2, R12_scratch2, 1);
2390   __ stw(R12_scratch2, offs, R11_scratch1);
2391 }
2392 
2393 #ifndef PRODUCT
2394 void TemplateInterpreterGenerator::histogram_bytecode_pair(Template* t) {
2395   const Register addr = R11_scratch1,
2396                  tmp  = R12_scratch2;
2397   // Get index, shift out old bytecode, bring in new bytecode, and store it.
2398   // _index = (_index >> log2_number_of_codes) |
2399   //          (bytecode << log2_number_of_codes);
2400   int offs1 = __ load_const_optimized(addr, (address)&BytecodePairHistogram::_index, tmp, true);
2401   __ lwz(tmp, offs1, addr);
2402   __ srwi(tmp, tmp, BytecodePairHistogram::log2_number_of_codes);
2403   __ ori(tmp, tmp, ((int) t->bytecode()) << BytecodePairHistogram::log2_number_of_codes);
2404   __ stw(tmp, offs1, addr);
2405 
2406   // Bump bucket contents.
2407   // _counters[_index] ++;
2408   int offs2 = __ load_const_optimized(addr, (address)&BytecodePairHistogram::_counters, R0, true);
2409   __ sldi(tmp, tmp, LogBytesPerInt);
2410   __ add(addr, tmp, addr);
2411   __ lwz(tmp, offs2, addr);
2412   __ addi(tmp, tmp, 1);
2413   __ stw(tmp, offs2, addr);
< prev index next >