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

Fri, 10 Oct 2014 15:51:58 +0200

author
tschatzl
date
Fri, 10 Oct 2014 15:51:58 +0200
changeset 7257
e7d0505c8a30
parent 7195
c02ec279b062
child 7535
7ae4e26cb1e0
child 7781
33e421924c67
permissions
-rw-r--r--

8059758: Footprint regressions with JDK-8038423
Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything.
Reviewed-by: jwilhelm, brutisso

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

mercurial