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

Wed, 27 Apr 2016 01:25:04 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:25:04 +0800
changeset 0
f90c822e73f8
child 6876
710a3c8b516e
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/
changeset: 6782:28b50d07f6f8
tag: jdk8u25-b17

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

mercurial