< prev index next >

src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp

Print this page

2260 
2261   // Check ic: object class == cached class?
2262   if (!method_is_static) {
2263   Register ic = R19_inline_cache_reg;
2264   Register receiver_klass = r_temp_1;
2265 
2266   __ cmpdi(CCR0, R3_ARG1, 0);
2267   __ beq(CCR0, ic_miss);
2268   __ verify_oop(R3_ARG1, FILE_AND_LINE);
2269   __ load_klass(receiver_klass, R3_ARG1);
2270 
2271   __ cmpd(CCR0, receiver_klass, ic);
2272   __ bne(CCR0, ic_miss);
2273   }
2274 
2275 
2276   // Generate the Verified Entry Point (VEP).
2277   // --------------------------------------------------------------------------
2278   vep_start_pc = (intptr_t)__ pc();
2279 
2280   if (UseRTMLocking) {
2281     // Abort RTM transaction before calling JNI
2282     // because critical section can be large and
2283     // abort anyway. Also nmethod can be deoptimized.
2284     __ tabort_();
2285   }
2286 
2287   if (VM_Version::supports_fast_class_init_checks() && method->needs_clinit_barrier()) {
2288     Label L_skip_barrier;
2289     Register klass = r_temp_1;
2290     // Notify OOP recorder (don't need the relocation)
2291     AddressLiteral md = __ constant_metadata_address(method->method_holder());
2292     __ load_const_optimized(klass, md.value(), R0);
2293     __ clinit_barrier(klass, R16_thread, &L_skip_barrier /*L_fast_path*/);
2294 
2295     __ load_const_optimized(klass, SharedRuntime::get_handle_wrong_method_stub(), R0);
2296     __ mtctr(klass);
2297     __ bctr();
2298 
2299     __ bind(L_skip_barrier);
2300   }
2301 
2302   __ save_LR_CR(r_temp_1);
2303   __ generate_stack_overflow_check(frame_size_in_bytes); // Check before creating frame.
2304   __ mr(r_callers_sp, R1_SP);                            // Remember frame pointer.
2305   __ push_frame(frame_size_in_bytes, r_temp_1);          // Push the c2n adapter's frame.
2306 

2453   // DTrace method entry
2454 # endif
2455 
2456   // Lock a synchronized method.
2457   // --------------------------------------------------------------------------
2458 
2459   if (method->is_synchronized()) {
2460     Register          r_oop  = r_temp_4;
2461     const Register    r_box  = r_temp_5;
2462     Label             done, locked;
2463 
2464     // Load the oop for the object or class. r_carg2_classorobject contains
2465     // either the handlized oop from the incoming arguments or the handlized
2466     // class mirror (if the method is static).
2467     __ ld(r_oop, 0, r_carg2_classorobject);
2468 
2469     // Get the lock box slot's address.
2470     __ addi(r_box, R1_SP, lock_offset);
2471 
2472     // Try fastpath for locking.
2473     // fast_lock kills r_temp_1, r_temp_2, r_temp_3.
2474     __ compiler_fast_lock_object(CCR0, r_oop, r_box, r_temp_1, r_temp_2, r_temp_3);





2475     __ beq(CCR0, locked);
2476 
2477     // None of the above fast optimizations worked so we have to get into the
2478     // slow case of monitor enter. Inline a special case of call_VM that
2479     // disallows any pending_exception.
2480 
2481     // Save argument registers and leave room for C-compatible ABI_REG_ARGS.
2482     int frame_size = frame::native_abi_reg_args_size + align_up(total_c_args * wordSize, frame::alignment_in_bytes);
2483     __ mr(R11_scratch1, R1_SP);
2484     RegisterSaver::push_frame_and_save_argument_registers(masm, R12_scratch2, frame_size, total_c_args, out_regs, out_regs2);
2485 
2486     // Do the call.
2487     __ set_last_Java_frame(R11_scratch1, r_return_pc);
2488     assert(r_return_pc->is_nonvolatile(), "expecting return pc to be in non-volatile register");
2489     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_locking_C), r_oop, r_box, R16_thread);
2490     __ reset_last_Java_frame();
2491 
2492     RegisterSaver::restore_argument_registers_and_pop_frame(masm, frame_size, total_c_args, out_regs, out_regs2);
2493 
2494     __ asm_assert_mem8_is_zero(thread_(pending_exception),

2664   // Unlock
2665   // --------------------------------------------------------------------------
2666 
2667   if (method->is_synchronized()) {
2668     const Register r_oop       = r_temp_4;
2669     const Register r_box       = r_temp_5;
2670     const Register r_exception = r_temp_6;
2671     Label done;
2672 
2673     // Get oop and address of lock object box.
2674     if (method_is_static) {
2675       assert(klass_offset != -1, "");
2676       __ ld(r_oop, klass_offset, R1_SP);
2677     } else {
2678       assert(receiver_offset != -1, "");
2679       __ ld(r_oop, receiver_offset, R1_SP);
2680     }
2681     __ addi(r_box, R1_SP, lock_offset);
2682 
2683     // Try fastpath for unlocking.
2684     __ compiler_fast_unlock_object(CCR0, r_oop, r_box, r_temp_1, r_temp_2, r_temp_3);




2685     __ beq(CCR0, done);
2686 
2687     // Save and restore any potential method result value around the unlocking operation.
2688     save_native_result(masm, ret_type, workspace_slot_offset);
2689 
2690     // Must save pending exception around the slow-path VM call. Since it's a
2691     // leaf call, the pending exception (if any) can be kept in a register.
2692     __ ld(r_exception, thread_(pending_exception));
2693     assert(r_exception->is_nonvolatile(), "exception register must be non-volatile");
2694     __ li(R0, 0);
2695     __ std(R0, thread_(pending_exception));
2696 
2697     // Slow case of monitor enter.
2698     // Inline a special case of call_VM that disallows any pending_exception.
2699     // Arguments are (oop obj, BasicLock* lock, JavaThread* thread).
2700     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C), r_oop, r_box, R16_thread);
2701 
2702     __ asm_assert_mem8_is_zero(thread_(pending_exception),
2703        "no pending exception allowed on exit from SharedRuntime::complete_monitor_unlocking_C");
2704 

3148   __ flush();
3149 #else // COMPILER2
3150   __ unimplemented("deopt blob needed only with compiler");
3151   int exception_offset = __ pc() - start;
3152 #endif // COMPILER2
3153 
3154   _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset,
3155                                            reexecute_offset, first_frame_size_in_bytes / wordSize);
3156   _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
3157 }
3158 
3159 #ifdef COMPILER2
3160 void SharedRuntime::generate_uncommon_trap_blob() {
3161   // Allocate space for the code.
3162   ResourceMark rm;
3163   // Setup code generation tools.
3164   CodeBuffer buffer("uncommon_trap_blob", 2048, 1024);
3165   InterpreterMacroAssembler* masm = new InterpreterMacroAssembler(&buffer);
3166   address start = __ pc();
3167 
3168   if (UseRTMLocking) {
3169     // Abort RTM transaction before possible nmethod deoptimization.
3170     __ tabort_();
3171   }
3172 
3173   Register unroll_block_reg = R21_tmp1;
3174   Register klass_index_reg  = R22_tmp2;
3175   Register unc_trap_reg     = R23_tmp3;
3176   Register r_return_pc      = R27_tmp7;
3177 
3178   OopMapSet* oop_maps = new OopMapSet();
3179   int frame_size_in_bytes = frame::native_abi_reg_args_size;
3180   OopMap* map = new OopMap(frame_size_in_bytes / sizeof(jint), 0);
3181 
3182   // stack: (deoptee, optional i2c, caller_of_deoptee, ...).
3183 
3184   // Push a dummy `unpack_frame' and call
3185   // `Deoptimization::uncommon_trap' to pack the compiled frame into a
3186   // vframe array and return the `UnrollBlock' information.
3187 
3188   // Save LR to compiled frame.
3189   __ save_LR_CR(R11_scratch1);
3190 
3191   // Push an "uncommon_trap" frame.
3192   __ push_frame_reg_args(0, R11_scratch1);

3303   OopMap* map;
3304 
3305   // Allocate space for the code. Setup code generation tools.
3306   CodeBuffer buffer("handler_blob", 2048, 1024);
3307   MacroAssembler* masm = new MacroAssembler(&buffer);
3308 
3309   address start = __ pc();
3310   int frame_size_in_bytes = 0;
3311 
3312   RegisterSaver::ReturnPCLocation return_pc_location;
3313   bool cause_return = (poll_type == POLL_AT_RETURN);
3314   if (cause_return) {
3315     // Nothing to do here. The frame has already been popped in MachEpilogNode.
3316     // Register LR already contains the return pc.
3317     return_pc_location = RegisterSaver::return_pc_is_pre_saved;
3318   } else {
3319     // Use thread()->saved_exception_pc() as return pc.
3320     return_pc_location = RegisterSaver::return_pc_is_thread_saved_exception_pc;
3321   }
3322 
3323   if (UseRTMLocking) {
3324     // Abort RTM transaction before calling runtime
3325     // because critical section can be large and so
3326     // will abort anyway. Also nmethod can be deoptimized.
3327     __ tabort_();
3328   }
3329 
3330   bool save_vectors = (poll_type == POLL_AT_VECTOR_LOOP);
3331 
3332   // Save registers, fpu state, and flags. Set R31 = return pc.
3333   map = RegisterSaver::push_frame_reg_args_and_save_live_registers(masm,
3334                                                                    &frame_size_in_bytes,
3335                                                                    /*generate_oop_map=*/ true,
3336                                                                    /*return_pc_adjustment=*/0,
3337                                                                    return_pc_location, save_vectors);
3338 
3339   // The following is basically a call_VM. However, we need the precise
3340   // address of the call in order to generate an oopmap. Hence, we do all the
3341   // work ourselves.
3342   __ set_last_Java_frame(/*sp=*/R1_SP, /*pc=*/noreg);
3343 
3344   // The return address must always be correct so that the frame constructor
3345   // never sees an invalid pc.
3346 
3347   // Do the call
3348   __ call_VM_leaf(call_ptr, R16_thread);
3349   address calls_return_pc = __ last_calls_return_pc();

2260 
2261   // Check ic: object class == cached class?
2262   if (!method_is_static) {
2263   Register ic = R19_inline_cache_reg;
2264   Register receiver_klass = r_temp_1;
2265 
2266   __ cmpdi(CCR0, R3_ARG1, 0);
2267   __ beq(CCR0, ic_miss);
2268   __ verify_oop(R3_ARG1, FILE_AND_LINE);
2269   __ load_klass(receiver_klass, R3_ARG1);
2270 
2271   __ cmpd(CCR0, receiver_klass, ic);
2272   __ bne(CCR0, ic_miss);
2273   }
2274 
2275 
2276   // Generate the Verified Entry Point (VEP).
2277   // --------------------------------------------------------------------------
2278   vep_start_pc = (intptr_t)__ pc();
2279 







2280   if (VM_Version::supports_fast_class_init_checks() && method->needs_clinit_barrier()) {
2281     Label L_skip_barrier;
2282     Register klass = r_temp_1;
2283     // Notify OOP recorder (don't need the relocation)
2284     AddressLiteral md = __ constant_metadata_address(method->method_holder());
2285     __ load_const_optimized(klass, md.value(), R0);
2286     __ clinit_barrier(klass, R16_thread, &L_skip_barrier /*L_fast_path*/);
2287 
2288     __ load_const_optimized(klass, SharedRuntime::get_handle_wrong_method_stub(), R0);
2289     __ mtctr(klass);
2290     __ bctr();
2291 
2292     __ bind(L_skip_barrier);
2293   }
2294 
2295   __ save_LR_CR(r_temp_1);
2296   __ generate_stack_overflow_check(frame_size_in_bytes); // Check before creating frame.
2297   __ mr(r_callers_sp, R1_SP);                            // Remember frame pointer.
2298   __ push_frame(frame_size_in_bytes, r_temp_1);          // Push the c2n adapter's frame.
2299 

2446   // DTrace method entry
2447 # endif
2448 
2449   // Lock a synchronized method.
2450   // --------------------------------------------------------------------------
2451 
2452   if (method->is_synchronized()) {
2453     Register          r_oop  = r_temp_4;
2454     const Register    r_box  = r_temp_5;
2455     Label             done, locked;
2456 
2457     // Load the oop for the object or class. r_carg2_classorobject contains
2458     // either the handlized oop from the incoming arguments or the handlized
2459     // class mirror (if the method is static).
2460     __ ld(r_oop, 0, r_carg2_classorobject);
2461 
2462     // Get the lock box slot's address.
2463     __ addi(r_box, R1_SP, lock_offset);
2464 
2465     // Try fastpath for locking.
2466     if (LockingMode == LM_LIGHTWEIGHT) {
2467       // fast_lock kills r_temp_1, r_temp_2, r_temp_3.
2468       __ compiler_fast_lock_lightweight_object(CCR0, r_oop, r_temp_1, r_temp_2, r_temp_3);
2469     } else {
2470       // fast_lock kills r_temp_1, r_temp_2, r_temp_3.
2471       __ compiler_fast_lock_object(CCR0, r_oop, r_box, r_temp_1, r_temp_2, r_temp_3);
2472     }
2473     __ beq(CCR0, locked);
2474 
2475     // None of the above fast optimizations worked so we have to get into the
2476     // slow case of monitor enter. Inline a special case of call_VM that
2477     // disallows any pending_exception.
2478 
2479     // Save argument registers and leave room for C-compatible ABI_REG_ARGS.
2480     int frame_size = frame::native_abi_reg_args_size + align_up(total_c_args * wordSize, frame::alignment_in_bytes);
2481     __ mr(R11_scratch1, R1_SP);
2482     RegisterSaver::push_frame_and_save_argument_registers(masm, R12_scratch2, frame_size, total_c_args, out_regs, out_regs2);
2483 
2484     // Do the call.
2485     __ set_last_Java_frame(R11_scratch1, r_return_pc);
2486     assert(r_return_pc->is_nonvolatile(), "expecting return pc to be in non-volatile register");
2487     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_locking_C), r_oop, r_box, R16_thread);
2488     __ reset_last_Java_frame();
2489 
2490     RegisterSaver::restore_argument_registers_and_pop_frame(masm, frame_size, total_c_args, out_regs, out_regs2);
2491 
2492     __ asm_assert_mem8_is_zero(thread_(pending_exception),

2662   // Unlock
2663   // --------------------------------------------------------------------------
2664 
2665   if (method->is_synchronized()) {
2666     const Register r_oop       = r_temp_4;
2667     const Register r_box       = r_temp_5;
2668     const Register r_exception = r_temp_6;
2669     Label done;
2670 
2671     // Get oop and address of lock object box.
2672     if (method_is_static) {
2673       assert(klass_offset != -1, "");
2674       __ ld(r_oop, klass_offset, R1_SP);
2675     } else {
2676       assert(receiver_offset != -1, "");
2677       __ ld(r_oop, receiver_offset, R1_SP);
2678     }
2679     __ addi(r_box, R1_SP, lock_offset);
2680 
2681     // Try fastpath for unlocking.
2682     if (LockingMode == LM_LIGHTWEIGHT) {
2683       __ compiler_fast_unlock_lightweight_object(CCR0, r_oop, r_temp_1, r_temp_2, r_temp_3);
2684     } else {
2685       __ compiler_fast_unlock_object(CCR0, r_oop, r_box, r_temp_1, r_temp_2, r_temp_3);
2686     }
2687     __ beq(CCR0, done);
2688 
2689     // Save and restore any potential method result value around the unlocking operation.
2690     save_native_result(masm, ret_type, workspace_slot_offset);
2691 
2692     // Must save pending exception around the slow-path VM call. Since it's a
2693     // leaf call, the pending exception (if any) can be kept in a register.
2694     __ ld(r_exception, thread_(pending_exception));
2695     assert(r_exception->is_nonvolatile(), "exception register must be non-volatile");
2696     __ li(R0, 0);
2697     __ std(R0, thread_(pending_exception));
2698 
2699     // Slow case of monitor enter.
2700     // Inline a special case of call_VM that disallows any pending_exception.
2701     // Arguments are (oop obj, BasicLock* lock, JavaThread* thread).
2702     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C), r_oop, r_box, R16_thread);
2703 
2704     __ asm_assert_mem8_is_zero(thread_(pending_exception),
2705        "no pending exception allowed on exit from SharedRuntime::complete_monitor_unlocking_C");
2706 

3150   __ flush();
3151 #else // COMPILER2
3152   __ unimplemented("deopt blob needed only with compiler");
3153   int exception_offset = __ pc() - start;
3154 #endif // COMPILER2
3155 
3156   _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset,
3157                                            reexecute_offset, first_frame_size_in_bytes / wordSize);
3158   _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
3159 }
3160 
3161 #ifdef COMPILER2
3162 void SharedRuntime::generate_uncommon_trap_blob() {
3163   // Allocate space for the code.
3164   ResourceMark rm;
3165   // Setup code generation tools.
3166   CodeBuffer buffer("uncommon_trap_blob", 2048, 1024);
3167   InterpreterMacroAssembler* masm = new InterpreterMacroAssembler(&buffer);
3168   address start = __ pc();
3169 





3170   Register unroll_block_reg = R21_tmp1;
3171   Register klass_index_reg  = R22_tmp2;
3172   Register unc_trap_reg     = R23_tmp3;
3173   Register r_return_pc      = R27_tmp7;
3174 
3175   OopMapSet* oop_maps = new OopMapSet();
3176   int frame_size_in_bytes = frame::native_abi_reg_args_size;
3177   OopMap* map = new OopMap(frame_size_in_bytes / sizeof(jint), 0);
3178 
3179   // stack: (deoptee, optional i2c, caller_of_deoptee, ...).
3180 
3181   // Push a dummy `unpack_frame' and call
3182   // `Deoptimization::uncommon_trap' to pack the compiled frame into a
3183   // vframe array and return the `UnrollBlock' information.
3184 
3185   // Save LR to compiled frame.
3186   __ save_LR_CR(R11_scratch1);
3187 
3188   // Push an "uncommon_trap" frame.
3189   __ push_frame_reg_args(0, R11_scratch1);

3300   OopMap* map;
3301 
3302   // Allocate space for the code. Setup code generation tools.
3303   CodeBuffer buffer("handler_blob", 2048, 1024);
3304   MacroAssembler* masm = new MacroAssembler(&buffer);
3305 
3306   address start = __ pc();
3307   int frame_size_in_bytes = 0;
3308 
3309   RegisterSaver::ReturnPCLocation return_pc_location;
3310   bool cause_return = (poll_type == POLL_AT_RETURN);
3311   if (cause_return) {
3312     // Nothing to do here. The frame has already been popped in MachEpilogNode.
3313     // Register LR already contains the return pc.
3314     return_pc_location = RegisterSaver::return_pc_is_pre_saved;
3315   } else {
3316     // Use thread()->saved_exception_pc() as return pc.
3317     return_pc_location = RegisterSaver::return_pc_is_thread_saved_exception_pc;
3318   }
3319 







3320   bool save_vectors = (poll_type == POLL_AT_VECTOR_LOOP);
3321 
3322   // Save registers, fpu state, and flags. Set R31 = return pc.
3323   map = RegisterSaver::push_frame_reg_args_and_save_live_registers(masm,
3324                                                                    &frame_size_in_bytes,
3325                                                                    /*generate_oop_map=*/ true,
3326                                                                    /*return_pc_adjustment=*/0,
3327                                                                    return_pc_location, save_vectors);
3328 
3329   // The following is basically a call_VM. However, we need the precise
3330   // address of the call in order to generate an oopmap. Hence, we do all the
3331   // work ourselves.
3332   __ set_last_Java_frame(/*sp=*/R1_SP, /*pc=*/noreg);
3333 
3334   // The return address must always be correct so that the frame constructor
3335   // never sees an invalid pc.
3336 
3337   // Do the call
3338   __ call_VM_leaf(call_ptr, R16_thread);
3339   address calls_return_pc = __ last_calls_return_pc();
< prev index next >