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

Thu, 03 Apr 2014 17:49:31 +0400

author
vkempik
date
Thu, 03 Apr 2014 17:49:31 +0400
changeset 6552
8847586c9037
parent 6422
8ee855b4e667
child 6680
78bbf4d43a14
permissions
-rw-r--r--

8016302: Change type of the number of GC workers to unsigned int (2)
Reviewed-by: tschatzl, jwilhelm

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

mercurial