Mercurial > hg > graal-jvmci-8
annotate src/share/vm/gc_implementation/g1/heapRegionSet.cpp @ 6611:7383557659bd
7185699: G1: Prediction model discrepancies
Summary: Correct the result value of G1CollectedHeap::pending_card_num(). Change the code that calculates the GC efficiency of a non-young heap region to use historical data from mixed GCs and the actual number of live bytes when predicting how long it would take to collect the region. Changes were also reviewed by Thomas Schatzl.
Reviewed-by: azeemj, brutisso
author | johnc |
---|---|
date | Tue, 21 Aug 2012 14:10:39 -0700 |
parents | a2f7274eb6ef |
children | 992f62c457b0 58fc1b1523dc |
rev | line source |
---|---|
2152 | 1 /* |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
2 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. |
2152 | 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 | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
28 uint HeapRegionSetBase::_unrealistically_long_length = 0; |
4072 | 29 HRSPhase HeapRegionSetBase::_phase = HRSPhaseNone; |
2152 | 30 |
31 //////////////////// HeapRegionSetBase //////////////////// | |
32 | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
33 void HeapRegionSetBase::set_unrealistically_long_length(uint len) { |
2152 | 34 guarantee(_unrealistically_long_length == 0, "should only be set once"); |
35 _unrealistically_long_length = len; | |
36 } | |
37 | |
2361 | 38 void HeapRegionSetBase::fill_in_ext_msg(hrs_ext_msg* msg, const char* message) { |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
39 msg->append("[%s] %s ln: %u rn: %u cy: "SIZE_FORMAT" ud: "SIZE_FORMAT, |
2152 | 40 name(), message, length(), region_num(), |
41 total_capacity_bytes(), total_used_bytes()); | |
42 fill_in_ext_msg_extra(msg); | |
43 } | |
44 | |
45 bool HeapRegionSetBase::verify_region(HeapRegion* hr, | |
46 HeapRegionSetBase* expected_containing_set) { | |
47 const char* error_message = NULL; | |
48 | |
49 if (!regions_humongous()) { | |
50 if (hr->isHumongous()) { | |
51 error_message = "the region should not be humongous"; | |
52 } | |
53 } else { | |
54 if (!hr->isHumongous() || !hr->startsHumongous()) { | |
55 error_message = "the region should be 'starts humongous'"; | |
56 } | |
57 } | |
58 | |
59 if (!regions_empty()) { | |
60 if (hr->is_empty()) { | |
61 error_message = "the region should not be empty"; | |
62 } | |
63 } else { | |
64 if (!hr->is_empty()) { | |
65 error_message = "the region should be empty"; | |
66 } | |
67 } | |
68 | |
69 #ifdef ASSERT | |
70 // The _containing_set field is only available when ASSERT is defined. | |
71 if (hr->containing_set() != expected_containing_set) { | |
72 error_message = "inconsistent containing set found"; | |
73 } | |
74 #endif // ASSERT | |
75 | |
76 const char* extra_error_message = verify_region_extra(hr); | |
77 if (extra_error_message != NULL) { | |
78 error_message = extra_error_message; | |
79 } | |
80 | |
81 if (error_message != NULL) { | |
82 outputStream* out = tty; | |
83 out->cr(); | |
84 out->print_cr("## [%s] %s", name(), error_message); | |
85 out->print_cr("## Offending Region: "PTR_FORMAT, hr); | |
86 out->print_cr(" "HR_FORMAT, HR_FORMAT_PARAMS(hr)); | |
87 #ifdef ASSERT | |
88 out->print_cr(" containing set: "PTR_FORMAT, hr->containing_set()); | |
89 #endif // ASSERT | |
90 out->print_cr("## Offending Region Set: "PTR_FORMAT, this); | |
91 print_on(out); | |
92 return false; | |
93 } else { | |
94 return true; | |
95 } | |
96 } | |
97 | |
98 void HeapRegionSetBase::verify() { | |
99 // It's important that we also observe the MT safety protocol even | |
100 // for the verification calls. If we do verification without the | |
101 // appropriate locks and the set changes underneath our feet | |
102 // verification might fail and send us on a wild goose chase. | |
2361 | 103 hrs_assert_mt_safety_ok(this); |
2152 | 104 |
105 guarantee(( is_empty() && length() == 0 && region_num() == 0 && | |
106 total_used_bytes() == 0 && total_capacity_bytes() == 0) || | |
107 (!is_empty() && length() >= 0 && region_num() >= 0 && | |
108 total_used_bytes() >= 0 && total_capacity_bytes() >= 0), | |
2361 | 109 hrs_ext_msg(this, "invariant")); |
2152 | 110 |
111 guarantee((!regions_humongous() && region_num() == length()) || | |
112 ( regions_humongous() && region_num() >= length()), | |
2361 | 113 hrs_ext_msg(this, "invariant")); |
2152 | 114 |
115 guarantee(!regions_empty() || total_used_bytes() == 0, | |
2361 | 116 hrs_ext_msg(this, "invariant")); |
2152 | 117 |
118 guarantee(total_used_bytes() <= total_capacity_bytes(), | |
2361 | 119 hrs_ext_msg(this, "invariant")); |
2152 | 120 } |
121 | |
122 void HeapRegionSetBase::verify_start() { | |
123 // See comment in verify() about MT safety and verification. | |
2361 | 124 hrs_assert_mt_safety_ok(this); |
2152 | 125 assert(!_verify_in_progress, |
2361 | 126 hrs_ext_msg(this, "verification should not be in progress")); |
2152 | 127 |
128 // Do the basic verification first before we do the checks over the regions. | |
129 HeapRegionSetBase::verify(); | |
130 | |
131 _calc_length = 0; | |
132 _calc_region_num = 0; | |
133 _calc_total_capacity_bytes = 0; | |
134 _calc_total_used_bytes = 0; | |
135 _verify_in_progress = true; | |
136 } | |
137 | |
138 void HeapRegionSetBase::verify_next_region(HeapRegion* hr) { | |
139 // See comment in verify() about MT safety and verification. | |
2361 | 140 hrs_assert_mt_safety_ok(this); |
2152 | 141 assert(_verify_in_progress, |
2361 | 142 hrs_ext_msg(this, "verification should be in progress")); |
2152 | 143 |
2361 | 144 guarantee(verify_region(hr, this), hrs_ext_msg(this, "region verification")); |
2152 | 145 |
146 _calc_length += 1; | |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6252
diff
changeset
|
147 _calc_region_num += hr->region_num(); |
2152 | 148 _calc_total_capacity_bytes += hr->capacity(); |
149 _calc_total_used_bytes += hr->used(); | |
150 } | |
151 | |
152 void HeapRegionSetBase::verify_end() { | |
153 // See comment in verify() about MT safety and verification. | |
2361 | 154 hrs_assert_mt_safety_ok(this); |
2152 | 155 assert(_verify_in_progress, |
2361 | 156 hrs_ext_msg(this, "verification should be in progress")); |
2152 | 157 |
158 guarantee(length() == _calc_length, | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
159 hrs_err_msg("[%s] length: %u should be == calc length: %u", |
2152 | 160 name(), length(), _calc_length)); |
161 | |
162 guarantee(region_num() == _calc_region_num, | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
163 hrs_err_msg("[%s] region num: %u should be == calc region num: %u", |
2152 | 164 name(), region_num(), _calc_region_num)); |
165 | |
166 guarantee(total_capacity_bytes() == _calc_total_capacity_bytes, | |
2361 | 167 hrs_err_msg("[%s] capacity bytes: "SIZE_FORMAT" should be == " |
2152 | 168 "calc capacity bytes: "SIZE_FORMAT, |
169 name(), | |
170 total_capacity_bytes(), _calc_total_capacity_bytes)); | |
171 | |
172 guarantee(total_used_bytes() == _calc_total_used_bytes, | |
2361 | 173 hrs_err_msg("[%s] used bytes: "SIZE_FORMAT" should be == " |
2152 | 174 "calc used bytes: "SIZE_FORMAT, |
175 name(), total_used_bytes(), _calc_total_used_bytes)); | |
176 | |
177 _verify_in_progress = false; | |
178 } | |
179 | |
4072 | 180 void HeapRegionSetBase::clear_phase() { |
181 assert(_phase != HRSPhaseNone, "pre-condition"); | |
182 _phase = HRSPhaseNone; | |
183 } | |
184 | |
185 void HeapRegionSetBase::set_phase(HRSPhase phase) { | |
186 assert(_phase == HRSPhaseNone, "pre-condition"); | |
187 assert(phase != HRSPhaseNone, "pre-condition"); | |
188 _phase = phase; | |
189 } | |
190 | |
2152 | 191 void HeapRegionSetBase::print_on(outputStream* out, bool print_contents) { |
192 out->cr(); | |
193 out->print_cr("Set: %s ("PTR_FORMAT")", name(), this); | |
194 out->print_cr(" Region Assumptions"); | |
195 out->print_cr(" humongous : %s", BOOL_TO_STR(regions_humongous())); | |
196 out->print_cr(" empty : %s", BOOL_TO_STR(regions_empty())); | |
197 out->print_cr(" Attributes"); | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
198 out->print_cr(" length : %14u", length()); |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
199 out->print_cr(" region num : %14u", region_num()); |
2152 | 200 out->print_cr(" total capacity : "SIZE_FORMAT_W(14)" bytes", |
201 total_capacity_bytes()); | |
202 out->print_cr(" total used : "SIZE_FORMAT_W(14)" bytes", | |
203 total_used_bytes()); | |
204 } | |
205 | |
206 void HeapRegionSetBase::clear() { | |
207 _length = 0; | |
208 _region_num = 0; | |
209 _total_used_bytes = 0; | |
210 } | |
211 | |
212 HeapRegionSetBase::HeapRegionSetBase(const char* name) | |
213 : _name(name), _verify_in_progress(false), | |
214 _calc_length(0), _calc_region_num(0), | |
215 _calc_total_capacity_bytes(0), _calc_total_used_bytes(0) { } | |
216 | |
217 //////////////////// HeapRegionSet //////////////////// | |
218 | |
219 void HeapRegionSet::update_from_proxy(HeapRegionSet* proxy_set) { | |
2361 | 220 hrs_assert_mt_safety_ok(this); |
221 hrs_assert_mt_safety_ok(proxy_set); | |
222 hrs_assert_sets_match(this, proxy_set); | |
2152 | 223 |
224 verify_optional(); | |
225 proxy_set->verify_optional(); | |
226 | |
227 if (proxy_set->is_empty()) return; | |
228 | |
229 assert(proxy_set->length() <= _length, | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
230 hrs_err_msg("[%s] proxy set length: %u should be <= length: %u", |
2152 | 231 name(), proxy_set->length(), _length)); |
232 _length -= proxy_set->length(); | |
233 | |
234 assert(proxy_set->region_num() <= _region_num, | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
235 hrs_err_msg("[%s] proxy set region num: %u should be <= region num: %u", |
2152 | 236 name(), proxy_set->region_num(), _region_num)); |
237 _region_num -= proxy_set->region_num(); | |
238 | |
239 assert(proxy_set->total_used_bytes() <= _total_used_bytes, | |
2361 | 240 hrs_err_msg("[%s] proxy set used bytes: "SIZE_FORMAT" " |
2152 | 241 "should be <= used bytes: "SIZE_FORMAT, |
242 name(), proxy_set->total_used_bytes(), | |
243 _total_used_bytes)); | |
244 _total_used_bytes -= proxy_set->total_used_bytes(); | |
245 | |
246 proxy_set->clear(); | |
247 | |
248 verify_optional(); | |
249 proxy_set->verify_optional(); | |
250 } | |
251 | |
252 //////////////////// HeapRegionLinkedList //////////////////// | |
253 | |
2361 | 254 void HeapRegionLinkedList::fill_in_ext_msg_extra(hrs_ext_msg* msg) { |
2152 | 255 msg->append(" hd: "PTR_FORMAT" tl: "PTR_FORMAT, head(), tail()); |
256 } | |
257 | |
2432
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
258 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
|
259 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
|
260 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
|
261 |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
262 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
|
263 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
|
264 |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
265 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
|
266 |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
267 #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
|
268 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
|
269 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
|
270 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
|
271 // 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
|
272 // 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
|
273 // 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
|
274 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
|
275 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
|
276 } |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
277 #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
|
278 |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
279 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
|
280 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
|
281 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
|
282 } else { |
6252
d42fe3c3001d
7184772: G1: Incorrect assert in HeapRegionLinkedList::add_as_head()
johnc
parents:
6010
diff
changeset
|
283 assert(length() == 0 && _tail == NULL, hrs_ext_msg(this, "invariant")); |
2432
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
284 _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
|
285 } |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
286 _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
|
287 |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
288 _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
|
289 _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
|
290 _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
|
291 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
|
292 |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
293 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
|
294 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
|
295 } |
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2361
diff
changeset
|
296 |
2152 | 297 void HeapRegionLinkedList::add_as_tail(HeapRegionLinkedList* from_list) { |
2361 | 298 hrs_assert_mt_safety_ok(this); |
299 hrs_assert_mt_safety_ok(from_list); | |
2152 | 300 |
301 verify_optional(); | |
302 from_list->verify_optional(); | |
303 | |
304 if (from_list->is_empty()) return; | |
305 | |
306 #ifdef ASSERT | |
307 HeapRegionLinkedListIterator iter(from_list); | |
308 while (iter.more_available()) { | |
309 HeapRegion* hr = iter.get_next(); | |
310 // In set_containing_set() we check that we either set the value | |
311 // from NULL to non-NULL or vice versa to catch bugs. So, we have | |
312 // to NULL it first before setting it to the value. | |
313 hr->set_containing_set(NULL); | |
314 hr->set_containing_set(this); | |
315 } | |
316 #endif // ASSERT | |
317 | |
318 if (_tail != NULL) { | |
2361 | 319 assert(length() > 0 && _head != NULL, hrs_ext_msg(this, "invariant")); |
2152 | 320 _tail->set_next(from_list->_head); |
321 } else { | |
2361 | 322 assert(length() == 0 && _head == NULL, hrs_ext_msg(this, "invariant")); |
2152 | 323 _head = from_list->_head; |
324 } | |
325 _tail = from_list->_tail; | |
326 | |
327 _length += from_list->length(); | |
328 _region_num += from_list->region_num(); | |
329 _total_used_bytes += from_list->total_used_bytes(); | |
330 from_list->clear(); | |
331 | |
332 verify_optional(); | |
333 from_list->verify_optional(); | |
334 } | |
335 | |
336 void HeapRegionLinkedList::remove_all() { | |
2361 | 337 hrs_assert_mt_safety_ok(this); |
2152 | 338 verify_optional(); |
339 | |
340 HeapRegion* curr = _head; | |
341 while (curr != NULL) { | |
2361 | 342 hrs_assert_region_ok(this, curr, this); |
2152 | 343 |
344 HeapRegion* next = curr->next(); | |
345 curr->set_next(NULL); | |
346 curr->set_containing_set(NULL); | |
347 curr = next; | |
348 } | |
349 clear(); | |
350 | |
351 verify_optional(); | |
352 } | |
353 | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
354 void HeapRegionLinkedList::remove_all_pending(uint target_count) { |
2361 | 355 hrs_assert_mt_safety_ok(this); |
356 assert(target_count > 1, hrs_ext_msg(this, "pre-condition")); | |
357 assert(!is_empty(), hrs_ext_msg(this, "pre-condition")); | |
2152 | 358 |
359 verify_optional(); | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
360 DEBUG_ONLY(uint old_length = length();) |
2152 | 361 |
362 HeapRegion* curr = _head; | |
363 HeapRegion* prev = NULL; | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
364 uint count = 0; |
2152 | 365 while (curr != NULL) { |
2361 | 366 hrs_assert_region_ok(this, curr, this); |
2152 | 367 HeapRegion* next = curr->next(); |
368 | |
369 if (curr->pending_removal()) { | |
370 assert(count < target_count, | |
2361 | 371 hrs_err_msg("[%s] should not come across more regions " |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
372 "pending for removal than target_count: %u", |
2152 | 373 name(), target_count)); |
374 | |
375 if (prev == NULL) { | |
2361 | 376 assert(_head == curr, hrs_ext_msg(this, "invariant")); |
2152 | 377 _head = next; |
378 } else { | |
2361 | 379 assert(_head != curr, hrs_ext_msg(this, "invariant")); |
2152 | 380 prev->set_next(next); |
381 } | |
382 if (next == NULL) { | |
2361 | 383 assert(_tail == curr, hrs_ext_msg(this, "invariant")); |
2152 | 384 _tail = prev; |
385 } else { | |
2361 | 386 assert(_tail != curr, hrs_ext_msg(this, "invariant")); |
2152 | 387 } |
388 | |
389 curr->set_next(NULL); | |
390 remove_internal(curr); | |
391 curr->set_pending_removal(false); | |
392 | |
393 count += 1; | |
394 | |
395 // If we have come across the target number of regions we can | |
396 // just bail out. However, for debugging purposes, we can just | |
397 // carry on iterating to make sure there are not more regions | |
398 // tagged with pending removal. | |
399 DEBUG_ONLY(if (count == target_count) break;) | |
400 } else { | |
401 prev = curr; | |
402 } | |
403 curr = next; | |
404 } | |
405 | |
406 assert(count == target_count, | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
407 hrs_err_msg("[%s] count: %u should be == target_count: %u", |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
408 name(), count, target_count)); |
2152 | 409 assert(length() + target_count == old_length, |
2361 | 410 hrs_err_msg("[%s] new length should be consistent " |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
411 "new length: %u old length: %u target_count: %u", |
2152 | 412 name(), length(), old_length, target_count)); |
413 | |
414 verify_optional(); | |
415 } | |
416 | |
417 void HeapRegionLinkedList::verify() { | |
418 // See comment in HeapRegionSetBase::verify() about MT safety and | |
419 // verification. | |
2361 | 420 hrs_assert_mt_safety_ok(this); |
2152 | 421 |
422 // This will also do the basic verification too. | |
423 verify_start(); | |
424 | |
425 HeapRegion* curr = _head; | |
426 HeapRegion* prev1 = NULL; | |
427 HeapRegion* prev0 = NULL; | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
428 uint count = 0; |
2152 | 429 while (curr != NULL) { |
430 verify_next_region(curr); | |
431 | |
432 count += 1; | |
433 guarantee(count < _unrealistically_long_length, | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
434 hrs_err_msg("[%s] the calculated length: %u " |
2152 | 435 "seems very long, is there maybe a cycle? " |
436 "curr: "PTR_FORMAT" prev0: "PTR_FORMAT" " | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
4072
diff
changeset
|
437 "prev1: "PTR_FORMAT" length: %u", |
2152 | 438 name(), count, curr, prev0, prev1, length())); |
439 | |
440 prev1 = prev0; | |
441 prev0 = curr; | |
442 curr = curr->next(); | |
443 } | |
444 | |
2361 | 445 guarantee(_tail == prev0, hrs_ext_msg(this, "post-condition")); |
2152 | 446 |
447 verify_end(); | |
448 } | |
449 | |
450 void HeapRegionLinkedList::clear() { | |
451 HeapRegionSetBase::clear(); | |
452 _head = NULL; | |
453 _tail = NULL; | |
454 } | |
455 | |
456 void HeapRegionLinkedList::print_on(outputStream* out, bool print_contents) { | |
457 HeapRegionSetBase::print_on(out, print_contents); | |
458 out->print_cr(" Linking"); | |
459 out->print_cr(" head : "PTR_FORMAT, _head); | |
460 out->print_cr(" tail : "PTR_FORMAT, _tail); | |
461 | |
462 if (print_contents) { | |
463 out->print_cr(" Contents"); | |
464 HeapRegionLinkedListIterator iter(this); | |
465 while (iter.more_available()) { | |
466 HeapRegion* hr = iter.get_next(); | |
467 hr->print_on(out); | |
468 } | |
469 } | |
470 } |