src/hotspot/share/gc/shared/oopStorage.cpp
changeset 51511 eb8d5aeabab3
parent 50954 f85092465b0c
child 51752 43323ced5e40
equal deleted inserted replaced
51510:6b0012622443 51511:eb8d5aeabab3
    41 #include "utilities/count_trailing_zeros.hpp"
    41 #include "utilities/count_trailing_zeros.hpp"
    42 #include "utilities/debug.hpp"
    42 #include "utilities/debug.hpp"
    43 #include "utilities/globalDefinitions.hpp"
    43 #include "utilities/globalDefinitions.hpp"
    44 #include "utilities/macros.hpp"
    44 #include "utilities/macros.hpp"
    45 #include "utilities/ostream.hpp"
    45 #include "utilities/ostream.hpp"
    46 #include "utilities/spinYield.hpp"
       
    47 
    46 
    48 OopStorage::AllocationListEntry::AllocationListEntry() : _prev(NULL), _next(NULL) {}
    47 OopStorage::AllocationListEntry::AllocationListEntry() : _prev(NULL), _next(NULL) {}
    49 
    48 
    50 OopStorage::AllocationListEntry::~AllocationListEntry() {
    49 OopStorage::AllocationListEntry::~AllocationListEntry() {
    51   assert(_prev == NULL, "deleting attached block");
    50   assert(_prev == NULL, "deleting attached block");
   493   replace_active_array(new_array);
   492   replace_active_array(new_array);
   494   relinquish_block_array(old_array);
   493   relinquish_block_array(old_array);
   495   return true;
   494   return true;
   496 }
   495 }
   497 
   496 
   498 OopStorage::ProtectActive::ProtectActive() : _enter(0), _exit() {}
       
   499 
       
   500 // Begin read-side critical section.
       
   501 uint OopStorage::ProtectActive::read_enter() {
       
   502   return Atomic::add(2u, &_enter);
       
   503 }
       
   504 
       
   505 // End read-side critical section.
       
   506 void OopStorage::ProtectActive::read_exit(uint enter_value) {
       
   507   Atomic::add(2u, &_exit[enter_value & 1]);
       
   508 }
       
   509 
       
   510 // Wait until all readers that entered the critical section before
       
   511 // synchronization have exited that critical section.
       
   512 void OopStorage::ProtectActive::write_synchronize() {
       
   513   SpinYield spinner;
       
   514   // Determine old and new exit counters, based on bit0 of the
       
   515   // on-entry _enter counter.
       
   516   uint value = OrderAccess::load_acquire(&_enter);
       
   517   volatile uint* new_ptr = &_exit[(value + 1) & 1];
       
   518   // Atomically change the in-use exit counter to the new counter, by
       
   519   // adding 1 to the _enter counter (flipping bit0 between 0 and 1)
       
   520   // and initializing the new exit counter to that enter value.  Note:
       
   521   // The new exit counter is not being used by read operations until
       
   522   // this change succeeds.
       
   523   uint old;
       
   524   do {
       
   525     old = value;
       
   526     *new_ptr = ++value;
       
   527     value = Atomic::cmpxchg(value, &_enter, old);
       
   528   } while (old != value);
       
   529   // Readers that entered the critical section before we changed the
       
   530   // selected exit counter will use the old exit counter.  Readers
       
   531   // entering after the change will use the new exit counter.  Wait
       
   532   // for all the critical sections started before the change to
       
   533   // complete, e.g. for the value of old_ptr to catch up with old.
       
   534   volatile uint* old_ptr = &_exit[old & 1];
       
   535   while (old != OrderAccess::load_acquire(old_ptr)) {
       
   536     spinner.wait();
       
   537   }
       
   538 }
       
   539 
       
   540 // Make new_array the _active_array.  Increments new_array's refcount
   497 // Make new_array the _active_array.  Increments new_array's refcount
   541 // to account for the new reference.  The assignment is atomic wrto
   498 // to account for the new reference.  The assignment is atomic wrto
   542 // obtain_active_array; once this function returns, it is safe for the
   499 // obtain_active_array; once this function returns, it is safe for the
   543 // caller to relinquish the old array.
   500 // caller to relinquish the old array.
   544 void OopStorage::replace_active_array(ActiveArray* new_array) {
   501 void OopStorage::replace_active_array(ActiveArray* new_array) {
   546   // Update new_array refcount to account for the new reference.
   503   // Update new_array refcount to account for the new reference.
   547   new_array->increment_refcount();
   504   new_array->increment_refcount();
   548   // Install new_array, ensuring its initialization is complete first.
   505   // Install new_array, ensuring its initialization is complete first.
   549   OrderAccess::release_store(&_active_array, new_array);
   506   OrderAccess::release_store(&_active_array, new_array);
   550   // Wait for any readers that could read the old array from _active_array.
   507   // Wait for any readers that could read the old array from _active_array.
   551   _protect_active.write_synchronize();
   508   // Can't use GlobalCounter here, because this is called from allocate(),
       
   509   // which may be called in the scope of a GlobalCounter critical section
       
   510   // when inserting a StringTable entry.
       
   511   _protect_active.synchronize();
   552   // All obtain critical sections that could see the old array have
   512   // All obtain critical sections that could see the old array have
   553   // completed, having incremented the refcount of the old array.  The
   513   // completed, having incremented the refcount of the old array.  The
   554   // caller can now safely relinquish the old array.
   514   // caller can now safely relinquish the old array.
   555 }
   515 }
   556 
   516 
   558 // increment its refcount.  This provides safe access to the array,
   518 // increment its refcount.  This provides safe access to the array,
   559 // even if an allocate operation expands and replaces the value of
   519 // even if an allocate operation expands and replaces the value of
   560 // _active_array.  The caller must relinquish the array when done
   520 // _active_array.  The caller must relinquish the array when done
   561 // using it.
   521 // using it.
   562 OopStorage::ActiveArray* OopStorage::obtain_active_array() const {
   522 OopStorage::ActiveArray* OopStorage::obtain_active_array() const {
   563   uint enter_value = _protect_active.read_enter();
   523   SingleWriterSynchronizer::CriticalSection cs(&_protect_active);
   564   ActiveArray* result = OrderAccess::load_acquire(&_active_array);
   524   ActiveArray* result = OrderAccess::load_acquire(&_active_array);
   565   result->increment_refcount();
   525   result->increment_refcount();
   566   _protect_active.read_exit(enter_value);
       
   567   return result;
   526   return result;
   568 }
   527 }
   569 
   528 
   570 // Decrement refcount of array and destroy if refcount is zero.
   529 // Decrement refcount of array and destroy if refcount is zero.
   571 void OopStorage::relinquish_block_array(ActiveArray* array) const {
   530 void OopStorage::relinquish_block_array(ActiveArray* array) const {