# HG changeset patch # User mdoerr # Date 1530524775 -7200 # Node ID 7f462e8383f6fa0aed50d2bb4568ee3f188b4783 # Parent d9160a3c97c17b78e145780ac1728693fa79bb36 8206003: SafepointSynchronize with TLH: StoreStore barriers should be moved out of the loop Reviewed-by: eosterlund, rehn, dholmes diff -r d9160a3c97c1 -r 7f462e8383f6 src/hotspot/share/runtime/handshake.cpp --- 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) { diff -r d9160a3c97c1 -r 7f462e8383f6 src/hotspot/share/runtime/safepoint.cpp --- 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 { diff -r d9160a3c97c1 -r 7f462e8383f6 src/hotspot/share/runtime/safepointMechanism.hpp --- 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); diff -r d9160a3c97c1 -r 7f462e8383f6 src/hotspot/share/runtime/safepointMechanism.inline.hpp --- 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 diff -r d9160a3c97c1 -r 7f462e8383f6 src/hotspot/share/runtime/thread.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(); diff -r d9160a3c97c1 -r 7f462e8383f6 src/hotspot/share/runtime/thread.inline.hpp --- 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