--- old/src/hotspot/share/gc/shared/oopStorage.cpp 2018-05-28 16:21:19.664954380 -0400 +++ new/src/hotspot/share/gc/shared/oopStorage.cpp 2018-05-28 16:21:19.404940833 -0400 @@ -40,6 +40,7 @@ #include "utilities/align.hpp" #include "utilities/count_trailing_zeros.hpp" #include "utilities/debug.hpp" +#include "utilities/globalCounter.inline.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" #include "utilities/ostream.hpp" @@ -501,48 +502,6 @@ return true; } -OopStorage::ProtectActive::ProtectActive() : _enter(0), _exit() {} - -// Begin read-side critical section. -uint OopStorage::ProtectActive::read_enter() { - return Atomic::add(2u, &_enter); -} - -// End read-side critical section. -void OopStorage::ProtectActive::read_exit(uint enter_value) { - Atomic::add(2u, &_exit[enter_value & 1]); -} - -// Wait until all readers that entered the critical section before -// synchronization have exited that critical section. -void OopStorage::ProtectActive::write_synchronize() { - SpinYield spinner; - // Determine old and new exit counters, based on bit0 of the - // on-entry _enter counter. - uint value = OrderAccess::load_acquire(&_enter); - volatile uint* new_ptr = &_exit[(value + 1) & 1]; - // Atomically change the in-use exit counter to the new counter, by - // adding 1 to the _enter counter (flipping bit0 between 0 and 1) - // and initializing the new exit counter to that enter value. Note: - // The new exit counter is not being used by read operations until - // this change succeeds. - uint old; - do { - old = value; - *new_ptr = ++value; - value = Atomic::cmpxchg(value, &_enter, old); - } while (old != value); - // Readers that entered the critical section before we changed the - // selected exit counter will use the old exit counter. Readers - // entering after the change will use the new exit counter. Wait - // for all the critical sections started before the change to - // complete, e.g. for the value of old_ptr to catch up with old. - volatile uint* old_ptr = &_exit[old & 1]; - while (old != OrderAccess::load_acquire(old_ptr)) { - spinner.wait(); - } -} - // Make new_array the _active_array. Increments new_array's refcount // to account for the new reference. The assignment is atomic wrto // obtain_active_array; once this function returns, it is safe for the @@ -554,9 +513,9 @@ // Install new_array, ensuring its initialization is complete first. OrderAccess::release_store(&_active_array, new_array); // Wait for any readers that could read the old array from _active_array. - _protect_active.write_synchronize(); - // All obtain critical sections that could see the old array have - // completed, having incremented the refcount of the old array. The + GlobalCounter::write_synchronize(); + // All obtain_actuve_array critical sections that could see the old array + // have completed, having incremented the refcount of the old array. The // caller can now safely relinquish the old array. } @@ -566,10 +525,9 @@ // _active_array. The caller must relinquish the array when done // using it. OopStorage::ActiveArray* OopStorage::obtain_active_array() const { - uint enter_value = _protect_active.read_enter(); + GlobalCounter::CriticalSection cs(Thread::current()); ActiveArray* result = OrderAccess::load_acquire(&_active_array); result->increment_refcount(); - _protect_active.read_exit(enter_value); return result; }