Mercurial > hg > graal-jvmci-8
annotate src/share/vm/gc_implementation/g1/heapRegionSet.cpp @ 3919:4f41766176cf
7084509: G1: fix inconsistencies and mistakes in the young list target length calculations
Summary: Fixed inconsistencies and mistakes in the young list target length calculations so that a) the calculated target length is optimal (before, it was not), b) other parameters like max survivor size and max gc locker eden expansion are always consistent with the calculated target length (before, they were not always), and c) the resulting target length was always bound by desired min and max values (before, it was not).
Reviewed-by: brutisso, johnc
author | tonyp |
---|---|
date | Thu, 08 Sep 2011 05:16:49 -0400 |
parents | 455328d90876 |
children | 8aae2050e83e |
rev | line source |
---|---|
2152 | 1 /* |
2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 * | |
23 */ | |
24 | |
25 #include "precompiled.hpp" | |
26 #include "gc_implementation/g1/heapRegionSet.inline.hpp" | |
27 | |
28 size_t HeapRegionSetBase::_unrealistically_long_length = 0; | |
29 | |
30 //////////////////// HeapRegionSetBase //////////////////// | |
31 | |
32 void HeapRegionSetBase::set_unrealistically_long_length(size_t len) { | |
33 guarantee(_unrealistically_long_length == 0, "should only be set once"); | |
34 _unrealistically_long_length = len; | |
35 } | |
36 | |
37 size_t HeapRegionSetBase::calculate_region_num(HeapRegion* hr) { | |
38 assert(hr->startsHumongous(), "pre-condition"); | |
39 assert(hr->capacity() % HeapRegion::GrainBytes == 0, "invariant"); | |
40 size_t region_num = hr->capacity() >> HeapRegion::LogOfHRGrainBytes; | |
41 assert(region_num > 0, "sanity"); | |
42 return region_num; | |
43 } | |
44 | |
2361 | 45 void HeapRegionSetBase::fill_in_ext_msg(hrs_ext_msg* msg, const char* message) { |
2152 | 46 msg->append("[%s] %s " |
47 "ln: "SIZE_FORMAT" rn: "SIZE_FORMAT" " | |
48 "cy: "SIZE_FORMAT" ud: "SIZE_FORMAT, | |
49 name(), message, length(), region_num(), | |
50 total_capacity_bytes(), total_used_bytes()); | |
51 fill_in_ext_msg_extra(msg); | |
52 } | |
53 | |
54 bool HeapRegionSetBase::verify_region(HeapRegion* hr, | |
55 HeapRegionSetBase* expected_containing_set) { | |
56 const char* error_message = NULL; | |
57 | |
58 if (!regions_humongous()) { | |
59 if (hr->isHumongous()) { | |
60 error_message = "the region should not be humongous"; | |
61 } | |
62 } else { | |
63 if (!hr->isHumongous() || !hr->startsHumongous()) { | |
64 error_message = "the region should be 'starts humongous'"; | |
65 } | |
66 } | |
67 | |
68 if (!regions_empty()) { | |
69 if (hr->is_empty()) { | |
70 error_message = "the region should not be empty"; | |
71 } | |
72 } else { | |
73 if (!hr->is_empty()) { | |
74 error_message = "the region should be empty"; | |
75 } | |
76 } | |
77 | |
78 #ifdef ASSERT | |
79 // The _containing_set field is only available when ASSERT is defined. | |
80 if (hr->containing_set() != expected_containing_set) { | |
81 error_message = "inconsistent containing set found"; | |
82 } | |
83 #endif // ASSERT | |
84 | |
85 const char* extra_error_message = verify_region_extra(hr); | |
86 if (extra_error_message != NULL) { | |
87 error_message = extra_error_message; | |
88 } | |
89 | |
90 if (error_message != NULL) { | |
91 outputStream* out = tty; | |
92 out->cr(); | |
93 out->print_cr("## [%s] %s", name(), error_message); | |
94 out->print_cr("## Offending Region: "PTR_FORMAT, hr); | |
95 out->print_cr(" "HR_FORMAT, HR_FORMAT_PARAMS(hr)); | |
96 #ifdef ASSERT | |
97 out->print_cr(" containing set: "PTR_FORMAT, hr->containing_set()); | |
98 #endif // ASSERT | |
99 out->print_cr("## Offending Region Set: "PTR_FORMAT, this); | |
100 print_on(out); | |
101 return false; | |
102 } else { | |
103 return true; | |
104 } | |
105 } | |
106 | |
107 void HeapRegionSetBase::verify() { | |
108 // It's important that we also observe the MT safety protocol even | |
109 // for the verification calls. If we do verification without the | |
110 // appropriate locks and the set changes underneath our feet | |
111 // verification might fail and send us on a wild goose chase. | |
2361 | 112 hrs_assert_mt_safety_ok(this); |
2152 | 113 |
114 guarantee(( is_empty() && length() == 0 && region_num() == 0 && | |
115 total_used_bytes() == 0 && total_capacity_bytes() == 0) || | |
116 (!is_empty() && length() >= 0 && region_num() >= 0 && | |
117 total_used_bytes() >= 0 && total_capacity_bytes() >= 0), | |
2361 | 118 hrs_ext_msg(this, "invariant")); |
2152 | 119 |
120 guarantee((!regions_humongous() && region_num() == length()) || | |
121 ( regions_humongous() && region_num() >= length()), | |
2361 | 122 hrs_ext_msg(this, "invariant")); |
2152 | 123 |
124 guarantee(!regions_empty() || total_used_bytes() == 0, | |
2361 | 125 hrs_ext_msg(this, "invariant")); |
2152 | 126 |
127 guarantee(total_used_bytes() <= total_capacity_bytes(), | |
2361 | 128 hrs_ext_msg(this, "invariant")); |
2152 | 129 } |
130 | |
131 void HeapRegionSetBase::verify_start() { | |
132 // See comment in verify() about MT safety and verification. | |
2361 | 133 hrs_assert_mt_safety_ok(this); |
2152 | 134 assert(!_verify_in_progress, |
2361 | 135 hrs_ext_msg(this, "verification should not be in progress")); |
2152 | 136 |
137 // Do the basic verification first before we do the checks over the regions. | |
138 HeapRegionSetBase::verify(); | |
139 | |
140 _calc_length = 0; | |
141 _calc_region_num = 0; | |
142 _calc_total_capacity_bytes = 0; | |
143 _calc_total_used_bytes = 0; | |
144 _verify_in_progress = true; | |
145 } | |
146 | |
147 void HeapRegionSetBase::verify_next_region(HeapRegion* hr) { | |
148 // See comment in verify() about MT safety and verification. | |
2361 | 149 hrs_assert_mt_safety_ok(this); |
2152 | 150 assert(_verify_in_progress, |
2361 | 151 hrs_ext_msg(this, "verification should be in progress")); |
2152 | 152 |
2361 | 153 guarantee(verify_region(hr, this), hrs_ext_msg(this, "region verification")); |
2152 | 154 |
155 _calc_length += 1; | |
156 if (!hr->isHumongous()) { | |
157 _calc_region_num += 1; | |
158 } else { | |
159 _calc_region_num += calculate_region_num(hr); | |
160 } | |
161 _calc_total_capacity_bytes += hr->capacity(); | |
162 _calc_total_used_bytes += hr->used(); | |
163 } | |
164 | |
165 void HeapRegionSetBase::verify_end() { | |
166 // See comment in verify() about MT safety and verification. | |
2361 | 167 hrs_assert_mt_safety_ok(this); |
2152 | 168 assert(_verify_in_progress, |
2361 | 169 hrs_ext_msg(this, "verification should be in progress")); |
2152 | 170 |
171 guarantee(length() == _calc_length, | |
2361 | 172 hrs_err_msg("[%s] length: "SIZE_FORMAT" should be == " |
2152 | 173 "calc length: "SIZE_FORMAT, |
174 name(), length(), _calc_length)); | |
175 | |
176 guarantee(region_num() == _calc_region_num, | |
2361 | 177 hrs_err_msg("[%s] region num: "SIZE_FORMAT" should be == " |
2152 | 178 "calc region num: "SIZE_FORMAT, |
179 name(), region_num(), _calc_region_num)); | |
180 | |
181 guarantee(total_capacity_bytes() == _calc_total_capacity_bytes, | |
2361 | 182 hrs_err_msg("[%s] capacity bytes: "SIZE_FORMAT" should be == " |
2152 | 183 "calc capacity bytes: "SIZE_FORMAT, |
184 name(), | |
185 total_capacity_bytes(), _calc_total_capacity_bytes)); | |
186 | |
187 guarantee(total_used_bytes() == _calc_total_used_bytes, | |
2361 | 188 hrs_err_msg("[%s] used bytes: "SIZE_FORMAT" should be == " |
2152 | 189 "calc used bytes: "SIZE_FORMAT, |
190 name(), total_used_bytes(), _calc_total_used_bytes)); | |
191 | |
192 _verify_in_progress = false; | |
193 } | |
194 | |
195 void HeapRegionSetBase::print_on(outputStream* out, bool print_contents) { | |
196 out->cr(); | |
197 out->print_cr("Set: %s ("PTR_FORMAT")", name(), this); | |
198 out->print_cr(" Region Assumptions"); | |
199 out->print_cr(" humongous : %s", BOOL_TO_STR(regions_humongous())); | |
200 out->print_cr(" empty : %s", BOOL_TO_STR(regions_empty())); | |
201 out->print_cr(" Attributes"); | |
202 out->print_cr(" length : "SIZE_FORMAT_W(14), length()); | |
203 out->print_cr(" region num : "SIZE_FORMAT_W(14), region_num()); | |
204 out->print_cr(" total capacity : "SIZE_FORMAT_W(14)" bytes", | |
205 total_capacity_bytes()); | |
206 out->print_cr(" total used : "SIZE_FORMAT_W(14)" bytes", | |
207 total_used_bytes()); | |
208 } | |
209 | |
210 void HeapRegionSetBase::clear() { | |
211 _length = 0; | |
212 _region_num = 0; | |
213 _total_used_bytes = 0; | |
214 } | |
215 | |
216 HeapRegionSetBase::HeapRegionSetBase(const char* name) | |
217 : _name(name), _verify_in_progress(false), | |
218 _calc_length(0), _calc_region_num(0), | |
219 _calc_total_capacity_bytes(0), _calc_total_used_bytes(0) { } | |
220 | |
221 //////////////////// HeapRegionSet //////////////////// | |
222 | |
223 void HeapRegionSet::update_from_proxy(HeapRegionSet* proxy_set) { | |
2361 | 224 hrs_assert_mt_safety_ok(this); |
225 hrs_assert_mt_safety_ok(proxy_set); | |
226 hrs_assert_sets_match(this, proxy_set); | |
2152 | 227 |
228 verify_optional(); | |
229 proxy_set->verify_optional(); | |
230 | |
231 if (proxy_set->is_empty()) return; | |
232 | |
233 assert(proxy_set->length() <= _length, | |
2361 | 234 hrs_err_msg("[%s] proxy set length: "SIZE_FORMAT" " |
2152 | 235 "should be <= length: "SIZE_FORMAT, |
236 name(), proxy_set->length(), _length)); | |
237 _length -= proxy_set->length(); | |
238 | |
239 assert(proxy_set->region_num() <= _region_num, | |
2361 | 240 hrs_err_msg("[%s] proxy set region num: "SIZE_FORMAT" " |
2152 | 241 "should be <= region num: "SIZE_FORMAT, |
242 name(), proxy_set->region_num(), _region_num)); | |
243 _region_num -= proxy_set->region_num(); | |
244 | |
245 assert(proxy_set->total_used_bytes() <= _total_used_bytes, | |
2361 | 246 hrs_err_msg("[%s] proxy set used bytes: "SIZE_FORMAT" " |
2152 | 247 "should be <= used bytes: "SIZE_FORMAT, |
248 name(), proxy_set->total_used_bytes(), | |
249 _total_used_bytes)); | |
250 _total_used_bytes -= proxy_set->total_used_bytes(); | |
251 | |
252 proxy_set->clear(); | |
253 | |
254 verify_optional(); | |
255 proxy_set->verify_optional(); | |
256 } | |
257 | |
258 //////////////////// HeapRegionLinkedList //////////////////// | |
259 | |
2361 | 260 void HeapRegionLinkedList::fill_in_ext_msg_extra(hrs_ext_msg* msg) { |
2152 | 261 msg->append(" hd: "PTR_FORMAT" tl: "PTR_FORMAT, head(), tail()); |
262 } | |
263 | |
2432
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
264 void HeapRegionLinkedList::add_as_head(HeapRegionLinkedList* from_list) { |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
265 hrs_assert_mt_safety_ok(this); |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
266 hrs_assert_mt_safety_ok(from_list); |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
267 |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
268 verify_optional(); |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
269 from_list->verify_optional(); |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
270 |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
271 if (from_list->is_empty()) return; |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
272 |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
273 #ifdef ASSERT |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
274 HeapRegionLinkedListIterator iter(from_list); |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
275 while (iter.more_available()) { |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
276 HeapRegion* hr = iter.get_next(); |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
277 // In set_containing_set() we check that we either set the value |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
278 // from NULL to non-NULL or vice versa to catch bugs. So, we have |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
279 // to NULL it first before setting it to the value. |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
280 hr->set_containing_set(NULL); |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
281 hr->set_containing_set(this); |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
282 } |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
283 #endif // ASSERT |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
284 |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
285 if (_head != NULL) { |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
286 assert(length() > 0 && _tail != NULL, hrs_ext_msg(this, "invariant")); |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
287 from_list->_tail->set_next(_head); |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
288 } else { |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
289 assert(length() == 0 && _head == NULL, hrs_ext_msg(this, "invariant")); |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
290 _tail = from_list->_tail; |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
291 } |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
292 _head = from_list->_head; |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
293 |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
294 _length += from_list->length(); |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
295 _region_num += from_list->region_num(); |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
296 _total_used_bytes += from_list->total_used_bytes(); |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
297 from_list->clear(); |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
298 |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
299 verify_optional(); |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
300 from_list->verify_optional(); |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
301 } |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
302 |
2152 | 303 void HeapRegionLinkedList::add_as_tail(HeapRegionLinkedList* from_list) { |
2361 | 304 hrs_assert_mt_safety_ok(this); |
305 hrs_assert_mt_safety_ok(from_list); | |
2152 | 306 |
307 verify_optional(); | |
308 from_list->verify_optional(); | |
309 | |
310 if (from_list->is_empty()) return; | |
311 | |
312 #ifdef ASSERT | |
313 HeapRegionLinkedListIterator iter(from_list); | |
314 while (iter.more_available()) { | |
315 HeapRegion* hr = iter.get_next(); | |
316 // In set_containing_set() we check that we either set the value | |
317 // from NULL to non-NULL or vice versa to catch bugs. So, we have | |
318 // to NULL it first before setting it to the value. | |
319 hr->set_containing_set(NULL); | |
320 hr->set_containing_set(this); | |
321 } | |
322 #endif // ASSERT | |
323 | |
324 if (_tail != NULL) { | |
2361 | 325 assert(length() > 0 && _head != NULL, hrs_ext_msg(this, "invariant")); |
2152 | 326 _tail->set_next(from_list->_head); |
327 } else { | |
2361 | 328 assert(length() == 0 && _head == NULL, hrs_ext_msg(this, "invariant")); |
2152 | 329 _head = from_list->_head; |
330 } | |
331 _tail = from_list->_tail; | |
332 | |
333 _length += from_list->length(); | |
334 _region_num += from_list->region_num(); | |
335 _total_used_bytes += from_list->total_used_bytes(); | |
336 from_list->clear(); | |
337 | |
338 verify_optional(); | |
339 from_list->verify_optional(); | |
340 } | |
341 | |
342 void HeapRegionLinkedList::remove_all() { | |
2361 | 343 hrs_assert_mt_safety_ok(this); |
2152 | 344 verify_optional(); |
345 | |
346 HeapRegion* curr = _head; | |
347 while (curr != NULL) { | |
2361 | 348 hrs_assert_region_ok(this, curr, this); |
2152 | 349 |
350 HeapRegion* next = curr->next(); | |
351 curr->set_next(NULL); | |
352 curr->set_containing_set(NULL); | |
353 curr = next; | |
354 } | |
355 clear(); | |
356 | |
357 verify_optional(); | |
358 } | |
359 | |
360 void HeapRegionLinkedList::remove_all_pending(size_t target_count) { | |
2361 | 361 hrs_assert_mt_safety_ok(this); |
362 assert(target_count > 1, hrs_ext_msg(this, "pre-condition")); | |
363 assert(!is_empty(), hrs_ext_msg(this, "pre-condition")); | |
2152 | 364 |
365 verify_optional(); | |
366 DEBUG_ONLY(size_t old_length = length();) | |
367 | |
368 HeapRegion* curr = _head; | |
369 HeapRegion* prev = NULL; | |
370 size_t count = 0; | |
371 while (curr != NULL) { | |
2361 | 372 hrs_assert_region_ok(this, curr, this); |
2152 | 373 HeapRegion* next = curr->next(); |
374 | |
375 if (curr->pending_removal()) { | |
376 assert(count < target_count, | |
2361 | 377 hrs_err_msg("[%s] should not come across more regions " |
2152 | 378 "pending for removal than target_count: "SIZE_FORMAT, |
379 name(), target_count)); | |
380 | |
381 if (prev == NULL) { | |
2361 | 382 assert(_head == curr, hrs_ext_msg(this, "invariant")); |
2152 | 383 _head = next; |
384 } else { | |
2361 | 385 assert(_head != curr, hrs_ext_msg(this, "invariant")); |
2152 | 386 prev->set_next(next); |
387 } | |
388 if (next == NULL) { | |
2361 | 389 assert(_tail == curr, hrs_ext_msg(this, "invariant")); |
2152 | 390 _tail = prev; |
391 } else { | |
2361 | 392 assert(_tail != curr, hrs_ext_msg(this, "invariant")); |
2152 | 393 } |
394 | |
395 curr->set_next(NULL); | |
396 remove_internal(curr); | |
397 curr->set_pending_removal(false); | |
398 | |
399 count += 1; | |
400 | |
401 // If we have come across the target number of regions we can | |
402 // just bail out. However, for debugging purposes, we can just | |
403 // carry on iterating to make sure there are not more regions | |
404 // tagged with pending removal. | |
405 DEBUG_ONLY(if (count == target_count) break;) | |
406 } else { | |
407 prev = curr; | |
408 } | |
409 curr = next; | |
410 } | |
411 | |
412 assert(count == target_count, | |
2361 | 413 hrs_err_msg("[%s] count: "SIZE_FORMAT" should be == " |
2152 | 414 "target_count: "SIZE_FORMAT, name(), count, target_count)); |
415 assert(length() + target_count == old_length, | |
2361 | 416 hrs_err_msg("[%s] new length should be consistent " |
2152 | 417 "new length: "SIZE_FORMAT" old length: "SIZE_FORMAT" " |
418 "target_count: "SIZE_FORMAT, | |
419 name(), length(), old_length, target_count)); | |
420 | |
421 verify_optional(); | |
422 } | |
423 | |
424 void HeapRegionLinkedList::verify() { | |
425 // See comment in HeapRegionSetBase::verify() about MT safety and | |
426 // verification. | |
2361 | 427 hrs_assert_mt_safety_ok(this); |
2152 | 428 |
429 // This will also do the basic verification too. | |
430 verify_start(); | |
431 | |
432 HeapRegion* curr = _head; | |
433 HeapRegion* prev1 = NULL; | |
434 HeapRegion* prev0 = NULL; | |
435 size_t count = 0; | |
436 while (curr != NULL) { | |
437 verify_next_region(curr); | |
438 | |
439 count += 1; | |
440 guarantee(count < _unrealistically_long_length, | |
2361 | 441 hrs_err_msg("[%s] the calculated length: "SIZE_FORMAT" " |
2152 | 442 "seems very long, is there maybe a cycle? " |
443 "curr: "PTR_FORMAT" prev0: "PTR_FORMAT" " | |
444 "prev1: "PTR_FORMAT" length: "SIZE_FORMAT, | |
445 name(), count, curr, prev0, prev1, length())); | |
446 | |
447 prev1 = prev0; | |
448 prev0 = curr; | |
449 curr = curr->next(); | |
450 } | |
451 | |
2361 | 452 guarantee(_tail == prev0, hrs_ext_msg(this, "post-condition")); |
2152 | 453 |
454 verify_end(); | |
455 } | |
456 | |
457 void HeapRegionLinkedList::clear() { | |
458 HeapRegionSetBase::clear(); | |
459 _head = NULL; | |
460 _tail = NULL; | |
461 } | |
462 | |
463 void HeapRegionLinkedList::print_on(outputStream* out, bool print_contents) { | |
464 HeapRegionSetBase::print_on(out, print_contents); | |
465 out->print_cr(" Linking"); | |
466 out->print_cr(" head : "PTR_FORMAT, _head); | |
467 out->print_cr(" tail : "PTR_FORMAT, _tail); | |
468 | |
469 if (print_contents) { | |
470 out->print_cr(" Contents"); | |
471 HeapRegionLinkedListIterator iter(this); | |
472 while (iter.more_available()) { | |
473 HeapRegion* hr = iter.get_next(); | |
474 hr->print_on(out); | |
475 } | |
476 } | |
477 } |