changeset 51582:7f462e8383f6

8206003: SafepointSynchronize with TLH: StoreStore barriers should be moved out of the loop Reviewed-by: eosterlund, rehn, dholmes
author mdoerr
date Mon, 02 Jul 2018 11:46:15 +0200
parents d9160a3c97c1
children c418c173158e
files src/hotspot/share/runtime/handshake.cpp src/hotspot/share/runtime/safepoint.cpp src/hotspot/share/runtime/safepointMechanism.hpp src/hotspot/share/runtime/safepointMechanism.inline.hpp src/hotspot/share/runtime/thread.hpp src/hotspot/share/runtime/thread.inline.hpp
diffstat 6 files changed, 24 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/runtime/handshake.cpp	Mon Jul 02 09:38:20 2018 +0200
+++ b/src/hotspot/share/runtime/handshake.cpp	Mon Jul 02 11:46:15 2018 +0200
@@ -297,12 +297,12 @@
 
 void HandshakeState::set_operation(JavaThread* target, HandshakeOperation* op) {
   _operation = op;
-  SafepointMechanism::arm_local_poll(target);
+  SafepointMechanism::arm_local_poll_release(target);
 }
 
 void HandshakeState::clear_handshake(JavaThread* target) {
   _operation = NULL;
-  SafepointMechanism::disarm_local_poll(target);
+  SafepointMechanism::disarm_local_poll_release(target);
 }
 
 void HandshakeState::process_self_inner(JavaThread* thread) {
--- a/src/hotspot/share/runtime/safepoint.cpp	Mon Jul 02 09:38:20 2018 +0200
+++ b/src/hotspot/share/runtime/safepoint.cpp	Mon Jul 02 11:46:15 2018 +0200
@@ -243,9 +243,10 @@
     if (SafepointMechanism::uses_thread_local_poll()) {
       // Arming the per thread poll while having _state != _not_synchronized means safepointing
       log_trace(safepoint)("Setting thread local yield flag for threads");
+      OrderAccess::storestore(); // storestore, global state -> local state
       for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur = jtiwh.next(); ) {
         // Make sure the threads start polling, it is time to yield.
-        SafepointMechanism::arm_local_poll(cur); // release store, global state -> local state
+        SafepointMechanism::arm_local_poll(cur);
       }
     }
     OrderAccess::fence(); // storestore|storeload, global state -> local state
@@ -546,7 +547,7 @@
         for (; JavaThread *current = jtiwh.next(); ) {
           ThreadSafepointState* cur_state = current->safepoint_state();
           cur_state->restart(); // TSS _running
-          SafepointMechanism::disarm_local_poll(current); // release store, local state -> polling page
+          SafepointMechanism::disarm_local_poll(current);
         }
         log_info(safepoint)("Leaving safepoint region");
       } else {
--- a/src/hotspot/share/runtime/safepointMechanism.hpp	Mon Jul 02 09:38:20 2018 +0200
+++ b/src/hotspot/share/runtime/safepointMechanism.hpp	Mon Jul 02 11:46:15 2018 +0200
@@ -79,9 +79,13 @@
   // Blocks a thread until safepoint is completed
   static inline void block_if_requested(JavaThread* thread);
 
+  // Caller is responsible for using a memory barrier if needed.
   static inline void arm_local_poll(JavaThread* thread);
   static inline void disarm_local_poll(JavaThread* thread);
 
+  static inline void arm_local_poll_release(JavaThread* thread);
+  static inline void disarm_local_poll_release(JavaThread* thread);
+
   // Setup the selected safepoint mechanism
   static void initialize();
   static void initialize_header(JavaThread* thread);
--- a/src/hotspot/share/runtime/safepointMechanism.inline.hpp	Mon Jul 02 09:38:20 2018 +0200
+++ b/src/hotspot/share/runtime/safepointMechanism.inline.hpp	Mon Jul 02 11:46:15 2018 +0200
@@ -87,4 +87,12 @@
   thread->set_polling_page(poll_disarmed_value());
 }
 
+void SafepointMechanism::arm_local_poll_release(JavaThread* thread) {
+  thread->set_polling_page_release(poll_armed_value());
+}
+
+void SafepointMechanism::disarm_local_poll_release(JavaThread* thread) {
+  thread->set_polling_page_release(poll_disarmed_value());
+}
+
 #endif // SHARE_VM_RUNTIME_SAFEPOINTMECHANISM_INLINE_HPP
--- a/src/hotspot/share/runtime/thread.hpp	Mon Jul 02 09:38:20 2018 +0200
+++ b/src/hotspot/share/runtime/thread.hpp	Mon Jul 02 11:46:15 2018 +0200
@@ -1207,6 +1207,7 @@
   bool do_not_unlock_if_synchronized()             { return _do_not_unlock_if_synchronized; }
   void set_do_not_unlock_if_synchronized(bool val) { _do_not_unlock_if_synchronized = val; }
 
+  inline void set_polling_page_release(void* poll_value);
   inline void set_polling_page(void* poll_value);
   inline volatile void* get_polling_page();
 
--- a/src/hotspot/share/runtime/thread.inline.hpp	Mon Jul 02 09:38:20 2018 +0200
+++ b/src/hotspot/share/runtime/thread.inline.hpp	Mon Jul 02 11:46:15 2018 +0200
@@ -170,8 +170,13 @@
 
 // The release make sure this store is done after storing the handshake
 // operation or global state
+inline void JavaThread::set_polling_page_release(void* poll_value) {
+  OrderAccess::release_store(polling_page_addr(), poll_value);
+}
+
+// Caller is responsible for using a memory barrier if needed.
 inline void JavaThread::set_polling_page(void* poll_value) {
-  OrderAccess::release_store(polling_page_addr(), poll_value);
+  *polling_page_addr() = poll_value;
 }
 
 // The aqcquire make sure reading of polling page is done before