comparison src/share/vm/gc_implementation/g1/heapRegionSet.cpp @ 17736:58fc1b1523dc

8034079: G1: Refactor the HeapRegionSet hierarchy Reviewed-by: tschatzl, pliden
author brutisso
date Fri, 14 Mar 2014 10:15:46 +0100
parents a2f7274eb6ef
children 0d2ce7411240
comparison
equal deleted inserted replaced
17735:8f28240318a2 17736:58fc1b1523dc
21 * questions. 21 * questions.
22 * 22 *
23 */ 23 */
24 24
25 #include "precompiled.hpp" 25 #include "precompiled.hpp"
26 #include "gc_implementation/g1/heapRegionRemSet.hpp"
26 #include "gc_implementation/g1/heapRegionSet.inline.hpp" 27 #include "gc_implementation/g1/heapRegionSet.inline.hpp"
27 28
28 uint HeapRegionSetBase::_unrealistically_long_length = 0; 29 uint FreeRegionList::_unrealistically_long_length = 0;
29 HRSPhase HeapRegionSetBase::_phase = HRSPhaseNone;
30
31 //////////////////// HeapRegionSetBase ////////////////////
32
33 void HeapRegionSetBase::set_unrealistically_long_length(uint len) {
34 guarantee(_unrealistically_long_length == 0, "should only be set once");
35 _unrealistically_long_length = len;
36 }
37 30
38 void HeapRegionSetBase::fill_in_ext_msg(hrs_ext_msg* msg, const char* message) { 31 void HeapRegionSetBase::fill_in_ext_msg(hrs_ext_msg* msg, const char* message) {
39 msg->append("[%s] %s ln: %u rn: %u cy: "SIZE_FORMAT" ud: "SIZE_FORMAT, 32 msg->append("[%s] %s ln: %u cy: "SIZE_FORMAT,
40 name(), message, length(), region_num(), 33 name(), message, length(), total_capacity_bytes());
41 total_capacity_bytes(), total_used_bytes());
42 fill_in_ext_msg_extra(msg); 34 fill_in_ext_msg_extra(msg);
43 } 35 }
44 36
45 bool HeapRegionSetBase::verify_region(HeapRegion* hr, 37 #ifndef PRODUCT
46 HeapRegionSetBase* expected_containing_set) { 38 void HeapRegionSetBase::verify_region(HeapRegion* hr) {
47 const char* error_message = NULL; 39 assert(hr->containing_set() == this, err_msg("Inconsistent containing set for %u", hr->hrs_index()));
48 40 assert(!hr->is_young(), err_msg("Adding young region %u", hr->hrs_index())); // currently we don't use these sets for young regions
49 if (!regions_humongous()) { 41 assert(hr->isHumongous() == regions_humongous(), err_msg("Wrong humongous state for region %u and set %s", hr->hrs_index(), name()));
50 if (hr->isHumongous()) { 42 assert(hr->is_empty() == regions_empty(), err_msg("Wrong empty state for region %u and set %s", hr->hrs_index(), name()));
51 error_message = "the region should not be humongous"; 43 assert(hr->rem_set()->verify_ready_for_par_iteration(), err_msg("Wrong iteration state %u", hr->hrs_index()));
52 } 44 }
53 } else { 45 #endif
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 46
98 void HeapRegionSetBase::verify() { 47 void HeapRegionSetBase::verify() {
99 // It's important that we also observe the MT safety protocol even 48 // It's important that we also observe the MT safety protocol even
100 // for the verification calls. If we do verification without the 49 // for the verification calls. If we do verification without the
101 // appropriate locks and the set changes underneath our feet 50 // appropriate locks and the set changes underneath our feet
102 // verification might fail and send us on a wild goose chase. 51 // verification might fail and send us on a wild goose chase.
103 hrs_assert_mt_safety_ok(this); 52 check_mt_safety();
104 53
105 guarantee(( is_empty() && length() == 0 && region_num() == 0 && 54 guarantee(( is_empty() && length() == 0 && total_capacity_bytes() == 0) ||
106 total_used_bytes() == 0 && total_capacity_bytes() == 0) || 55 (!is_empty() && length() >= 0 && total_capacity_bytes() >= 0),
107 (!is_empty() && length() >= 0 && region_num() >= 0 &&
108 total_used_bytes() >= 0 && total_capacity_bytes() >= 0),
109 hrs_ext_msg(this, "invariant"));
110
111 guarantee((!regions_humongous() && region_num() == length()) ||
112 ( regions_humongous() && region_num() >= length()),
113 hrs_ext_msg(this, "invariant"));
114
115 guarantee(!regions_empty() || total_used_bytes() == 0,
116 hrs_ext_msg(this, "invariant"));
117
118 guarantee(total_used_bytes() <= total_capacity_bytes(),
119 hrs_ext_msg(this, "invariant")); 56 hrs_ext_msg(this, "invariant"));
120 } 57 }
121 58
122 void HeapRegionSetBase::verify_start() { 59 void HeapRegionSetBase::verify_start() {
123 // See comment in verify() about MT safety and verification. 60 // See comment in verify() about MT safety and verification.
124 hrs_assert_mt_safety_ok(this); 61 check_mt_safety();
125 assert(!_verify_in_progress, 62 assert(!_verify_in_progress,
126 hrs_ext_msg(this, "verification should not be in progress")); 63 hrs_ext_msg(this, "verification should not be in progress"));
127 64
128 // Do the basic verification first before we do the checks over the regions. 65 // Do the basic verification first before we do the checks over the regions.
129 HeapRegionSetBase::verify(); 66 HeapRegionSetBase::verify();
130 67
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; 68 _verify_in_progress = true;
136 } 69 }
137 70
138 void HeapRegionSetBase::verify_next_region(HeapRegion* hr) { 71 void HeapRegionSetBase::verify_end() {
139 // See comment in verify() about MT safety and verification. 72 // See comment in verify() about MT safety and verification.
140 hrs_assert_mt_safety_ok(this); 73 check_mt_safety();
141 assert(_verify_in_progress, 74 assert(_verify_in_progress,
142 hrs_ext_msg(this, "verification should be in progress")); 75 hrs_ext_msg(this, "verification should be in progress"));
143 76
144 guarantee(verify_region(hr, this), hrs_ext_msg(this, "region verification"));
145
146 _calc_length += 1;
147 _calc_region_num += hr->region_num();
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.
154 hrs_assert_mt_safety_ok(this);
155 assert(_verify_in_progress,
156 hrs_ext_msg(this, "verification should be in progress"));
157
158 guarantee(length() == _calc_length,
159 hrs_err_msg("[%s] length: %u should be == calc length: %u",
160 name(), length(), _calc_length));
161
162 guarantee(region_num() == _calc_region_num,
163 hrs_err_msg("[%s] region num: %u should be == calc region num: %u",
164 name(), region_num(), _calc_region_num));
165
166 guarantee(total_capacity_bytes() == _calc_total_capacity_bytes,
167 hrs_err_msg("[%s] capacity bytes: "SIZE_FORMAT" should be == "
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,
173 hrs_err_msg("[%s] used bytes: "SIZE_FORMAT" should be == "
174 "calc used bytes: "SIZE_FORMAT,
175 name(), total_used_bytes(), _calc_total_used_bytes));
176
177 _verify_in_progress = false; 77 _verify_in_progress = false;
178 }
179
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 } 78 }
190 79
191 void HeapRegionSetBase::print_on(outputStream* out, bool print_contents) { 80 void HeapRegionSetBase::print_on(outputStream* out, bool print_contents) {
192 out->cr(); 81 out->cr();
193 out->print_cr("Set: %s ("PTR_FORMAT")", name(), this); 82 out->print_cr("Set: %s ("PTR_FORMAT")", name(), this);
194 out->print_cr(" Region Assumptions"); 83 out->print_cr(" Region Assumptions");
195 out->print_cr(" humongous : %s", BOOL_TO_STR(regions_humongous())); 84 out->print_cr(" humongous : %s", BOOL_TO_STR(regions_humongous()));
196 out->print_cr(" empty : %s", BOOL_TO_STR(regions_empty())); 85 out->print_cr(" empty : %s", BOOL_TO_STR(regions_empty()));
197 out->print_cr(" Attributes"); 86 out->print_cr(" Attributes");
198 out->print_cr(" length : %14u", length()); 87 out->print_cr(" length : %14u", length());
199 out->print_cr(" region num : %14u", region_num());
200 out->print_cr(" total capacity : "SIZE_FORMAT_W(14)" bytes", 88 out->print_cr(" total capacity : "SIZE_FORMAT_W(14)" bytes",
201 total_capacity_bytes()); 89 total_capacity_bytes());
202 out->print_cr(" total used : "SIZE_FORMAT_W(14)" bytes", 90 }
203 total_used_bytes()); 91
204 } 92 HeapRegionSetBase::HeapRegionSetBase(const char* name, bool humongous, bool empty, HRSMtSafeChecker* mt_safety_checker)
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), 93 : _name(name), _verify_in_progress(false),
214 _calc_length(0), _calc_region_num(0), 94 _is_humongous(humongous), _is_empty(empty), _mt_safety_checker(mt_safety_checker),
215 _calc_total_capacity_bytes(0), _calc_total_used_bytes(0) { } 95 _count()
216 96 { }
217 //////////////////// HeapRegionSet //////////////////// 97
218 98 void FreeRegionList::set_unrealistically_long_length(uint len) {
219 void HeapRegionSet::update_from_proxy(HeapRegionSet* proxy_set) { 99 guarantee(_unrealistically_long_length == 0, "should only be set once");
220 hrs_assert_mt_safety_ok(this); 100 _unrealistically_long_length = len;
221 hrs_assert_mt_safety_ok(proxy_set); 101 }
222 hrs_assert_sets_match(this, proxy_set); 102
223 103 void FreeRegionList::fill_in_ext_msg_extra(hrs_ext_msg* msg) {
224 verify_optional();
225 proxy_set->verify_optional();
226
227 if (proxy_set->is_empty()) return;
228
229 assert(proxy_set->length() <= _length,
230 hrs_err_msg("[%s] proxy set length: %u should be <= length: %u",
231 name(), proxy_set->length(), _length));
232 _length -= proxy_set->length();
233
234 assert(proxy_set->region_num() <= _region_num,
235 hrs_err_msg("[%s] proxy set region num: %u should be <= region num: %u",
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,
240 hrs_err_msg("[%s] proxy set used bytes: "SIZE_FORMAT" "
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
254 void HeapRegionLinkedList::fill_in_ext_msg_extra(hrs_ext_msg* msg) {
255 msg->append(" hd: "PTR_FORMAT" tl: "PTR_FORMAT, head(), tail()); 104 msg->append(" hd: "PTR_FORMAT" tl: "PTR_FORMAT, head(), tail());
256 } 105 }
257 106
258 void HeapRegionLinkedList::add_as_head(HeapRegionLinkedList* from_list) { 107 void FreeRegionList::add_as_head_or_tail(FreeRegionList* from_list, bool as_head) {
259 hrs_assert_mt_safety_ok(this); 108 check_mt_safety();
260 hrs_assert_mt_safety_ok(from_list); 109 from_list->check_mt_safety();
261 110
262 verify_optional(); 111 verify_optional();
263 from_list->verify_optional(); 112 from_list->verify_optional();
264 113
265 if (from_list->is_empty()) return; 114 if (from_list->is_empty()) {
115 return;
116 }
266 117
267 #ifdef ASSERT 118 #ifdef ASSERT
268 HeapRegionLinkedListIterator iter(from_list); 119 FreeRegionListIterator iter(from_list);
269 while (iter.more_available()) { 120 while (iter.more_available()) {
270 HeapRegion* hr = iter.get_next(); 121 HeapRegion* hr = iter.get_next();
271 // In set_containing_set() we check that we either set the value 122 // In set_containing_set() we check that we either set the value
272 // from NULL to non-NULL or vice versa to catch bugs. So, we have 123 // from NULL to non-NULL or vice versa to catch bugs. So, we have
273 // to NULL it first before setting it to the value. 124 // to NULL it first before setting it to the value.
274 hr->set_containing_set(NULL); 125 hr->set_containing_set(NULL);
275 hr->set_containing_set(this); 126 hr->set_containing_set(this);
276 } 127 }
277 #endif // ASSERT 128 #endif // ASSERT
278 129
279 if (_head != NULL) { 130 if (_head == NULL) {
280 assert(length() > 0 && _tail != NULL, hrs_ext_msg(this, "invariant")); 131 assert(length() == 0 && _tail == NULL, hrs_ext_msg(this, "invariant"));
281 from_list->_tail->set_next(_head); 132 _head = from_list->_head;
133 _tail = from_list->_tail;
282 } else { 134 } else {
283 assert(length() == 0 && _tail == NULL, hrs_ext_msg(this, "invariant")); 135 assert(length() > 0 && _tail != NULL, hrs_ext_msg(this, "invariant"));
284 _tail = from_list->_tail; 136 if (as_head) {
285 } 137 from_list->_tail->set_next(_head);
286 _head = from_list->_head; 138 _head = from_list->_head;
287 139 } else {
288 _length += from_list->length(); 140 _tail->set_next(from_list->_head);
289 _region_num += from_list->region_num(); 141 _tail = from_list->_tail;
290 _total_used_bytes += from_list->total_used_bytes(); 142 }
143 }
144
145 _count.increment(from_list->length(), from_list->total_capacity_bytes());
291 from_list->clear(); 146 from_list->clear();
292 147
293 verify_optional(); 148 verify_optional();
294 from_list->verify_optional(); 149 from_list->verify_optional();
295 } 150 }
296 151
297 void HeapRegionLinkedList::add_as_tail(HeapRegionLinkedList* from_list) { 152 void FreeRegionList::add_as_head(FreeRegionList* from_list) {
298 hrs_assert_mt_safety_ok(this); 153 add_as_head_or_tail(from_list, true /* as_head */);
299 hrs_assert_mt_safety_ok(from_list); 154 }
300 155
301 verify_optional(); 156 void FreeRegionList::add_as_tail(FreeRegionList* from_list) {
302 from_list->verify_optional(); 157 add_as_head_or_tail(from_list, false /* as_head */);
303 158 }
304 if (from_list->is_empty()) return; 159
305 160 void FreeRegionList::remove_all() {
306 #ifdef ASSERT 161 check_mt_safety();
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) {
319 assert(length() > 0 && _head != NULL, hrs_ext_msg(this, "invariant"));
320 _tail->set_next(from_list->_head);
321 } else {
322 assert(length() == 0 && _head == NULL, hrs_ext_msg(this, "invariant"));
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() {
337 hrs_assert_mt_safety_ok(this);
338 verify_optional(); 162 verify_optional();
339 163
340 HeapRegion* curr = _head; 164 HeapRegion* curr = _head;
341 while (curr != NULL) { 165 while (curr != NULL) {
342 hrs_assert_region_ok(this, curr, this); 166 verify_region(curr);
343 167
344 HeapRegion* next = curr->next(); 168 HeapRegion* next = curr->next();
345 curr->set_next(NULL); 169 curr->set_next(NULL);
346 curr->set_containing_set(NULL); 170 curr->set_containing_set(NULL);
347 curr = next; 171 curr = next;
349 clear(); 173 clear();
350 174
351 verify_optional(); 175 verify_optional();
352 } 176 }
353 177
354 void HeapRegionLinkedList::remove_all_pending(uint target_count) { 178 void FreeRegionList::remove_all_pending(uint target_count) {
355 hrs_assert_mt_safety_ok(this); 179 check_mt_safety();
356 assert(target_count > 1, hrs_ext_msg(this, "pre-condition")); 180 assert(target_count > 1, hrs_ext_msg(this, "pre-condition"));
357 assert(!is_empty(), hrs_ext_msg(this, "pre-condition")); 181 assert(!is_empty(), hrs_ext_msg(this, "pre-condition"));
358 182
359 verify_optional(); 183 verify_optional();
360 DEBUG_ONLY(uint old_length = length();) 184 DEBUG_ONLY(uint old_length = length();)
361 185
362 HeapRegion* curr = _head; 186 HeapRegion* curr = _head;
363 HeapRegion* prev = NULL; 187 HeapRegion* prev = NULL;
364 uint count = 0; 188 uint count = 0;
365 while (curr != NULL) { 189 while (curr != NULL) {
366 hrs_assert_region_ok(this, curr, this); 190 verify_region(curr);
367 HeapRegion* next = curr->next(); 191 HeapRegion* next = curr->next();
368 192
369 if (curr->pending_removal()) { 193 if (curr->pending_removal()) {
370 assert(count < target_count, 194 assert(count < target_count,
371 hrs_err_msg("[%s] should not come across more regions " 195 hrs_err_msg("[%s] should not come across more regions "
385 } else { 209 } else {
386 assert(_tail != curr, hrs_ext_msg(this, "invariant")); 210 assert(_tail != curr, hrs_ext_msg(this, "invariant"));
387 } 211 }
388 212
389 curr->set_next(NULL); 213 curr->set_next(NULL);
390 remove_internal(curr); 214 remove(curr);
391 curr->set_pending_removal(false); 215 curr->set_pending_removal(false);
392 216
393 count += 1; 217 count += 1;
394 218
395 // If we have come across the target number of regions we can 219 // If we have come across the target number of regions we can
412 name(), length(), old_length, target_count)); 236 name(), length(), old_length, target_count));
413 237
414 verify_optional(); 238 verify_optional();
415 } 239 }
416 240
417 void HeapRegionLinkedList::verify() { 241 void FreeRegionList::verify() {
418 // See comment in HeapRegionSetBase::verify() about MT safety and 242 // See comment in HeapRegionSetBase::verify() about MT safety and
419 // verification. 243 // verification.
420 hrs_assert_mt_safety_ok(this); 244 check_mt_safety();
421 245
422 // This will also do the basic verification too. 246 // This will also do the basic verification too.
423 verify_start(); 247 verify_start();
424 248
425 HeapRegion* curr = _head; 249 verify_list();
426 HeapRegion* prev1 = NULL;
427 HeapRegion* prev0 = NULL;
428 uint count = 0;
429 while (curr != NULL) {
430 verify_next_region(curr);
431
432 count += 1;
433 guarantee(count < _unrealistically_long_length,
434 hrs_err_msg("[%s] the calculated length: %u "
435 "seems very long, is there maybe a cycle? "
436 "curr: "PTR_FORMAT" prev0: "PTR_FORMAT" "
437 "prev1: "PTR_FORMAT" length: %u",
438 name(), count, curr, prev0, prev1, length()));
439
440 prev1 = prev0;
441 prev0 = curr;
442 curr = curr->next();
443 }
444
445 guarantee(_tail == prev0, hrs_ext_msg(this, "post-condition"));
446 250
447 verify_end(); 251 verify_end();
448 } 252 }
449 253
450 void HeapRegionLinkedList::clear() { 254 void FreeRegionList::clear() {
451 HeapRegionSetBase::clear(); 255 _count = HeapRegionSetCount();
452 _head = NULL; 256 _head = NULL;
453 _tail = NULL; 257 _tail = NULL;
454 } 258 }
455 259
456 void HeapRegionLinkedList::print_on(outputStream* out, bool print_contents) { 260 void FreeRegionList::print_on(outputStream* out, bool print_contents) {
457 HeapRegionSetBase::print_on(out, print_contents); 261 HeapRegionSetBase::print_on(out, print_contents);
458 out->print_cr(" Linking"); 262 out->print_cr(" Linking");
459 out->print_cr(" head : "PTR_FORMAT, _head); 263 out->print_cr(" head : "PTR_FORMAT, _head);
460 out->print_cr(" tail : "PTR_FORMAT, _tail); 264 out->print_cr(" tail : "PTR_FORMAT, _tail);
461 265
462 if (print_contents) { 266 if (print_contents) {
463 out->print_cr(" Contents"); 267 out->print_cr(" Contents");
464 HeapRegionLinkedListIterator iter(this); 268 FreeRegionListIterator iter(this);
465 while (iter.more_available()) { 269 while (iter.more_available()) {
466 HeapRegion* hr = iter.get_next(); 270 HeapRegion* hr = iter.get_next();
467 hr->print_on(out); 271 hr->print_on(out);
468 } 272 }
469 } 273 }