< prev index next >

src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp

Print this page
rev 48251 : 8193257: PPC64, s390 implementation for Thread-local handshakes
Reviewed-by:

*** 212,221 **** --- 212,222 ---- // callee-save values in an OopMap so their save locations will be // propagated to the RegisterMap of the caller frame during // StackFrameStream construction (needed for deoptimization; see // compiledVFrame::create_stack_value). // If return_pc_adjustment != 0 adjust the return pc by return_pc_adjustment. + // Updated return pc is returned in R31 (if not return_pc_is_pre_saved). int i; int offset; // calcualte frame size
*** 233,250 **** BLOCK_COMMENT("push_frame_reg_args_and_save_live_registers {"); // Save r31 in the last slot of the not yet pushed frame so that we // can use it as scratch reg. ! __ std(R31, -reg_size, R1_SP); assert(-reg_size == register_save_offset - frame_size_in_bytes + ((regstosave_num-1)*reg_size), "consistency check"); // save the flags // Do the save_LR_CR by hand and adjust the return pc if requested. ! __ mfcr(R31); ! __ std(R31, _abi(cr), R1_SP); switch (return_pc_location) { case return_pc_is_lr: __ mflr(R31); break; case return_pc_is_pre_saved: assert(return_pc_adjustment == 0, "unsupported"); break; case return_pc_is_thread_saved_exception_pc: __ ld(R31, thread_(saved_exception_pc)); break; default: ShouldNotReachHere(); --- 234,252 ---- BLOCK_COMMENT("push_frame_reg_args_and_save_live_registers {"); // Save r31 in the last slot of the not yet pushed frame so that we // can use it as scratch reg. ! __ std(R31, - reg_size, R1_SP); ! __ std(R30, -2*reg_size, R1_SP); assert(-reg_size == register_save_offset - frame_size_in_bytes + ((regstosave_num-1)*reg_size), "consistency check"); // save the flags // Do the save_LR_CR by hand and adjust the return pc if requested. ! __ mfcr(R30); ! __ std(R30, _abi(cr), R1_SP); switch (return_pc_location) { case return_pc_is_lr: __ mflr(R31); break; case return_pc_is_pre_saved: assert(return_pc_adjustment == 0, "unsupported"); break; case return_pc_is_thread_saved_exception_pc: __ ld(R31, thread_(saved_exception_pc)); break; default: ShouldNotReachHere();
*** 255,287 **** } __ std(R31, _abi(lr), R1_SP); } // push a new frame ! __ push_frame(frame_size_in_bytes, R31); // save all registers (ints and floats) offset = register_save_offset; for (int i = 0; i < regstosave_num; i++) { int reg_num = RegisterSaver_LiveRegs[i].reg_num; int reg_type = RegisterSaver_LiveRegs[i].reg_type; switch (reg_type) { case RegisterSaver::int_reg: { ! if (reg_num != 31) { // We spilled R31 right at the beginning. __ std(as_Register(reg_num), offset, R1_SP); } break; } case RegisterSaver::float_reg: { __ stfd(as_FloatRegister(reg_num), offset, R1_SP); break; } case RegisterSaver::special_reg: { if (reg_num == SR_CTR_SpecialRegisterEnumValue) { ! __ mfctr(R31); ! __ std(R31, offset, R1_SP); } else { Unimplemented(); } break; } --- 257,289 ---- } __ std(R31, _abi(lr), R1_SP); } // push a new frame ! __ push_frame(frame_size_in_bytes, R30); // save all registers (ints and floats) offset = register_save_offset; for (int i = 0; i < regstosave_num; i++) { int reg_num = RegisterSaver_LiveRegs[i].reg_num; int reg_type = RegisterSaver_LiveRegs[i].reg_type; switch (reg_type) { case RegisterSaver::int_reg: { ! if (reg_num < 30) { // We spilled R30-31 right at the beginning. __ std(as_Register(reg_num), offset, R1_SP); } break; } case RegisterSaver::float_reg: { __ stfd(as_FloatRegister(reg_num), offset, R1_SP); break; } case RegisterSaver::special_reg: { if (reg_num == SR_CTR_SpecialRegisterEnumValue) { ! __ mfctr(R30); ! __ std(R30, offset, R1_SP); } else { Unimplemented(); } break; }
*** 2362,2395 **** Register sync_state_addr = r_temp_4; Register sync_state = r_temp_5; Register suspend_flags = r_temp_6; ! __ load_const(sync_state_addr, SafepointSynchronize::address_of_state(), /*temp*/ sync_state); ! ! // TODO: PPC port assert(4 == SafepointSynchronize::sz_state(), "unexpected field size"); ! __ lwz(sync_state, 0, sync_state_addr); // TODO: PPC port assert(4 == Thread::sz_suspend_flags(), "unexpected field size"); __ lwz(suspend_flags, thread_(suspend_flags)); - - __ acquire(); - - Label do_safepoint; - // No synchronization in progress nor yet synchronized. - __ cmpwi(CCR0, sync_state, SafepointSynchronize::_not_synchronized); - // Not suspended. __ cmpwi(CCR1, suspend_flags, 0); - - __ bne(CCR0, sync); __ beq(CCR1, no_block); // Block. Save any potential method result value before the operation and // use a leaf call to leave the last_Java_frame setup undisturbed. Doing this // lets us share the oopMap we used when we went native rather than create // a distinct one for this pc. __ bind(sync); address entry_point = is_critical_native ? CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans_and_transition) : CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans); save_native_result(masm, ret_type, workspace_slot_offset); --- 2364,2389 ---- Register sync_state_addr = r_temp_4; Register sync_state = r_temp_5; Register suspend_flags = r_temp_6; ! // No synchronization in progress nor yet synchronized ! // (cmp-br-isync on one path, release (same as acquire on PPC64) on the other path). ! __ safepoint_poll(sync, sync_state); + // Not suspended. // TODO: PPC port assert(4 == Thread::sz_suspend_flags(), "unexpected field size"); __ lwz(suspend_flags, thread_(suspend_flags)); __ cmpwi(CCR1, suspend_flags, 0); __ beq(CCR1, no_block); // Block. Save any potential method result value before the operation and // use a leaf call to leave the last_Java_frame setup undisturbed. Doing this // lets us share the oopMap we used when we went native rather than create // a distinct one for this pc. __ bind(sync); + __ isync(); address entry_point = is_critical_native ? CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans_and_transition) : CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans); save_native_result(masm, ret_type, workspace_slot_offset);
*** 2408,2418 **** // Thread state is thread_in_native_trans. Any safepoint blocking has // already happened so we can now change state to _thread_in_Java. // Transition from _thread_in_native_trans to _thread_in_Java. __ li(R0, _thread_in_Java); ! __ release(); // TODO: PPC port assert(4 == JavaThread::sz_thread_state(), "unexpected field size"); __ stw(R0, thread_(thread_state)); __ bind(after_transition); // Reguard any pages if necessary. --- 2402,2412 ---- // Thread state is thread_in_native_trans. Any safepoint blocking has // already happened so we can now change state to _thread_in_Java. // Transition from _thread_in_native_trans to _thread_in_Java. __ li(R0, _thread_in_Java); ! __ lwsync(); // Acquire safepoint and suspend state, release thread state. // TODO: PPC port assert(4 == JavaThread::sz_thread_state(), "unexpected field size"); __ stw(R0, thread_(thread_state)); __ bind(after_transition); // Reguard any pages if necessary.
*** 3091,3101 **** } else { // Use thread()->saved_exception_pc() as return pc. return_pc_location = RegisterSaver::return_pc_is_thread_saved_exception_pc; } ! // Save registers, fpu state, and flags. map = RegisterSaver::push_frame_reg_args_and_save_live_registers(masm, &frame_size_in_bytes, /*generate_oop_map=*/ true, /*return_pc_adjustment=*/0, return_pc_location); --- 3085,3095 ---- } else { // Use thread()->saved_exception_pc() as return pc. return_pc_location = RegisterSaver::return_pc_is_thread_saved_exception_pc; } ! // Save registers, fpu state, and flags. Set R31 = return pc. map = RegisterSaver::push_frame_reg_args_and_save_live_registers(masm, &frame_size_in_bytes, /*generate_oop_map=*/ true, /*return_pc_adjustment=*/0, return_pc_location);
*** 3140,3149 **** --- 3134,3156 ---- __ b64_patchable(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type); // No exception case. __ BIND(noException); + if (SafepointMechanism::uses_thread_local_poll() && !cause_return) { + Label no_adjust; + // If our stashed return pc was modified by the runtime we avoid touching it + __ ld(R0, frame_size_in_bytes + _abi(lr), R1_SP); + __ cmpd(CCR0, R0, R31); + __ bne(CCR0, no_adjust); + + // Adjust return pc forward to step over the safepoint poll instruction + __ addi(R31, R31, 4); + __ std(R31, frame_size_in_bytes + _abi(lr), R1_SP); + + __ bind(no_adjust); + } // Normal exit, restore registers and exit. RegisterSaver::restore_live_registers_and_pop_frame(masm, frame_size_in_bytes, /*restore_ctr=*/true);
< prev index next >