35 */ |
35 */ |
36 |
36 |
37 // A TreeList is a FreeList which can be used to maintain a |
37 // A TreeList is a FreeList which can be used to maintain a |
38 // binary tree of free lists. |
38 // binary tree of free lists. |
39 |
39 |
40 template <class Chunk> class TreeChunk; |
40 template <class Chunk_t, template <class> class FreeList_t> class TreeChunk; |
41 template <class Chunk> class BinaryTreeDictionary; |
41 template <class Chunk_t, template <class> class FreeList_t> class BinaryTreeDictionary; |
42 template <class Chunk> class AscendTreeCensusClosure; |
42 template <class Chunk_t, template <class> class FreeList_t> class AscendTreeCensusClosure; |
43 template <class Chunk> class DescendTreeCensusClosure; |
43 template <class Chunk_t, template <class> class FreeList_t> class DescendTreeCensusClosure; |
44 template <class Chunk> class DescendTreeSearchClosure; |
44 template <class Chunk_t, template <class> class FreeList_t> class DescendTreeSearchClosure; |
45 |
45 |
46 template <class Chunk> |
46 template <class Chunk_t, template <class> class FreeList_t> |
47 class TreeList: public FreeList<Chunk> { |
47 class TreeList : public FreeList_t<Chunk_t> { |
48 friend class TreeChunk<Chunk>; |
48 friend class TreeChunk<Chunk_t, FreeList_t>; |
49 friend class BinaryTreeDictionary<Chunk>; |
49 friend class BinaryTreeDictionary<Chunk_t, FreeList_t>; |
50 friend class AscendTreeCensusClosure<Chunk>; |
50 friend class AscendTreeCensusClosure<Chunk_t, FreeList_t>; |
51 friend class DescendTreeCensusClosure<Chunk>; |
51 friend class DescendTreeCensusClosure<Chunk_t, FreeList_t>; |
52 friend class DescendTreeSearchClosure<Chunk>; |
52 friend class DescendTreeSearchClosure<Chunk_t, FreeList_t>; |
53 |
53 |
54 TreeList<Chunk>* _parent; |
54 TreeList<Chunk_t, FreeList_t>* _parent; |
55 TreeList<Chunk>* _left; |
55 TreeList<Chunk_t, FreeList_t>* _left; |
56 TreeList<Chunk>* _right; |
56 TreeList<Chunk_t, FreeList_t>* _right; |
57 |
57 |
58 protected: |
58 protected: |
59 TreeList<Chunk>* parent() const { return _parent; } |
59 |
60 TreeList<Chunk>* left() const { return _left; } |
60 TreeList<Chunk_t, FreeList_t>* parent() const { return _parent; } |
61 TreeList<Chunk>* right() const { return _right; } |
61 TreeList<Chunk_t, FreeList_t>* left() const { return _left; } |
62 |
62 TreeList<Chunk_t, FreeList_t>* right() const { return _right; } |
63 // Explicitly import these names into our namespace to fix name lookup with templates |
63 |
64 using FreeList<Chunk>::head; |
64 // Wrapper on call to base class, to get the template to compile. |
65 using FreeList<Chunk>::set_head; |
65 Chunk_t* head() const { return FreeList_t<Chunk_t>::head(); } |
66 |
66 Chunk_t* tail() const { return FreeList_t<Chunk_t>::tail(); } |
67 using FreeList<Chunk>::tail; |
67 void set_head(Chunk_t* head) { FreeList_t<Chunk_t>::set_head(head); } |
68 using FreeList<Chunk>::set_tail; |
68 void set_tail(Chunk_t* tail) { FreeList_t<Chunk_t>::set_tail(tail); } |
69 using FreeList<Chunk>::link_tail; |
69 |
70 |
70 size_t size() const { return FreeList_t<Chunk_t>::size(); } |
71 using FreeList<Chunk>::increment_count; |
|
72 NOT_PRODUCT(using FreeList<Chunk>::increment_returned_bytes_by;) |
|
73 using FreeList<Chunk>::verify_chunk_in_free_list; |
|
74 using FreeList<Chunk>::size; |
|
75 |
71 |
76 // Accessors for links in tree. |
72 // Accessors for links in tree. |
77 |
73 |
78 void set_left(TreeList<Chunk>* tl) { |
74 void set_left(TreeList<Chunk_t, FreeList_t>* tl) { |
79 _left = tl; |
75 _left = tl; |
80 if (tl != NULL) |
76 if (tl != NULL) |
81 tl->set_parent(this); |
77 tl->set_parent(this); |
82 } |
78 } |
83 void set_right(TreeList<Chunk>* tl) { |
79 void set_right(TreeList<Chunk_t, FreeList_t>* tl) { |
84 _right = tl; |
80 _right = tl; |
85 if (tl != NULL) |
81 if (tl != NULL) |
86 tl->set_parent(this); |
82 tl->set_parent(this); |
87 } |
83 } |
88 void set_parent(TreeList<Chunk>* tl) { _parent = tl; } |
84 void set_parent(TreeList<Chunk_t, FreeList_t>* tl) { _parent = tl; } |
89 |
85 |
90 void clearLeft() { _left = NULL; } |
86 void clear_left() { _left = NULL; } |
91 void clear_right() { _right = NULL; } |
87 void clear_right() { _right = NULL; } |
92 void clear_parent() { _parent = NULL; } |
88 void clear_parent() { _parent = NULL; } |
93 void initialize() { clearLeft(); clear_right(), clear_parent(); } |
89 void initialize() { clear_left(); clear_right(), clear_parent(); FreeList_t<Chunk_t>::initialize(); } |
94 |
90 |
95 // For constructing a TreeList from a Tree chunk or |
91 // For constructing a TreeList from a Tree chunk or |
96 // address and size. |
92 // address and size. |
97 static TreeList<Chunk>* as_TreeList(TreeChunk<Chunk>* tc); |
93 TreeList(); |
98 static TreeList<Chunk>* as_TreeList(HeapWord* addr, size_t size); |
94 static TreeList<Chunk_t, FreeList_t>* |
|
95 as_TreeList(TreeChunk<Chunk_t, FreeList_t>* tc); |
|
96 static TreeList<Chunk_t, FreeList_t>* as_TreeList(HeapWord* addr, size_t size); |
99 |
97 |
100 // Returns the head of the free list as a pointer to a TreeChunk. |
98 // Returns the head of the free list as a pointer to a TreeChunk. |
101 TreeChunk<Chunk>* head_as_TreeChunk(); |
99 TreeChunk<Chunk_t, FreeList_t>* head_as_TreeChunk(); |
102 |
100 |
103 // Returns the first available chunk in the free list as a pointer |
101 // Returns the first available chunk in the free list as a pointer |
104 // to a TreeChunk. |
102 // to a TreeChunk. |
105 TreeChunk<Chunk>* first_available(); |
103 TreeChunk<Chunk_t, FreeList_t>* first_available(); |
106 |
104 |
107 // Returns the block with the largest heap address amongst |
105 // Returns the block with the largest heap address amongst |
108 // those in the list for this size; potentially slow and expensive, |
106 // those in the list for this size; potentially slow and expensive, |
109 // use with caution! |
107 // use with caution! |
110 TreeChunk<Chunk>* largest_address(); |
108 TreeChunk<Chunk_t, FreeList_t>* largest_address(); |
|
109 |
|
110 TreeList<Chunk_t, FreeList_t>* get_better_list( |
|
111 BinaryTreeDictionary<Chunk_t, FreeList_t>* dictionary); |
111 |
112 |
112 // remove_chunk_replace_if_needed() removes the given "tc" from the TreeList. |
113 // remove_chunk_replace_if_needed() removes the given "tc" from the TreeList. |
113 // If "tc" is the first chunk in the list, it is also the |
114 // If "tc" is the first chunk in the list, it is also the |
114 // TreeList that is the node in the tree. remove_chunk_replace_if_needed() |
115 // TreeList that is the node in the tree. remove_chunk_replace_if_needed() |
115 // returns the possibly replaced TreeList* for the node in |
116 // returns the possibly replaced TreeList* for the node in |
116 // the tree. It also updates the parent of the original |
117 // the tree. It also updates the parent of the original |
117 // node to point to the new node. |
118 // node to point to the new node. |
118 TreeList<Chunk>* remove_chunk_replace_if_needed(TreeChunk<Chunk>* tc); |
119 TreeList<Chunk_t, FreeList_t>* remove_chunk_replace_if_needed(TreeChunk<Chunk_t, FreeList_t>* tc); |
119 // See FreeList. |
120 // See FreeList. |
120 void return_chunk_at_head(TreeChunk<Chunk>* tc); |
121 void return_chunk_at_head(TreeChunk<Chunk_t, FreeList_t>* tc); |
121 void return_chunk_at_tail(TreeChunk<Chunk>* tc); |
122 void return_chunk_at_tail(TreeChunk<Chunk_t, FreeList_t>* tc); |
122 }; |
123 }; |
123 |
124 |
124 // A TreeChunk is a subclass of a Chunk that additionally |
125 // A TreeChunk is a subclass of a Chunk that additionally |
125 // maintains a pointer to the free list on which it is currently |
126 // maintains a pointer to the free list on which it is currently |
126 // linked. |
127 // linked. |
132 // the first chunk in the list is distinguished in this fashion |
133 // the first chunk in the list is distinguished in this fashion |
133 // (also is the node in the tree), it is the last chunk to be found |
134 // (also is the node in the tree), it is the last chunk to be found |
134 // on the free list for a node in the tree and is only removed if |
135 // on the free list for a node in the tree and is only removed if |
135 // it is the last chunk on the free list. |
136 // it is the last chunk on the free list. |
136 |
137 |
137 template <class Chunk> |
138 template <class Chunk_t, template <class> class FreeList_t> |
138 class TreeChunk : public Chunk { |
139 class TreeChunk : public Chunk_t { |
139 friend class TreeList<Chunk>; |
140 friend class TreeList<Chunk_t, FreeList_t>; |
140 TreeList<Chunk>* _list; |
141 TreeList<Chunk_t, FreeList_t>* _list; |
141 TreeList<Chunk> _embedded_list; // if non-null, this chunk is on _list |
142 TreeList<Chunk_t, FreeList_t> _embedded_list; // if non-null, this chunk is on _list |
|
143 |
|
144 static size_t _min_tree_chunk_size; |
|
145 |
142 protected: |
146 protected: |
143 TreeList<Chunk>* embedded_list() const { return (TreeList<Chunk>*) &_embedded_list; } |
147 TreeList<Chunk_t, FreeList_t>* embedded_list() const { return (TreeList<Chunk_t, FreeList_t>*) &_embedded_list; } |
144 void set_embedded_list(TreeList<Chunk>* v) { _embedded_list = *v; } |
148 void set_embedded_list(TreeList<Chunk_t, FreeList_t>* v) { _embedded_list = *v; } |
145 public: |
149 public: |
146 TreeList<Chunk>* list() { return _list; } |
150 TreeList<Chunk_t, FreeList_t>* list() { return _list; } |
147 void set_list(TreeList<Chunk>* v) { _list = v; } |
151 void set_list(TreeList<Chunk_t, FreeList_t>* v) { _list = v; } |
148 static TreeChunk<Chunk>* as_TreeChunk(Chunk* fc); |
152 static TreeChunk<Chunk_t, FreeList_t>* as_TreeChunk(Chunk_t* fc); |
149 // Initialize fields in a TreeChunk that should be |
153 // Initialize fields in a TreeChunk that should be |
150 // initialized when the TreeChunk is being added to |
154 // initialized when the TreeChunk is being added to |
151 // a free list in the tree. |
155 // a free list in the tree. |
152 void initialize() { embedded_list()->initialize(); } |
156 void initialize() { embedded_list()->initialize(); } |
153 |
157 |
154 Chunk* next() const { return Chunk::next(); } |
158 Chunk_t* next() const { return Chunk_t::next(); } |
155 Chunk* prev() const { return Chunk::prev(); } |
159 Chunk_t* prev() const { return Chunk_t::prev(); } |
156 size_t size() const volatile { return Chunk::size(); } |
160 size_t size() const volatile { return Chunk_t::size(); } |
|
161 |
|
162 static size_t min_size() { |
|
163 return _min_tree_chunk_size; |
|
164 } |
157 |
165 |
158 // debugging |
166 // debugging |
159 void verify_tree_chunk_list() const; |
167 void verify_tree_chunk_list() const; |
|
168 void assert_is_mangled() const; |
160 }; |
169 }; |
161 |
170 |
162 |
171 |
163 template <class Chunk> |
172 template <class Chunk_t, template <class> class FreeList_t> |
164 class BinaryTreeDictionary: public FreeBlockDictionary<Chunk> { |
173 class BinaryTreeDictionary: public FreeBlockDictionary<Chunk_t> { |
165 friend class VMStructs; |
174 friend class VMStructs; |
166 bool _splay; |
|
167 bool _adaptive_freelists; |
|
168 size_t _total_size; |
175 size_t _total_size; |
169 size_t _total_free_blocks; |
176 size_t _total_free_blocks; |
170 TreeList<Chunk>* _root; |
177 TreeList<Chunk_t, FreeList_t>* _root; |
171 |
178 |
172 // private accessors |
179 // private accessors |
173 bool splay() const { return _splay; } |
|
174 void set_splay(bool v) { _splay = v; } |
|
175 void set_total_size(size_t v) { _total_size = v; } |
180 void set_total_size(size_t v) { _total_size = v; } |
176 virtual void inc_total_size(size_t v); |
181 virtual void inc_total_size(size_t v); |
177 virtual void dec_total_size(size_t v); |
182 virtual void dec_total_size(size_t v); |
178 size_t total_free_blocks() const { return _total_free_blocks; } |
|
179 void set_total_free_blocks(size_t v) { _total_free_blocks = v; } |
183 void set_total_free_blocks(size_t v) { _total_free_blocks = v; } |
180 TreeList<Chunk>* root() const { return _root; } |
184 TreeList<Chunk_t, FreeList_t>* root() const { return _root; } |
181 void set_root(TreeList<Chunk>* v) { _root = v; } |
185 void set_root(TreeList<Chunk_t, FreeList_t>* v) { _root = v; } |
182 bool adaptive_freelists() { return _adaptive_freelists; } |
|
183 |
186 |
184 // This field is added and can be set to point to the |
187 // This field is added and can be set to point to the |
185 // the Mutex used to synchronize access to the |
188 // the Mutex used to synchronize access to the |
186 // dictionary so that assertion checking can be done. |
189 // dictionary so that assertion checking can be done. |
187 // For example it is set to point to _parDictionaryAllocLock. |
190 // For example it is set to point to _parDictionaryAllocLock. |
189 |
192 |
190 // Remove a chunk of size "size" or larger from the tree and |
193 // Remove a chunk of size "size" or larger from the tree and |
191 // return it. If the chunk |
194 // return it. If the chunk |
192 // is the last chunk of that size, remove the node for that size |
195 // is the last chunk of that size, remove the node for that size |
193 // from the tree. |
196 // from the tree. |
194 TreeChunk<Chunk>* get_chunk_from_tree(size_t size, enum FreeBlockDictionary<Chunk>::Dither dither, bool splay); |
197 TreeChunk<Chunk_t, FreeList_t>* get_chunk_from_tree(size_t size, enum FreeBlockDictionary<Chunk_t>::Dither dither); |
|
198 // Remove this chunk from the tree. If the removal results |
|
199 // in an empty list in the tree, remove the empty list. |
|
200 TreeChunk<Chunk_t, FreeList_t>* remove_chunk_from_tree(TreeChunk<Chunk_t, FreeList_t>* tc); |
|
201 // Remove the node in the trees starting at tl that has the |
|
202 // minimum value and return it. Repair the tree as needed. |
|
203 TreeList<Chunk_t, FreeList_t>* remove_tree_minimum(TreeList<Chunk_t, FreeList_t>* tl); |
|
204 // Add this free chunk to the tree. |
|
205 void insert_chunk_in_tree(Chunk_t* freeChunk); |
|
206 public: |
|
207 |
195 // Return a list of the specified size or NULL from the tree. |
208 // Return a list of the specified size or NULL from the tree. |
196 // The list is not removed from the tree. |
209 // The list is not removed from the tree. |
197 TreeList<Chunk>* find_list (size_t size) const; |
210 TreeList<Chunk_t, FreeList_t>* find_list (size_t size) const; |
198 // Remove this chunk from the tree. If the removal results |
|
199 // in an empty list in the tree, remove the empty list. |
|
200 TreeChunk<Chunk>* remove_chunk_from_tree(TreeChunk<Chunk>* tc); |
|
201 // Remove the node in the trees starting at tl that has the |
|
202 // minimum value and return it. Repair the tree as needed. |
|
203 TreeList<Chunk>* remove_tree_minimum(TreeList<Chunk>* tl); |
|
204 void semi_splay_step(TreeList<Chunk>* tl); |
|
205 // Add this free chunk to the tree. |
|
206 void insert_chunk_in_tree(Chunk* freeChunk); |
|
207 public: |
|
208 |
|
209 static const size_t min_tree_chunk_size = sizeof(TreeChunk<Chunk>)/HeapWordSize; |
|
210 |
211 |
211 void verify_tree() const; |
212 void verify_tree() const; |
212 // verify that the given chunk is in the tree. |
213 // verify that the given chunk is in the tree. |
213 bool verify_chunk_in_free_list(Chunk* tc) const; |
214 bool verify_chunk_in_free_list(Chunk_t* tc) const; |
214 private: |
215 private: |
215 void verify_tree_helper(TreeList<Chunk>* tl) const; |
216 void verify_tree_helper(TreeList<Chunk_t, FreeList_t>* tl) const; |
216 static size_t verify_prev_free_ptrs(TreeList<Chunk>* tl); |
217 static size_t verify_prev_free_ptrs(TreeList<Chunk_t, FreeList_t>* tl); |
217 |
218 |
218 // Returns the total number of chunks in the list. |
219 // Returns the total number of chunks in the list. |
219 size_t total_list_length(TreeList<Chunk>* tl) const; |
220 size_t total_list_length(TreeList<Chunk_t, FreeList_t>* tl) const; |
220 // Returns the total number of words in the chunks in the tree |
221 // Returns the total number of words in the chunks in the tree |
221 // starting at "tl". |
222 // starting at "tl". |
222 size_t total_size_in_tree(TreeList<Chunk>* tl) const; |
223 size_t total_size_in_tree(TreeList<Chunk_t, FreeList_t>* tl) const; |
223 // Returns the sum of the square of the size of each block |
224 // Returns the sum of the square of the size of each block |
224 // in the tree starting at "tl". |
225 // in the tree starting at "tl". |
225 double sum_of_squared_block_sizes(TreeList<Chunk>* const tl) const; |
226 double sum_of_squared_block_sizes(TreeList<Chunk_t, FreeList_t>* const tl) const; |
226 // Returns the total number of free blocks in the tree starting |
227 // Returns the total number of free blocks in the tree starting |
227 // at "tl". |
228 // at "tl". |
228 size_t total_free_blocks_in_tree(TreeList<Chunk>* tl) const; |
229 size_t total_free_blocks_in_tree(TreeList<Chunk_t, FreeList_t>* tl) const; |
229 size_t num_free_blocks() const; |
230 size_t num_free_blocks() const; |
230 size_t treeHeight() const; |
231 size_t tree_height() const; |
231 size_t tree_height_helper(TreeList<Chunk>* tl) const; |
232 size_t tree_height_helper(TreeList<Chunk_t, FreeList_t>* tl) const; |
232 size_t total_nodes_in_tree(TreeList<Chunk>* tl) const; |
233 size_t total_nodes_in_tree(TreeList<Chunk_t, FreeList_t>* tl) const; |
233 size_t total_nodes_helper(TreeList<Chunk>* tl) const; |
234 size_t total_nodes_helper(TreeList<Chunk_t, FreeList_t>* tl) const; |
234 |
235 |
235 public: |
236 public: |
236 // Constructor |
237 // Constructor |
237 BinaryTreeDictionary(bool adaptive_freelists, bool splay = false); |
238 BinaryTreeDictionary() : |
238 BinaryTreeDictionary(MemRegion mr, bool adaptive_freelists, bool splay = false); |
239 _total_size(0), _total_free_blocks(0), _root(0) {} |
|
240 |
|
241 BinaryTreeDictionary(MemRegion mr); |
239 |
242 |
240 // Public accessors |
243 // Public accessors |
241 size_t total_size() const { return _total_size; } |
244 size_t total_size() const { return _total_size; } |
|
245 size_t total_free_blocks() const { return _total_free_blocks; } |
242 |
246 |
243 // Reset the dictionary to the initial conditions with |
247 // Reset the dictionary to the initial conditions with |
244 // a single free chunk. |
248 // a single free chunk. |
245 void reset(MemRegion mr); |
249 void reset(MemRegion mr); |
246 void reset(HeapWord* addr, size_t size); |
250 void reset(HeapWord* addr, size_t size); |
247 // Reset the dictionary to be empty. |
251 // Reset the dictionary to be empty. |
248 void reset(); |
252 void reset(); |
249 |
253 |
250 // Return a chunk of size "size" or greater from |
254 // Return a chunk of size "size" or greater from |
251 // the tree. |
255 // the tree. |
252 // want a better dynamic splay strategy for the future. |
256 Chunk_t* get_chunk(size_t size, enum FreeBlockDictionary<Chunk_t>::Dither dither) { |
253 Chunk* get_chunk(size_t size, enum FreeBlockDictionary<Chunk>::Dither dither) { |
257 FreeBlockDictionary<Chunk_t>::verify_par_locked(); |
254 FreeBlockDictionary<Chunk>::verify_par_locked(); |
258 Chunk_t* res = get_chunk_from_tree(size, dither); |
255 Chunk* res = get_chunk_from_tree(size, dither, splay()); |
|
256 assert(res == NULL || res->is_free(), |
259 assert(res == NULL || res->is_free(), |
257 "Should be returning a free chunk"); |
260 "Should be returning a free chunk"); |
|
261 assert(dither != FreeBlockDictionary<Chunk_t>::exactly || |
|
262 res->size() == size, "Not correct size"); |
258 return res; |
263 return res; |
259 } |
264 } |
260 |
265 |
261 void return_chunk(Chunk* chunk) { |
266 void return_chunk(Chunk_t* chunk) { |
262 FreeBlockDictionary<Chunk>::verify_par_locked(); |
267 FreeBlockDictionary<Chunk_t>::verify_par_locked(); |
263 insert_chunk_in_tree(chunk); |
268 insert_chunk_in_tree(chunk); |
264 } |
269 } |
265 |
270 |
266 void remove_chunk(Chunk* chunk) { |
271 void remove_chunk(Chunk_t* chunk) { |
267 FreeBlockDictionary<Chunk>::verify_par_locked(); |
272 FreeBlockDictionary<Chunk_t>::verify_par_locked(); |
268 remove_chunk_from_tree((TreeChunk<Chunk>*)chunk); |
273 remove_chunk_from_tree((TreeChunk<Chunk_t, FreeList_t>*)chunk); |
269 assert(chunk->is_free(), "Should still be a free chunk"); |
274 assert(chunk->is_free(), "Should still be a free chunk"); |
270 } |
275 } |
271 |
276 |
272 size_t max_chunk_size() const; |
277 size_t max_chunk_size() const; |
273 size_t total_chunk_size(debug_only(const Mutex* lock)) const { |
278 size_t total_chunk_size(debug_only(const Mutex* lock)) const { |
279 ) |
284 ) |
280 return total_size(); |
285 return total_size(); |
281 } |
286 } |
282 |
287 |
283 size_t min_size() const { |
288 size_t min_size() const { |
284 return min_tree_chunk_size; |
289 return TreeChunk<Chunk_t, FreeList_t>::min_size(); |
285 } |
290 } |
286 |
291 |
287 double sum_of_squared_block_sizes() const { |
292 double sum_of_squared_block_sizes() const { |
288 return sum_of_squared_block_sizes(root()); |
293 return sum_of_squared_block_sizes(root()); |
289 } |
294 } |
290 |
295 |
291 Chunk* find_chunk_ends_at(HeapWord* target) const; |
296 Chunk_t* find_chunk_ends_at(HeapWord* target) const; |
292 |
297 |
293 // Find the list with size "size" in the binary tree and update |
298 // Find the list with size "size" in the binary tree and update |
294 // the statistics in the list according to "split" (chunk was |
299 // the statistics in the list according to "split" (chunk was |
295 // split or coalesce) and "birth" (chunk was added or removed). |
300 // split or coalesce) and "birth" (chunk was added or removed). |
296 void dict_census_udpate(size_t size, bool split, bool birth); |
301 void dict_census_update(size_t size, bool split, bool birth); |
297 // Return true if the dictionary is overpopulated (more chunks of |
302 // Return true if the dictionary is overpopulated (more chunks of |
298 // this size than desired) for size "size". |
303 // this size than desired) for size "size". |
299 bool coal_dict_over_populated(size_t size); |
304 bool coal_dict_over_populated(size_t size); |
300 // Methods called at the beginning of a sweep to prepare the |
305 // Methods called at the beginning of a sweep to prepare the |
301 // statistics for the sweep. |
306 // statistics for the sweep. |