< 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 >