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;
|