40 size_t region_num = hr->capacity() >> HeapRegion::LogOfHRGrainBytes; |
40 size_t region_num = hr->capacity() >> HeapRegion::LogOfHRGrainBytes; |
41 assert(region_num > 0, "sanity"); |
41 assert(region_num > 0, "sanity"); |
42 return region_num; |
42 return region_num; |
43 } |
43 } |
44 |
44 |
45 void HeapRegionSetBase::fill_in_ext_msg(hrl_ext_msg* msg, const char* message) { |
45 void HeapRegionSetBase::fill_in_ext_msg(hrs_ext_msg* msg, const char* message) { |
46 msg->append("[%s] %s " |
46 msg->append("[%s] %s " |
47 "ln: "SIZE_FORMAT" rn: "SIZE_FORMAT" " |
47 "ln: "SIZE_FORMAT" rn: "SIZE_FORMAT" " |
48 "cy: "SIZE_FORMAT" ud: "SIZE_FORMAT, |
48 "cy: "SIZE_FORMAT" ud: "SIZE_FORMAT, |
49 name(), message, length(), region_num(), |
49 name(), message, length(), region_num(), |
50 total_capacity_bytes(), total_used_bytes()); |
50 total_capacity_bytes(), total_used_bytes()); |
107 void HeapRegionSetBase::verify() { |
107 void HeapRegionSetBase::verify() { |
108 // It's important that we also observe the MT safety protocol even |
108 // It's important that we also observe the MT safety protocol even |
109 // for the verification calls. If we do verification without the |
109 // for the verification calls. If we do verification without the |
110 // appropriate locks and the set changes underneath our feet |
110 // appropriate locks and the set changes underneath our feet |
111 // verification might fail and send us on a wild goose chase. |
111 // verification might fail and send us on a wild goose chase. |
112 hrl_assert_mt_safety_ok(this); |
112 hrs_assert_mt_safety_ok(this); |
113 |
113 |
114 guarantee(( is_empty() && length() == 0 && region_num() == 0 && |
114 guarantee(( is_empty() && length() == 0 && region_num() == 0 && |
115 total_used_bytes() == 0 && total_capacity_bytes() == 0) || |
115 total_used_bytes() == 0 && total_capacity_bytes() == 0) || |
116 (!is_empty() && length() >= 0 && region_num() >= 0 && |
116 (!is_empty() && length() >= 0 && region_num() >= 0 && |
117 total_used_bytes() >= 0 && total_capacity_bytes() >= 0), |
117 total_used_bytes() >= 0 && total_capacity_bytes() >= 0), |
118 hrl_ext_msg(this, "invariant")); |
118 hrs_ext_msg(this, "invariant")); |
119 |
119 |
120 guarantee((!regions_humongous() && region_num() == length()) || |
120 guarantee((!regions_humongous() && region_num() == length()) || |
121 ( regions_humongous() && region_num() >= length()), |
121 ( regions_humongous() && region_num() >= length()), |
122 hrl_ext_msg(this, "invariant")); |
122 hrs_ext_msg(this, "invariant")); |
123 |
123 |
124 guarantee(!regions_empty() || total_used_bytes() == 0, |
124 guarantee(!regions_empty() || total_used_bytes() == 0, |
125 hrl_ext_msg(this, "invariant")); |
125 hrs_ext_msg(this, "invariant")); |
126 |
126 |
127 guarantee(total_used_bytes() <= total_capacity_bytes(), |
127 guarantee(total_used_bytes() <= total_capacity_bytes(), |
128 hrl_ext_msg(this, "invariant")); |
128 hrs_ext_msg(this, "invariant")); |
129 } |
129 } |
130 |
130 |
131 void HeapRegionSetBase::verify_start() { |
131 void HeapRegionSetBase::verify_start() { |
132 // See comment in verify() about MT safety and verification. |
132 // See comment in verify() about MT safety and verification. |
133 hrl_assert_mt_safety_ok(this); |
133 hrs_assert_mt_safety_ok(this); |
134 assert(!_verify_in_progress, |
134 assert(!_verify_in_progress, |
135 hrl_ext_msg(this, "verification should not be in progress")); |
135 hrs_ext_msg(this, "verification should not be in progress")); |
136 |
136 |
137 // Do the basic verification first before we do the checks over the regions. |
137 // Do the basic verification first before we do the checks over the regions. |
138 HeapRegionSetBase::verify(); |
138 HeapRegionSetBase::verify(); |
139 |
139 |
140 _calc_length = 0; |
140 _calc_length = 0; |
144 _verify_in_progress = true; |
144 _verify_in_progress = true; |
145 } |
145 } |
146 |
146 |
147 void HeapRegionSetBase::verify_next_region(HeapRegion* hr) { |
147 void HeapRegionSetBase::verify_next_region(HeapRegion* hr) { |
148 // See comment in verify() about MT safety and verification. |
148 // See comment in verify() about MT safety and verification. |
149 hrl_assert_mt_safety_ok(this); |
149 hrs_assert_mt_safety_ok(this); |
150 assert(_verify_in_progress, |
150 assert(_verify_in_progress, |
151 hrl_ext_msg(this, "verification should be in progress")); |
151 hrs_ext_msg(this, "verification should be in progress")); |
152 |
152 |
153 guarantee(verify_region(hr, this), hrl_ext_msg(this, "region verification")); |
153 guarantee(verify_region(hr, this), hrs_ext_msg(this, "region verification")); |
154 |
154 |
155 _calc_length += 1; |
155 _calc_length += 1; |
156 if (!hr->isHumongous()) { |
156 if (!hr->isHumongous()) { |
157 _calc_region_num += 1; |
157 _calc_region_num += 1; |
158 } else { |
158 } else { |
162 _calc_total_used_bytes += hr->used(); |
162 _calc_total_used_bytes += hr->used(); |
163 } |
163 } |
164 |
164 |
165 void HeapRegionSetBase::verify_end() { |
165 void HeapRegionSetBase::verify_end() { |
166 // See comment in verify() about MT safety and verification. |
166 // See comment in verify() about MT safety and verification. |
167 hrl_assert_mt_safety_ok(this); |
167 hrs_assert_mt_safety_ok(this); |
168 assert(_verify_in_progress, |
168 assert(_verify_in_progress, |
169 hrl_ext_msg(this, "verification should be in progress")); |
169 hrs_ext_msg(this, "verification should be in progress")); |
170 |
170 |
171 guarantee(length() == _calc_length, |
171 guarantee(length() == _calc_length, |
172 hrl_err_msg("[%s] length: "SIZE_FORMAT" should be == " |
172 hrs_err_msg("[%s] length: "SIZE_FORMAT" should be == " |
173 "calc length: "SIZE_FORMAT, |
173 "calc length: "SIZE_FORMAT, |
174 name(), length(), _calc_length)); |
174 name(), length(), _calc_length)); |
175 |
175 |
176 guarantee(region_num() == _calc_region_num, |
176 guarantee(region_num() == _calc_region_num, |
177 hrl_err_msg("[%s] region num: "SIZE_FORMAT" should be == " |
177 hrs_err_msg("[%s] region num: "SIZE_FORMAT" should be == " |
178 "calc region num: "SIZE_FORMAT, |
178 "calc region num: "SIZE_FORMAT, |
179 name(), region_num(), _calc_region_num)); |
179 name(), region_num(), _calc_region_num)); |
180 |
180 |
181 guarantee(total_capacity_bytes() == _calc_total_capacity_bytes, |
181 guarantee(total_capacity_bytes() == _calc_total_capacity_bytes, |
182 hrl_err_msg("[%s] capacity bytes: "SIZE_FORMAT" should be == " |
182 hrs_err_msg("[%s] capacity bytes: "SIZE_FORMAT" should be == " |
183 "calc capacity bytes: "SIZE_FORMAT, |
183 "calc capacity bytes: "SIZE_FORMAT, |
184 name(), |
184 name(), |
185 total_capacity_bytes(), _calc_total_capacity_bytes)); |
185 total_capacity_bytes(), _calc_total_capacity_bytes)); |
186 |
186 |
187 guarantee(total_used_bytes() == _calc_total_used_bytes, |
187 guarantee(total_used_bytes() == _calc_total_used_bytes, |
188 hrl_err_msg("[%s] used bytes: "SIZE_FORMAT" should be == " |
188 hrs_err_msg("[%s] used bytes: "SIZE_FORMAT" should be == " |
189 "calc used bytes: "SIZE_FORMAT, |
189 "calc used bytes: "SIZE_FORMAT, |
190 name(), total_used_bytes(), _calc_total_used_bytes)); |
190 name(), total_used_bytes(), _calc_total_used_bytes)); |
191 |
191 |
192 _verify_in_progress = false; |
192 _verify_in_progress = false; |
193 } |
193 } |
219 _calc_total_capacity_bytes(0), _calc_total_used_bytes(0) { } |
219 _calc_total_capacity_bytes(0), _calc_total_used_bytes(0) { } |
220 |
220 |
221 //////////////////// HeapRegionSet //////////////////// |
221 //////////////////// HeapRegionSet //////////////////// |
222 |
222 |
223 void HeapRegionSet::update_from_proxy(HeapRegionSet* proxy_set) { |
223 void HeapRegionSet::update_from_proxy(HeapRegionSet* proxy_set) { |
224 hrl_assert_mt_safety_ok(this); |
224 hrs_assert_mt_safety_ok(this); |
225 hrl_assert_mt_safety_ok(proxy_set); |
225 hrs_assert_mt_safety_ok(proxy_set); |
226 hrl_assert_sets_match(this, proxy_set); |
226 hrs_assert_sets_match(this, proxy_set); |
227 |
227 |
228 verify_optional(); |
228 verify_optional(); |
229 proxy_set->verify_optional(); |
229 proxy_set->verify_optional(); |
230 |
230 |
231 if (proxy_set->is_empty()) return; |
231 if (proxy_set->is_empty()) return; |
232 |
232 |
233 assert(proxy_set->length() <= _length, |
233 assert(proxy_set->length() <= _length, |
234 hrl_err_msg("[%s] proxy set length: "SIZE_FORMAT" " |
234 hrs_err_msg("[%s] proxy set length: "SIZE_FORMAT" " |
235 "should be <= length: "SIZE_FORMAT, |
235 "should be <= length: "SIZE_FORMAT, |
236 name(), proxy_set->length(), _length)); |
236 name(), proxy_set->length(), _length)); |
237 _length -= proxy_set->length(); |
237 _length -= proxy_set->length(); |
238 |
238 |
239 assert(proxy_set->region_num() <= _region_num, |
239 assert(proxy_set->region_num() <= _region_num, |
240 hrl_err_msg("[%s] proxy set region num: "SIZE_FORMAT" " |
240 hrs_err_msg("[%s] proxy set region num: "SIZE_FORMAT" " |
241 "should be <= region num: "SIZE_FORMAT, |
241 "should be <= region num: "SIZE_FORMAT, |
242 name(), proxy_set->region_num(), _region_num)); |
242 name(), proxy_set->region_num(), _region_num)); |
243 _region_num -= proxy_set->region_num(); |
243 _region_num -= proxy_set->region_num(); |
244 |
244 |
245 assert(proxy_set->total_used_bytes() <= _total_used_bytes, |
245 assert(proxy_set->total_used_bytes() <= _total_used_bytes, |
246 hrl_err_msg("[%s] proxy set used bytes: "SIZE_FORMAT" " |
246 hrs_err_msg("[%s] proxy set used bytes: "SIZE_FORMAT" " |
247 "should be <= used bytes: "SIZE_FORMAT, |
247 "should be <= used bytes: "SIZE_FORMAT, |
248 name(), proxy_set->total_used_bytes(), |
248 name(), proxy_set->total_used_bytes(), |
249 _total_used_bytes)); |
249 _total_used_bytes)); |
250 _total_used_bytes -= proxy_set->total_used_bytes(); |
250 _total_used_bytes -= proxy_set->total_used_bytes(); |
251 |
251 |
255 proxy_set->verify_optional(); |
255 proxy_set->verify_optional(); |
256 } |
256 } |
257 |
257 |
258 //////////////////// HeapRegionLinkedList //////////////////// |
258 //////////////////// HeapRegionLinkedList //////////////////// |
259 |
259 |
260 void HeapRegionLinkedList::fill_in_ext_msg_extra(hrl_ext_msg* msg) { |
260 void HeapRegionLinkedList::fill_in_ext_msg_extra(hrs_ext_msg* msg) { |
261 msg->append(" hd: "PTR_FORMAT" tl: "PTR_FORMAT, head(), tail()); |
261 msg->append(" hd: "PTR_FORMAT" tl: "PTR_FORMAT, head(), tail()); |
262 } |
262 } |
263 |
263 |
264 void HeapRegionLinkedList::add_as_tail(HeapRegionLinkedList* from_list) { |
264 void HeapRegionLinkedList::add_as_tail(HeapRegionLinkedList* from_list) { |
265 hrl_assert_mt_safety_ok(this); |
265 hrs_assert_mt_safety_ok(this); |
266 hrl_assert_mt_safety_ok(from_list); |
266 hrs_assert_mt_safety_ok(from_list); |
267 |
267 |
268 verify_optional(); |
268 verify_optional(); |
269 from_list->verify_optional(); |
269 from_list->verify_optional(); |
270 |
270 |
271 if (from_list->is_empty()) return; |
271 if (from_list->is_empty()) return; |
281 hr->set_containing_set(this); |
281 hr->set_containing_set(this); |
282 } |
282 } |
283 #endif // ASSERT |
283 #endif // ASSERT |
284 |
284 |
285 if (_tail != NULL) { |
285 if (_tail != NULL) { |
286 assert(length() > 0 && _head != NULL, hrl_ext_msg(this, "invariant")); |
286 assert(length() > 0 && _head != NULL, hrs_ext_msg(this, "invariant")); |
287 _tail->set_next(from_list->_head); |
287 _tail->set_next(from_list->_head); |
288 } else { |
288 } else { |
289 assert(length() == 0 && _head == NULL, hrl_ext_msg(this, "invariant")); |
289 assert(length() == 0 && _head == NULL, hrs_ext_msg(this, "invariant")); |
290 _head = from_list->_head; |
290 _head = from_list->_head; |
291 } |
291 } |
292 _tail = from_list->_tail; |
292 _tail = from_list->_tail; |
293 |
293 |
294 _length += from_list->length(); |
294 _length += from_list->length(); |
299 verify_optional(); |
299 verify_optional(); |
300 from_list->verify_optional(); |
300 from_list->verify_optional(); |
301 } |
301 } |
302 |
302 |
303 void HeapRegionLinkedList::remove_all() { |
303 void HeapRegionLinkedList::remove_all() { |
304 hrl_assert_mt_safety_ok(this); |
304 hrs_assert_mt_safety_ok(this); |
305 verify_optional(); |
305 verify_optional(); |
306 |
306 |
307 HeapRegion* curr = _head; |
307 HeapRegion* curr = _head; |
308 while (curr != NULL) { |
308 while (curr != NULL) { |
309 hrl_assert_region_ok(this, curr, this); |
309 hrs_assert_region_ok(this, curr, this); |
310 |
310 |
311 HeapRegion* next = curr->next(); |
311 HeapRegion* next = curr->next(); |
312 curr->set_next(NULL); |
312 curr->set_next(NULL); |
313 curr->set_containing_set(NULL); |
313 curr->set_containing_set(NULL); |
314 curr = next; |
314 curr = next; |
317 |
317 |
318 verify_optional(); |
318 verify_optional(); |
319 } |
319 } |
320 |
320 |
321 void HeapRegionLinkedList::remove_all_pending(size_t target_count) { |
321 void HeapRegionLinkedList::remove_all_pending(size_t target_count) { |
322 hrl_assert_mt_safety_ok(this); |
322 hrs_assert_mt_safety_ok(this); |
323 assert(target_count > 1, hrl_ext_msg(this, "pre-condition")); |
323 assert(target_count > 1, hrs_ext_msg(this, "pre-condition")); |
324 assert(!is_empty(), hrl_ext_msg(this, "pre-condition")); |
324 assert(!is_empty(), hrs_ext_msg(this, "pre-condition")); |
325 |
325 |
326 verify_optional(); |
326 verify_optional(); |
327 DEBUG_ONLY(size_t old_length = length();) |
327 DEBUG_ONLY(size_t old_length = length();) |
328 |
328 |
329 HeapRegion* curr = _head; |
329 HeapRegion* curr = _head; |
330 HeapRegion* prev = NULL; |
330 HeapRegion* prev = NULL; |
331 size_t count = 0; |
331 size_t count = 0; |
332 while (curr != NULL) { |
332 while (curr != NULL) { |
333 hrl_assert_region_ok(this, curr, this); |
333 hrs_assert_region_ok(this, curr, this); |
334 HeapRegion* next = curr->next(); |
334 HeapRegion* next = curr->next(); |
335 |
335 |
336 if (curr->pending_removal()) { |
336 if (curr->pending_removal()) { |
337 assert(count < target_count, |
337 assert(count < target_count, |
338 hrl_err_msg("[%s] should not come across more regions " |
338 hrs_err_msg("[%s] should not come across more regions " |
339 "pending for removal than target_count: "SIZE_FORMAT, |
339 "pending for removal than target_count: "SIZE_FORMAT, |
340 name(), target_count)); |
340 name(), target_count)); |
341 |
341 |
342 if (prev == NULL) { |
342 if (prev == NULL) { |
343 assert(_head == curr, hrl_ext_msg(this, "invariant")); |
343 assert(_head == curr, hrs_ext_msg(this, "invariant")); |
344 _head = next; |
344 _head = next; |
345 } else { |
345 } else { |
346 assert(_head != curr, hrl_ext_msg(this, "invariant")); |
346 assert(_head != curr, hrs_ext_msg(this, "invariant")); |
347 prev->set_next(next); |
347 prev->set_next(next); |
348 } |
348 } |
349 if (next == NULL) { |
349 if (next == NULL) { |
350 assert(_tail == curr, hrl_ext_msg(this, "invariant")); |
350 assert(_tail == curr, hrs_ext_msg(this, "invariant")); |
351 _tail = prev; |
351 _tail = prev; |
352 } else { |
352 } else { |
353 assert(_tail != curr, hrl_ext_msg(this, "invariant")); |
353 assert(_tail != curr, hrs_ext_msg(this, "invariant")); |
354 } |
354 } |
355 |
355 |
356 curr->set_next(NULL); |
356 curr->set_next(NULL); |
357 remove_internal(curr); |
357 remove_internal(curr); |
358 curr->set_pending_removal(false); |
358 curr->set_pending_removal(false); |
369 } |
369 } |
370 curr = next; |
370 curr = next; |
371 } |
371 } |
372 |
372 |
373 assert(count == target_count, |
373 assert(count == target_count, |
374 hrl_err_msg("[%s] count: "SIZE_FORMAT" should be == " |
374 hrs_err_msg("[%s] count: "SIZE_FORMAT" should be == " |
375 "target_count: "SIZE_FORMAT, name(), count, target_count)); |
375 "target_count: "SIZE_FORMAT, name(), count, target_count)); |
376 assert(length() + target_count == old_length, |
376 assert(length() + target_count == old_length, |
377 hrl_err_msg("[%s] new length should be consistent " |
377 hrs_err_msg("[%s] new length should be consistent " |
378 "new length: "SIZE_FORMAT" old length: "SIZE_FORMAT" " |
378 "new length: "SIZE_FORMAT" old length: "SIZE_FORMAT" " |
379 "target_count: "SIZE_FORMAT, |
379 "target_count: "SIZE_FORMAT, |
380 name(), length(), old_length, target_count)); |
380 name(), length(), old_length, target_count)); |
381 |
381 |
382 verify_optional(); |
382 verify_optional(); |
383 } |
383 } |
384 |
384 |
385 void HeapRegionLinkedList::verify() { |
385 void HeapRegionLinkedList::verify() { |
386 // See comment in HeapRegionSetBase::verify() about MT safety and |
386 // See comment in HeapRegionSetBase::verify() about MT safety and |
387 // verification. |
387 // verification. |
388 hrl_assert_mt_safety_ok(this); |
388 hrs_assert_mt_safety_ok(this); |
389 |
389 |
390 // This will also do the basic verification too. |
390 // This will also do the basic verification too. |
391 verify_start(); |
391 verify_start(); |
392 |
392 |
393 HeapRegion* curr = _head; |
393 HeapRegion* curr = _head; |
397 while (curr != NULL) { |
397 while (curr != NULL) { |
398 verify_next_region(curr); |
398 verify_next_region(curr); |
399 |
399 |
400 count += 1; |
400 count += 1; |
401 guarantee(count < _unrealistically_long_length, |
401 guarantee(count < _unrealistically_long_length, |
402 hrl_err_msg("[%s] the calculated length: "SIZE_FORMAT" " |
402 hrs_err_msg("[%s] the calculated length: "SIZE_FORMAT" " |
403 "seems very long, is there maybe a cycle? " |
403 "seems very long, is there maybe a cycle? " |
404 "curr: "PTR_FORMAT" prev0: "PTR_FORMAT" " |
404 "curr: "PTR_FORMAT" prev0: "PTR_FORMAT" " |
405 "prev1: "PTR_FORMAT" length: "SIZE_FORMAT, |
405 "prev1: "PTR_FORMAT" length: "SIZE_FORMAT, |
406 name(), count, curr, prev0, prev1, length())); |
406 name(), count, curr, prev0, prev1, length())); |
407 |
407 |
408 prev1 = prev0; |
408 prev1 = prev0; |
409 prev0 = curr; |
409 prev0 = curr; |
410 curr = curr->next(); |
410 curr = curr->next(); |
411 } |
411 } |
412 |
412 |
413 guarantee(_tail == prev0, hrl_ext_msg(this, "post-condition")); |
413 guarantee(_tail == prev0, hrs_ext_msg(this, "post-condition")); |
414 |
414 |
415 verify_end(); |
415 verify_end(); |
416 } |
416 } |
417 |
417 |
418 void HeapRegionLinkedList::clear() { |
418 void HeapRegionLinkedList::clear() { |