--- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp Thu Dec 14 12:02:16 2017 +0100
+++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp Thu Dec 14 13:05:20 2017 +0100
@@ -214,6 +214,7 @@
// 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;
@@ -233,16 +234,17 @@
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);
+ // Save some registers in the last slots of the not yet pushed frame so that we
+ // can use them as scratch regs.
+ __ 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(R31);
- __ std(R31, _abi(cr), R1_SP);
+ __ 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;
@@ -257,7 +259,7 @@
}
// push a new frame
- __ push_frame(frame_size_in_bytes, R31);
+ __ push_frame(frame_size_in_bytes, R30);
// save all registers (ints and floats)
offset = register_save_offset;
@@ -267,7 +269,7 @@
switch (reg_type) {
case RegisterSaver::int_reg: {
- if (reg_num != 31) { // We spilled R31 right at the beginning.
+ if (reg_num < 30) { // We spilled R30-31 right at the beginning.
__ std(as_Register(reg_num), offset, R1_SP);
}
break;
@@ -278,8 +280,8 @@
}
case RegisterSaver::special_reg: {
if (reg_num == SR_CTR_SpecialRegisterEnumValue) {
- __ mfctr(R31);
- __ std(R31, offset, R1_SP);
+ __ mfctr(R30);
+ __ std(R30, offset, R1_SP);
} else {
Unimplemented();
}
@@ -2364,23 +2366,14 @@
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);
-
+ // 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));
-
- __ 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
@@ -2388,6 +2381,7 @@
// 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)
@@ -2410,7 +2404,7 @@
// Transition from _thread_in_native_trans to _thread_in_Java.
__ li(R0, _thread_in_Java);
- __ release();
+ __ 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);
@@ -3093,7 +3087,7 @@
return_pc_location = RegisterSaver::return_pc_is_thread_saved_exception_pc;
}
- // Save registers, fpu state, and flags.
+ // 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,
@@ -3142,6 +3136,19 @@
// 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,