1 /* 2 * Copyright (c) 2011, 2012, 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 uint HeapRegionSetBase::_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 38 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, 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. 103 hrs_assert_mt_safety_ok(this); 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), 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")); 120 } 121 122 void HeapRegionSetBase::verify_start() { 123 // See comment in verify() about MT safety and verification. 124 hrs_assert_mt_safety_ok(this); 125 assert(!_verify_in_progress, 126 hrs_ext_msg(this, "verification should not be in progress")); 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. 140 hrs_assert_mt_safety_ok(this); 141 assert(_verify_in_progress, 142 hrs_ext_msg(this, "verification should be in progress")); 143 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; 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 } 190 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"); 198 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", 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) { 220 hrs_assert_mt_safety_ok(this); 221 hrs_assert_mt_safety_ok(proxy_set); 222 hrs_assert_sets_match(this, proxy_set); 223 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()); 256 } 257 258 void HeapRegionLinkedList::add_as_head(HeapRegionLinkedList* from_list) { 259 hrs_assert_mt_safety_ok(this); 260 hrs_assert_mt_safety_ok(from_list); 261 262 verify_optional(); 263 from_list->verify_optional(); 264 265 if (from_list->is_empty()) return; 266 267 #ifdef ASSERT 268 HeapRegionLinkedListIterator iter(from_list); 269 while (iter.more_available()) { 270 HeapRegion* hr = iter.get_next(); 271 // 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 273 // to NULL it first before setting it to the value. 274 hr->set_containing_set(NULL); 275 hr->set_containing_set(this); 276 } 277 #endif // ASSERT 278 279 if (_head != NULL) { 280 assert(length() > 0 && _tail != NULL, hrs_ext_msg(this, "invariant")); 281 from_list->_tail->set_next(_head); 282 } else { 283 assert(length() == 0 && _tail == NULL, hrs_ext_msg(this, "invariant")); 284 _tail = from_list->_tail; 285 } 286 _head = from_list->_head; 287 288 _length += from_list->length(); 289 _region_num += from_list->region_num(); 290 _total_used_bytes += from_list->total_used_bytes(); 291 from_list->clear(); 292 293 verify_optional(); 294 from_list->verify_optional(); 295 } 296 297 void HeapRegionLinkedList::add_as_tail(HeapRegionLinkedList* from_list) { 298 hrs_assert_mt_safety_ok(this); 299 hrs_assert_mt_safety_ok(from_list); 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) { 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(); 339 340 HeapRegion* curr = _head; 341 while (curr != NULL) { 342 hrs_assert_region_ok(this, curr, this); 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 354 void HeapRegionLinkedList::remove_all_pending(uint target_count) { 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")); 358 359 verify_optional(); 360 DEBUG_ONLY(uint old_length = length();) 361 362 HeapRegion* curr = _head; 363 HeapRegion* prev = NULL; 364 uint count = 0; 365 while (curr != NULL) { 366 hrs_assert_region_ok(this, curr, this); 367 HeapRegion* next = curr->next(); 368 369 if (curr->pending_removal()) { 370 assert(count < target_count, 371 hrs_err_msg("[%s] should not come across more regions " 372 "pending for removal than target_count: %u", 373 name(), target_count)); 374 375 if (prev == NULL) { 376 assert(_head == curr, hrs_ext_msg(this, "invariant")); 377 _head = next; 378 } else { 379 assert(_head != curr, hrs_ext_msg(this, "invariant")); 380 prev->set_next(next); 381 } 382 if (next == NULL) { 383 assert(_tail == curr, hrs_ext_msg(this, "invariant")); 384 _tail = prev; 385 } else { 386 assert(_tail != curr, hrs_ext_msg(this, "invariant")); 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, 407 hrs_err_msg("[%s] count: %u should be == target_count: %u", 408 name(), count, target_count)); 409 assert(length() + target_count == old_length, 410 hrs_err_msg("[%s] new length should be consistent " 411 "new length: %u old length: %u target_count: %u", 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. 420 hrs_assert_mt_safety_ok(this); 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; 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 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 }