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