< prev index next >
src/hotspot/cpu/sparc/sharedRuntime_sparc.cpp
Print this page
rev 47415 : Add Thread Local handshakes and thread local polling
@@ -2361,11 +2361,10 @@
// must we block?
// Block, if necessary, before resuming in _thread_in_Java state.
// In order for GC to work, don't clear the last_Java_sp until after blocking.
{ Label no_block;
- AddressLiteral sync_state(SafepointSynchronize::address_of_state());
// Switch thread to "native transition" state before reading the synchronization state.
// This additional state is necessary because reading and testing the synchronization
// state is not atomic w.r.t. GC, as this scenario demonstrates:
// Java thread A, in _thread_in_native state, loads _not_synchronized and is preempted.
@@ -2384,16 +2383,14 @@
// offset to write to within the page. This minimizes bus traffic
// due to cache line collision.
__ serialize_memory(G2_thread, G1_scratch, G3_scratch);
}
}
- __ load_contents(sync_state, G3_scratch);
- __ cmp(G3_scratch, SafepointSynchronize::_not_synchronized);
Label L;
Address suspend_state(G2_thread, JavaThread::suspend_flags_offset());
- __ br(Assembler::notEqual, false, Assembler::pn, L);
+ __ safepoint_poll(L, false, G2_thread, G3_scratch);
__ delayed()->ld(suspend_state, G3_scratch);
__ cmp_and_br_short(G3_scratch, 0, Assembler::equal, Assembler::pt, no_block);
__ bind(L);
// Block. Save any potential method result value before the operation and
@@ -3120,19 +3117,28 @@
if (cause_return) {
__ restore();
} else {
// Make it look like we were called via the poll
// so that frame constructor always sees a valid return address
- __ ld_ptr(G2_thread, in_bytes(JavaThread::saved_exception_pc_offset()), O7);
+ __ ld_ptr(Address(G2_thread, JavaThread::saved_exception_pc_offset()), O7);
__ sub(O7, frame::pc_return_offset, O7);
}
map = RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
// setup last_Java_sp (blows G4)
__ set_last_Java_frame(SP, noreg);
+ Register saved_O7 = O7->after_save();
+ if (!cause_return && SafepointMechanism::uses_thread_local_poll()) {
+ // Keep a copy of the return pc in L0 to detect if it gets modified
+ __ mov(saved_O7, L0);
+ // Adjust and keep a copy of our npc saved by the signal handler
+ __ ld_ptr(Address(G2_thread, JavaThread::saved_exception_npc_offset()), L1);
+ __ sub(L1, frame::pc_return_offset, L1);
+ }
+
// call into the runtime to handle illegal instructions exception
// Do not use call_VM_leaf, because we need to make a GC map at this call site.
__ mov(G2_thread, O0);
__ save_thread(L7_thread_cache);
__ call(call_ptr);
@@ -3152,10 +3158,16 @@
Label pending;
__ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O1);
__ br_notnull_short(O1, Assembler::pn, pending);
+ if (!cause_return && SafepointMechanism::uses_thread_local_poll()) {
+ // If nobody modified our return pc then we must return to the npc which he saved in L1
+ __ cmp(saved_O7, L0);
+ __ movcc(Assembler::equal, false, Assembler::ptr_cc, L1, saved_O7);
+ }
+
RegisterSaver::restore_live_registers(masm);
// We are back the the original state on entry and ready to go.
__ retl();
< prev index next >