< prev index next >

src/hotspot/share/gc/shared/oopStorage.hpp

Print this page
rev 50951 : imported patch rename_AllocateList
rev 50952 : imported patch rename_AllocateEntry
rev 50954 : imported patch rename_allocate_list
rev 50955 : imported patch rename_allocate_mutex
rev 50956 : [mq]: fix_more_comments


  56 // categories.  In particular, support for concurrent iteration by the garbage
  57 // collector, under certain restrictions, is required.  Further, it must not
  58 // block nor be blocked by other operations for long periods.
  59 //
  60 // Internally, OopStorage is a set of Block objects, from which entries are
  61 // allocated and released.  A block contains an oop[] and a bitmask indicating
  62 // which entries are in use (have been allocated and not yet released).  New
  63 // blocks are constructed and added to the storage object when an entry
  64 // allocation request is made and there are no blocks with unused entries.
  65 // Blocks may be removed and deleted when empty.
  66 //
  67 // There are two important (and somewhat intertwined) protocols governing
  68 // concurrent access to a storage object.  These are the Concurrent Iteration
  69 // Protocol and the Allocation Protocol.  See the ParState class for a
  70 // discussion of concurrent iteration and the management of thread
  71 // interactions for this protocol.  Similarly, see the allocate() function for
  72 // a discussion of allocation.
  73 
  74 class OopStorage : public CHeapObj<mtGC> {
  75 public:
  76   OopStorage(const char* name, Mutex* allocate_mutex, Mutex* active_mutex);
  77   ~OopStorage();
  78 
  79   // These count and usage accessors are racy unless at a safepoint.
  80 
  81   // The number of allocated and not yet released entries.
  82   size_t allocation_count() const;
  83 
  84   // The number of blocks of entries.  Useful for sizing parallel iteration.
  85   size_t block_count() const;
  86 
  87   // Total number of blocks * memory allocation per block, plus
  88   // bookkeeping overhead, including this storage object.
  89   size_t total_memory_usage() const;
  90 
  91   enum EntryStatus {
  92     INVALID_ENTRY,
  93     UNALLOCATED_ENTRY,
  94     ALLOCATED_ENTRY
  95   };
  96 
  97   // Locks _allocate_mutex.
  98   // precondition: ptr != NULL.
  99   EntryStatus allocation_status(const oop* ptr) const;
 100 
 101   // Allocates and returns a new entry.  Returns NULL if memory allocation
 102   // failed.  Locks _allocate_mutex.
 103   // postcondition: *result == NULL.
 104   oop* allocate();
 105 
 106   // Deallocates ptr.  No locking.
 107   // precondition: ptr is a valid allocated entry.
 108   // precondition: *ptr == NULL.
 109   void release(const oop* ptr);
 110 
 111   // Releases all the ptrs.  Possibly faster than individual calls to
 112   // release(oop*).  Best if ptrs is sorted by address.  No locking.
 113   // precondition: All elements of ptrs are valid allocated entries.
 114   // precondition: *ptrs[i] == NULL, for i in [0,size).
 115   void release(const oop* const* ptrs, size_t size);
 116 
 117   // Applies f to each allocated entry's location.  f must be a function or
 118   // function object.  Assume p is either a const oop* or an oop*, depending
 119   // on whether the associated storage is const or non-const, respectively.
 120   // Then f(p) must be a valid expression.  The result of invoking f(p) must
 121   // be implicitly convertible to bool.  Iteration terminates and returns
 122   // false if any invocation of f returns false.  Otherwise, the result of


 135   // - is_alive->do_object_b(*p) must be a valid expression whose value is
 136   // convertible to bool.
 137   //
 138   // For weak_oops_do, if *p == NULL then neither is_alive nor closure will be
 139   // invoked for p.  If is_alive->do_object_b(*p) is false, then closure will
 140   // not be invoked on p, and *p will be set to NULL.
 141 
 142   template<typename Closure> inline void oops_do(Closure* closure);
 143   template<typename Closure> inline void oops_do(Closure* closure) const;
 144   template<typename Closure> inline void weak_oops_do(Closure* closure);
 145 
 146   template<typename IsAliveClosure, typename Closure>
 147   inline void weak_oops_do(IsAliveClosure* is_alive, Closure* closure);
 148 
 149   // Parallel iteration is for the exclusive use of the GC.
 150   // Other clients must use serial iteration.
 151   template<bool concurrent, bool is_const> class ParState;
 152 
 153   // Block cleanup functions are for the exclusive use of the GC.
 154   // Both stop deleting if there is an in-progress concurrent iteration.
 155   // Concurrent deletion locks both the allocate_mutex and the active_mutex.
 156   void delete_empty_blocks_safepoint();
 157   void delete_empty_blocks_concurrent();
 158 
 159   // Debugging and logging support.
 160   const char* name() const;
 161   void print_on(outputStream* st) const PRODUCT_RETURN;
 162 
 163   // Provides access to storage internals, for unit testing.
 164   // Declare, but not define, the public class OopStorage::TestAccess.
 165   // That class is defined as part of the unit-test. It "exports" the needed
 166   // private types by providing public typedefs for them.
 167   class TestAccess;
 168 
 169   // xlC on AIX can't compile test_oopStorage.cpp with following private
 170   // classes. C++03 introduced access for nested classes with DR45, but xlC
 171   // version 12 rejects it.
 172 NOT_AIX( private: )
 173   class Block;                  // Fixed-size array of oops, plus bookkeeping.
 174   class ActiveArray;            // Array of Blocks, plus bookkeeping.
 175   class AllocateEntry;          // Provides AllocateList links in a Block.
 176 
 177   // Doubly-linked list of Blocks.
 178   class AllocateList {
 179     const Block* _head;
 180     const Block* _tail;
 181 
 182     // Noncopyable.
 183     AllocateList(const AllocateList&);
 184     AllocateList& operator=(const AllocateList&);
 185 
 186   public:
 187     AllocateList();
 188     ~AllocateList();
 189 
 190     Block* head();
 191     Block* tail();
 192     const Block* chead() const;
 193     const Block* ctail() const;
 194 
 195     Block* prev(Block& block);
 196     Block* next(Block& block);
 197 
 198     const Block* prev(const Block& block) const;
 199     const Block* next(const Block& block) const;
 200 
 201     void push_front(const Block& block);
 202     void push_back(const Block& block);
 203     void unlink(const Block& block);
 204   };
 205 
 206   // RCU-inspired protection of access to _active_array.
 207   class ProtectActive {
 208     volatile uint _enter;
 209     volatile uint _exit[2];
 210 
 211   public:
 212     ProtectActive();
 213 
 214     uint read_enter();
 215     void read_exit(uint enter_value);
 216     void write_synchronize();
 217   };
 218 
 219 private:
 220   const char* _name;
 221   ActiveArray* _active_array;
 222   AllocateList _allocate_list;
 223   Block* volatile _deferred_updates;
 224 
 225   Mutex* _allocate_mutex;
 226   Mutex* _active_mutex;
 227 
 228   // Volatile for racy unlocked accesses.
 229   volatile size_t _allocation_count;
 230 
 231   // Protection for _active_array.
 232   mutable ProtectActive _protect_active;
 233 
 234   // mutable because this gets set even for const iteration.
 235   mutable bool _concurrent_iteration_active;
 236 
 237   Block* find_block_or_null(const oop* ptr) const;
 238   void delete_empty_block(const Block& block);
 239   bool reduce_deferred_updates();
 240 
 241   // Managing _active_array.
 242   bool expand_active_array();
 243   void replace_active_array(ActiveArray* new_array);
 244   ActiveArray* obtain_active_array() const;
 245   void relinquish_block_array(ActiveArray* array) const;




  56 // categories.  In particular, support for concurrent iteration by the garbage
  57 // collector, under certain restrictions, is required.  Further, it must not
  58 // block nor be blocked by other operations for long periods.
  59 //
  60 // Internally, OopStorage is a set of Block objects, from which entries are
  61 // allocated and released.  A block contains an oop[] and a bitmask indicating
  62 // which entries are in use (have been allocated and not yet released).  New
  63 // blocks are constructed and added to the storage object when an entry
  64 // allocation request is made and there are no blocks with unused entries.
  65 // Blocks may be removed and deleted when empty.
  66 //
  67 // There are two important (and somewhat intertwined) protocols governing
  68 // concurrent access to a storage object.  These are the Concurrent Iteration
  69 // Protocol and the Allocation Protocol.  See the ParState class for a
  70 // discussion of concurrent iteration and the management of thread
  71 // interactions for this protocol.  Similarly, see the allocate() function for
  72 // a discussion of allocation.
  73 
  74 class OopStorage : public CHeapObj<mtGC> {
  75 public:
  76   OopStorage(const char* name, Mutex* allocation_mutex, Mutex* active_mutex);
  77   ~OopStorage();
  78 
  79   // These count and usage accessors are racy unless at a safepoint.
  80 
  81   // The number of allocated and not yet released entries.
  82   size_t allocation_count() const;
  83 
  84   // The number of blocks of entries.  Useful for sizing parallel iteration.
  85   size_t block_count() const;
  86 
  87   // Total number of blocks * memory allocation per block, plus
  88   // bookkeeping overhead, including this storage object.
  89   size_t total_memory_usage() const;
  90 
  91   enum EntryStatus {
  92     INVALID_ENTRY,
  93     UNALLOCATED_ENTRY,
  94     ALLOCATED_ENTRY
  95   };
  96 
  97   // Locks _allocation_mutex.
  98   // precondition: ptr != NULL.
  99   EntryStatus allocation_status(const oop* ptr) const;
 100 
 101   // Allocates and returns a new entry.  Returns NULL if memory allocation
 102   // failed.  Locks _allocation_mutex.
 103   // postcondition: *result == NULL.
 104   oop* allocate();
 105 
 106   // Deallocates ptr.  No locking.
 107   // precondition: ptr is a valid allocated entry.
 108   // precondition: *ptr == NULL.
 109   void release(const oop* ptr);
 110 
 111   // Releases all the ptrs.  Possibly faster than individual calls to
 112   // release(oop*).  Best if ptrs is sorted by address.  No locking.
 113   // precondition: All elements of ptrs are valid allocated entries.
 114   // precondition: *ptrs[i] == NULL, for i in [0,size).
 115   void release(const oop* const* ptrs, size_t size);
 116 
 117   // Applies f to each allocated entry's location.  f must be a function or
 118   // function object.  Assume p is either a const oop* or an oop*, depending
 119   // on whether the associated storage is const or non-const, respectively.
 120   // Then f(p) must be a valid expression.  The result of invoking f(p) must
 121   // be implicitly convertible to bool.  Iteration terminates and returns
 122   // false if any invocation of f returns false.  Otherwise, the result of


 135   // - is_alive->do_object_b(*p) must be a valid expression whose value is
 136   // convertible to bool.
 137   //
 138   // For weak_oops_do, if *p == NULL then neither is_alive nor closure will be
 139   // invoked for p.  If is_alive->do_object_b(*p) is false, then closure will
 140   // not be invoked on p, and *p will be set to NULL.
 141 
 142   template<typename Closure> inline void oops_do(Closure* closure);
 143   template<typename Closure> inline void oops_do(Closure* closure) const;
 144   template<typename Closure> inline void weak_oops_do(Closure* closure);
 145 
 146   template<typename IsAliveClosure, typename Closure>
 147   inline void weak_oops_do(IsAliveClosure* is_alive, Closure* closure);
 148 
 149   // Parallel iteration is for the exclusive use of the GC.
 150   // Other clients must use serial iteration.
 151   template<bool concurrent, bool is_const> class ParState;
 152 
 153   // Block cleanup functions are for the exclusive use of the GC.
 154   // Both stop deleting if there is an in-progress concurrent iteration.
 155   // Concurrent deletion locks both the _allocation_mutex and the _active_mutex.
 156   void delete_empty_blocks_safepoint();
 157   void delete_empty_blocks_concurrent();
 158 
 159   // Debugging and logging support.
 160   const char* name() const;
 161   void print_on(outputStream* st) const PRODUCT_RETURN;
 162 
 163   // Provides access to storage internals, for unit testing.
 164   // Declare, but not define, the public class OopStorage::TestAccess.
 165   // That class is defined as part of the unit-test. It "exports" the needed
 166   // private types by providing public typedefs for them.
 167   class TestAccess;
 168 
 169   // xlC on AIX can't compile test_oopStorage.cpp with following private
 170   // classes. C++03 introduced access for nested classes with DR45, but xlC
 171   // version 12 rejects it.
 172 NOT_AIX( private: )
 173   class Block;                  // Fixed-size array of oops, plus bookkeeping.
 174   class ActiveArray;            // Array of Blocks, plus bookkeeping.
 175   class AllocationListEntry;    // Provides AllocationList links in a Block.
 176 
 177   // Doubly-linked list of Blocks.
 178   class AllocationList {
 179     const Block* _head;
 180     const Block* _tail;
 181 
 182     // Noncopyable.
 183     AllocationList(const AllocationList&);
 184     AllocationList& operator=(const AllocationList&);
 185 
 186   public:
 187     AllocationList();
 188     ~AllocationList();
 189 
 190     Block* head();
 191     Block* tail();
 192     const Block* chead() const;
 193     const Block* ctail() const;
 194 
 195     Block* prev(Block& block);
 196     Block* next(Block& block);
 197 
 198     const Block* prev(const Block& block) const;
 199     const Block* next(const Block& block) const;
 200 
 201     void push_front(const Block& block);
 202     void push_back(const Block& block);
 203     void unlink(const Block& block);
 204   };
 205 
 206   // RCU-inspired protection of access to _active_array.
 207   class ProtectActive {
 208     volatile uint _enter;
 209     volatile uint _exit[2];
 210 
 211   public:
 212     ProtectActive();
 213 
 214     uint read_enter();
 215     void read_exit(uint enter_value);
 216     void write_synchronize();
 217   };
 218 
 219 private:
 220   const char* _name;
 221   ActiveArray* _active_array;
 222   AllocationList _allocation_list;
 223   Block* volatile _deferred_updates;
 224 
 225   Mutex* _allocation_mutex;
 226   Mutex* _active_mutex;
 227 
 228   // Volatile for racy unlocked accesses.
 229   volatile size_t _allocation_count;
 230 
 231   // Protection for _active_array.
 232   mutable ProtectActive _protect_active;
 233 
 234   // mutable because this gets set even for const iteration.
 235   mutable bool _concurrent_iteration_active;
 236 
 237   Block* find_block_or_null(const oop* ptr) const;
 238   void delete_empty_block(const Block& block);
 239   bool reduce_deferred_updates();
 240 
 241   // Managing _active_array.
 242   bool expand_active_array();
 243   void replace_active_array(ActiveArray* new_array);
 244   ActiveArray* obtain_active_array() const;
 245   void relinquish_block_array(ActiveArray* array) const;


< prev index next >