82 size_t allocation_count() const; |
82 size_t allocation_count() const; |
83 |
83 |
84 // The number of blocks of entries. Useful for sizing parallel iteration. |
84 // The number of blocks of entries. Useful for sizing parallel iteration. |
85 size_t block_count() const; |
85 size_t block_count() const; |
86 |
86 |
87 // The number of blocks with no allocated entries. Useful for sizing |
|
88 // parallel iteration and scheduling block deletion. |
|
89 size_t empty_block_count() const; |
|
90 |
|
91 // Total number of blocks * memory allocation per block, plus |
87 // Total number of blocks * memory allocation per block, plus |
92 // bookkeeping overhead, including this storage object. |
88 // bookkeeping overhead, including this storage object. |
93 size_t total_memory_usage() const; |
89 size_t total_memory_usage() const; |
94 |
90 |
95 enum EntryStatus { |
91 enum EntryStatus { |
105 // Allocates and returns a new entry. Returns NULL if memory allocation |
101 // Allocates and returns a new entry. Returns NULL if memory allocation |
106 // failed. Locks _allocate_mutex. |
102 // failed. Locks _allocate_mutex. |
107 // postcondition: *result == NULL. |
103 // postcondition: *result == NULL. |
108 oop* allocate(); |
104 oop* allocate(); |
109 |
105 |
110 // Deallocates ptr, after setting its value to NULL. Locks _allocate_mutex. |
106 // Deallocates ptr. No locking. |
111 // precondition: ptr is a valid allocated entry. |
107 // precondition: ptr is a valid allocated entry. |
112 // precondition: *ptr == NULL. |
108 // precondition: *ptr == NULL. |
113 void release(const oop* ptr); |
109 void release(const oop* ptr); |
114 |
110 |
115 // Releases all the ptrs. Possibly faster than individual calls to |
111 // Releases all the ptrs. Possibly faster than individual calls to |
116 // release(oop*). Best if ptrs is sorted by address. Locks |
112 // release(oop*). Best if ptrs is sorted by address. No locking. |
117 // _allocate_mutex. |
|
118 // precondition: All elements of ptrs are valid allocated entries. |
113 // precondition: All elements of ptrs are valid allocated entries. |
119 // precondition: *ptrs[i] == NULL, for i in [0,size). |
114 // precondition: *ptrs[i] == NULL, for i in [0,size). |
120 void release(const oop* const* ptrs, size_t size); |
115 void release(const oop* const* ptrs, size_t size); |
121 |
116 |
122 // Applies f to each allocated entry's location. f must be a function or |
117 // Applies f to each allocated entry's location. f must be a function or |
158 #endif // INCLUDE_ALL_GCS |
153 #endif // INCLUDE_ALL_GCS |
159 |
154 |
160 // Block cleanup functions are for the exclusive use of the GC. |
155 // Block cleanup functions are for the exclusive use of the GC. |
161 // Both stop deleting if there is an in-progress concurrent iteration. |
156 // Both stop deleting if there is an in-progress concurrent iteration. |
162 // Concurrent deletion locks both the allocate_mutex and the active_mutex. |
157 // Concurrent deletion locks both the allocate_mutex and the active_mutex. |
163 void delete_empty_blocks_safepoint(size_t retain = 1); |
158 void delete_empty_blocks_safepoint(); |
164 void delete_empty_blocks_concurrent(size_t retain = 1); |
159 void delete_empty_blocks_concurrent(); |
165 |
160 |
166 // Debugging and logging support. |
161 // Debugging and logging support. |
167 const char* name() const; |
162 const char* name() const; |
168 void print_on(outputStream* st) const PRODUCT_RETURN; |
163 void print_on(outputStream* st) const PRODUCT_RETURN; |
169 |
164 |
229 private: |
224 private: |
230 const char* _name; |
225 const char* _name; |
231 BlockList _active_list; |
226 BlockList _active_list; |
232 BlockList _allocate_list; |
227 BlockList _allocate_list; |
233 Block* volatile _active_head; |
228 Block* volatile _active_head; |
|
229 Block* volatile _deferred_updates; |
234 |
230 |
235 Mutex* _allocate_mutex; |
231 Mutex* _allocate_mutex; |
236 Mutex* _active_mutex; |
232 Mutex* _active_mutex; |
237 |
233 |
238 // Counts are volatile for racy unlocked accesses. |
234 // Counts are volatile for racy unlocked accesses. |
239 volatile size_t _allocation_count; |
235 volatile size_t _allocation_count; |
240 volatile size_t _block_count; |
236 volatile size_t _block_count; |
241 volatile size_t _empty_block_count; |
|
242 // mutable because this gets set even for const iteration. |
237 // mutable because this gets set even for const iteration. |
243 mutable bool _concurrent_iteration_active; |
238 mutable bool _concurrent_iteration_active; |
244 |
239 |
245 Block* find_block_or_null(const oop* ptr) const; |
240 Block* find_block_or_null(const oop* ptr) const; |
246 bool is_valid_block_locked_or_safepoint(const Block* block) const; |
|
247 EntryStatus allocation_status_validating_block(const Block* block, const oop* ptr) const; |
|
248 void check_release(const Block* block, const oop* ptr) const NOT_DEBUG_RETURN; |
|
249 void release_from_block(Block& block, uintx release_bitmask); |
|
250 void delete_empty_block(const Block& block); |
241 void delete_empty_block(const Block& block); |
|
242 bool reduce_deferred_updates(); |
251 |
243 |
252 static void assert_at_safepoint() NOT_DEBUG_RETURN; |
244 static void assert_at_safepoint() NOT_DEBUG_RETURN; |
253 |
245 |
254 template<typename F, typename Storage> |
246 template<typename F, typename Storage> |
255 static bool iterate_impl(F f, Storage* storage); |
247 static bool iterate_impl(F f, Storage* storage); |