Thu, 22 Sep 2011 10:57:37 -0700
6484982: G1: process references during evacuation pauses
Summary: G1 now uses two reference processors - one is used by concurrent marking and the other is used by STW GCs (both full and incremental evacuation pauses). In an evacuation pause, the reference processor is embedded into the closures used to scan objects. Doing so causes causes reference objects to be 'discovered' by the reference processor. At the end of the evacuation pause, these discovered reference objects are processed - preserving (and copying) referent objects (and their reachable graphs) as appropriate.
Reviewed-by: ysr, jwilhelm, brutisso, stefank, tonyp
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 */
25 #include "precompiled.hpp"
26 #include "gc_implementation/g1/heapRegionSet.inline.hpp"
28 size_t HeapRegionSetBase::_unrealistically_long_length = 0;
30 //////////////////// HeapRegionSetBase ////////////////////
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 }
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 }
45 void HeapRegionSetBase::fill_in_ext_msg(hrs_ext_msg* msg, const char* message) {
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 }
54 bool HeapRegionSetBase::verify_region(HeapRegion* hr,
55 HeapRegionSetBase* expected_containing_set) {
56 const char* error_message = NULL;
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 }
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 }
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
85 const char* extra_error_message = verify_region_extra(hr);
86 if (extra_error_message != NULL) {
87 error_message = extra_error_message;
88 }
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 }
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.
112 hrs_assert_mt_safety_ok(this);
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),
118 hrs_ext_msg(this, "invariant"));
120 guarantee((!regions_humongous() && region_num() == length()) ||
121 ( regions_humongous() && region_num() >= length()),
122 hrs_ext_msg(this, "invariant"));
124 guarantee(!regions_empty() || total_used_bytes() == 0,
125 hrs_ext_msg(this, "invariant"));
127 guarantee(total_used_bytes() <= total_capacity_bytes(),
128 hrs_ext_msg(this, "invariant"));
129 }
131 void HeapRegionSetBase::verify_start() {
132 // See comment in verify() about MT safety and verification.
133 hrs_assert_mt_safety_ok(this);
134 assert(!_verify_in_progress,
135 hrs_ext_msg(this, "verification should not be in progress"));
137 // Do the basic verification first before we do the checks over the regions.
138 HeapRegionSetBase::verify();
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 }
147 void HeapRegionSetBase::verify_next_region(HeapRegion* hr) {
148 // See comment in verify() about MT safety and verification.
149 hrs_assert_mt_safety_ok(this);
150 assert(_verify_in_progress,
151 hrs_ext_msg(this, "verification should be in progress"));
153 guarantee(verify_region(hr, this), hrs_ext_msg(this, "region verification"));
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 }
165 void HeapRegionSetBase::verify_end() {
166 // See comment in verify() about MT safety and verification.
167 hrs_assert_mt_safety_ok(this);
168 assert(_verify_in_progress,
169 hrs_ext_msg(this, "verification should be in progress"));
171 guarantee(length() == _calc_length,
172 hrs_err_msg("[%s] length: "SIZE_FORMAT" should be == "
173 "calc length: "SIZE_FORMAT,
174 name(), length(), _calc_length));
176 guarantee(region_num() == _calc_region_num,
177 hrs_err_msg("[%s] region num: "SIZE_FORMAT" should be == "
178 "calc region num: "SIZE_FORMAT,
179 name(), region_num(), _calc_region_num));
181 guarantee(total_capacity_bytes() == _calc_total_capacity_bytes,
182 hrs_err_msg("[%s] capacity bytes: "SIZE_FORMAT" should be == "
183 "calc capacity bytes: "SIZE_FORMAT,
184 name(),
185 total_capacity_bytes(), _calc_total_capacity_bytes));
187 guarantee(total_used_bytes() == _calc_total_used_bytes,
188 hrs_err_msg("[%s] used bytes: "SIZE_FORMAT" should be == "
189 "calc used bytes: "SIZE_FORMAT,
190 name(), total_used_bytes(), _calc_total_used_bytes));
192 _verify_in_progress = false;
193 }
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 }
210 void HeapRegionSetBase::clear() {
211 _length = 0;
212 _region_num = 0;
213 _total_used_bytes = 0;
214 }
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) { }
221 //////////////////// HeapRegionSet ////////////////////
223 void HeapRegionSet::update_from_proxy(HeapRegionSet* proxy_set) {
224 hrs_assert_mt_safety_ok(this);
225 hrs_assert_mt_safety_ok(proxy_set);
226 hrs_assert_sets_match(this, proxy_set);
228 verify_optional();
229 proxy_set->verify_optional();
231 if (proxy_set->is_empty()) return;
233 assert(proxy_set->length() <= _length,
234 hrs_err_msg("[%s] proxy set length: "SIZE_FORMAT" "
235 "should be <= length: "SIZE_FORMAT,
236 name(), proxy_set->length(), _length));
237 _length -= proxy_set->length();
239 assert(proxy_set->region_num() <= _region_num,
240 hrs_err_msg("[%s] proxy set region num: "SIZE_FORMAT" "
241 "should be <= region num: "SIZE_FORMAT,
242 name(), proxy_set->region_num(), _region_num));
243 _region_num -= proxy_set->region_num();
245 assert(proxy_set->total_used_bytes() <= _total_used_bytes,
246 hrs_err_msg("[%s] proxy set used bytes: "SIZE_FORMAT" "
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();
252 proxy_set->clear();
254 verify_optional();
255 proxy_set->verify_optional();
256 }
258 //////////////////// HeapRegionLinkedList ////////////////////
260 void HeapRegionLinkedList::fill_in_ext_msg_extra(hrs_ext_msg* msg) {
261 msg->append(" hd: "PTR_FORMAT" tl: "PTR_FORMAT, head(), tail());
262 }
264 void HeapRegionLinkedList::add_as_head(HeapRegionLinkedList* from_list) {
265 hrs_assert_mt_safety_ok(this);
266 hrs_assert_mt_safety_ok(from_list);
268 verify_optional();
269 from_list->verify_optional();
271 if (from_list->is_empty()) return;
273 #ifdef ASSERT
274 HeapRegionLinkedListIterator iter(from_list);
275 while (iter.more_available()) {
276 HeapRegion* hr = iter.get_next();
277 // In set_containing_set() we check that we either set the value
278 // from NULL to non-NULL or vice versa to catch bugs. So, we have
279 // to NULL it first before setting it to the value.
280 hr->set_containing_set(NULL);
281 hr->set_containing_set(this);
282 }
283 #endif // ASSERT
285 if (_head != NULL) {
286 assert(length() > 0 && _tail != NULL, hrs_ext_msg(this, "invariant"));
287 from_list->_tail->set_next(_head);
288 } else {
289 assert(length() == 0 && _head == NULL, hrs_ext_msg(this, "invariant"));
290 _tail = from_list->_tail;
291 }
292 _head = from_list->_head;
294 _length += from_list->length();
295 _region_num += from_list->region_num();
296 _total_used_bytes += from_list->total_used_bytes();
297 from_list->clear();
299 verify_optional();
300 from_list->verify_optional();
301 }
303 void HeapRegionLinkedList::add_as_tail(HeapRegionLinkedList* from_list) {
304 hrs_assert_mt_safety_ok(this);
305 hrs_assert_mt_safety_ok(from_list);
307 verify_optional();
308 from_list->verify_optional();
310 if (from_list->is_empty()) return;
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
324 if (_tail != NULL) {
325 assert(length() > 0 && _head != NULL, hrs_ext_msg(this, "invariant"));
326 _tail->set_next(from_list->_head);
327 } else {
328 assert(length() == 0 && _head == NULL, hrs_ext_msg(this, "invariant"));
329 _head = from_list->_head;
330 }
331 _tail = from_list->_tail;
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();
338 verify_optional();
339 from_list->verify_optional();
340 }
342 void HeapRegionLinkedList::remove_all() {
343 hrs_assert_mt_safety_ok(this);
344 verify_optional();
346 HeapRegion* curr = _head;
347 while (curr != NULL) {
348 hrs_assert_region_ok(this, curr, this);
350 HeapRegion* next = curr->next();
351 curr->set_next(NULL);
352 curr->set_containing_set(NULL);
353 curr = next;
354 }
355 clear();
357 verify_optional();
358 }
360 void HeapRegionLinkedList::remove_all_pending(size_t target_count) {
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"));
365 verify_optional();
366 DEBUG_ONLY(size_t old_length = length();)
368 HeapRegion* curr = _head;
369 HeapRegion* prev = NULL;
370 size_t count = 0;
371 while (curr != NULL) {
372 hrs_assert_region_ok(this, curr, this);
373 HeapRegion* next = curr->next();
375 if (curr->pending_removal()) {
376 assert(count < target_count,
377 hrs_err_msg("[%s] should not come across more regions "
378 "pending for removal than target_count: "SIZE_FORMAT,
379 name(), target_count));
381 if (prev == NULL) {
382 assert(_head == curr, hrs_ext_msg(this, "invariant"));
383 _head = next;
384 } else {
385 assert(_head != curr, hrs_ext_msg(this, "invariant"));
386 prev->set_next(next);
387 }
388 if (next == NULL) {
389 assert(_tail == curr, hrs_ext_msg(this, "invariant"));
390 _tail = prev;
391 } else {
392 assert(_tail != curr, hrs_ext_msg(this, "invariant"));
393 }
395 curr->set_next(NULL);
396 remove_internal(curr);
397 curr->set_pending_removal(false);
399 count += 1;
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 }
412 assert(count == target_count,
413 hrs_err_msg("[%s] count: "SIZE_FORMAT" should be == "
414 "target_count: "SIZE_FORMAT, name(), count, target_count));
415 assert(length() + target_count == old_length,
416 hrs_err_msg("[%s] new length should be consistent "
417 "new length: "SIZE_FORMAT" old length: "SIZE_FORMAT" "
418 "target_count: "SIZE_FORMAT,
419 name(), length(), old_length, target_count));
421 verify_optional();
422 }
424 void HeapRegionLinkedList::verify() {
425 // See comment in HeapRegionSetBase::verify() about MT safety and
426 // verification.
427 hrs_assert_mt_safety_ok(this);
429 // This will also do the basic verification too.
430 verify_start();
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);
439 count += 1;
440 guarantee(count < _unrealistically_long_length,
441 hrs_err_msg("[%s] the calculated length: "SIZE_FORMAT" "
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()));
447 prev1 = prev0;
448 prev0 = curr;
449 curr = curr->next();
450 }
452 guarantee(_tail == prev0, hrs_ext_msg(this, "post-condition"));
454 verify_end();
455 }
457 void HeapRegionLinkedList::clear() {
458 HeapRegionSetBase::clear();
459 _head = NULL;
460 _tail = NULL;
461 }
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);
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 }