src/share/vm/gc_implementation/g1/heapRegionSet.cpp

Thu, 28 Mar 2013 10:27:28 +0100

author
mgerdin
date
Thu, 28 Mar 2013 10:27:28 +0100
changeset 4853
2e093b564241
parent 3957
a2f7274eb6ef
child 6385
58fc1b1523dc
permissions
-rw-r--r--

7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
Summary: Keep a counter of how many times we were stalled by the GC locker, add a diagnostic flag which sets the limit.
Reviewed-by: brutisso, ehelin, johnc

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

mercurial