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

Mon, 02 Aug 2010 12:51:43 -0700

author
johnc
date
Mon, 02 Aug 2010 12:51:43 -0700
changeset 2060
2d160770d2e5
parent 1907
c18cbe5936b8
child 2063
a03ae377b2e8
permissions
-rw-r--r--

6814437: G1: remove the _new_refs array
Summary: The per-worker _new_refs array is used to hold references that point into the collection set. It is populated during RSet updating and subsequently processed. In the event of an evacuation failure it processed again to recreate the RSets of regions in the collection set. Remove the per-worker _new_refs array by processing the references directly. Use a DirtyCardQueue to hold the cards containing the references so that the RSets of regions in the collection set can be recreated when handling an evacuation failure.
Reviewed-by: iveresov, jmasa, tonyp

ysr@777 1 /*
trims@1907 2 * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved.
ysr@777 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ysr@777 4 *
ysr@777 5 * This code is free software; you can redistribute it and/or modify it
ysr@777 6 * under the terms of the GNU General Public License version 2 only, as
ysr@777 7 * published by the Free Software Foundation.
ysr@777 8 *
ysr@777 9 * This code is distributed in the hope that it will be useful, but WITHOUT
ysr@777 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ysr@777 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ysr@777 12 * version 2 for more details (a copy is included in the LICENSE file that
ysr@777 13 * accompanied this code).
ysr@777 14 *
ysr@777 15 * You should have received a copy of the GNU General Public License version
ysr@777 16 * 2 along with this work; if not, write to the Free Software Foundation,
ysr@777 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ysr@777 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
ysr@777 22 *
ysr@777 23 */
ysr@777 24
ysr@777 25 #include "incls/_precompiled.incl"
ysr@777 26 #include "incls/_sparsePRT.cpp.incl"
ysr@777 27
ysr@777 28 #define SPARSE_PRT_VERBOSE 0
ysr@777 29
iveresov@1696 30 #define UNROLL_CARD_LOOPS 1
ysr@777 31
ysr@777 32 void SparsePRT::init_iterator(SparsePRTIter* sprt_iter) {
ysr@777 33 sprt_iter->init(this);
ysr@777 34 }
ysr@777 35
johnc@1242 36 void SparsePRTEntry::init(RegionIdx_t region_ind) {
ysr@777 37 _region_ind = region_ind;
ysr@777 38 _next_index = NullEntry;
iveresov@1696 39
ysr@777 40 #if UNROLL_CARD_LOOPS
iveresov@1696 41 assert((cards_num() & (UnrollFactor - 1)) == 0, "Invalid number of cards in the entry");
iveresov@1696 42 for (int i = 0; i < cards_num(); i += UnrollFactor) {
iveresov@1696 43 _cards[i] = NullEntry;
iveresov@1696 44 _cards[i + 1] = NullEntry;
iveresov@1696 45 _cards[i + 2] = NullEntry;
iveresov@1696 46 _cards[i + 3] = NullEntry;
iveresov@1696 47 }
ysr@777 48 #else
iveresov@1696 49 for (int i = 0; i < cards_num(); i++)
johnc@1242 50 _cards[i] = NullEntry;
ysr@777 51 #endif
ysr@777 52 }
ysr@777 53
johnc@1242 54 bool SparsePRTEntry::contains_card(CardIdx_t card_index) const {
ysr@777 55 #if UNROLL_CARD_LOOPS
iveresov@1696 56 assert((cards_num() & (UnrollFactor - 1)) == 0, "Invalid number of cards in the entry");
iveresov@1696 57 for (int i = 0; i < cards_num(); i += UnrollFactor) {
iveresov@1696 58 if (_cards[i] == card_index ||
iveresov@1696 59 _cards[i + 1] == card_index ||
iveresov@1696 60 _cards[i + 2] == card_index ||
iveresov@1696 61 _cards[i + 3] == card_index) return true;
iveresov@1696 62 }
ysr@777 63 #else
iveresov@1696 64 for (int i = 0; i < cards_num(); i++) {
ysr@777 65 if (_cards[i] == card_index) return true;
ysr@777 66 }
ysr@777 67 #endif
ysr@777 68 // Otherwise, we're full.
ysr@777 69 return false;
ysr@777 70 }
ysr@777 71
ysr@777 72 int SparsePRTEntry::num_valid_cards() const {
ysr@777 73 int sum = 0;
ysr@777 74 #if UNROLL_CARD_LOOPS
iveresov@1696 75 assert((cards_num() & (UnrollFactor - 1)) == 0, "Invalid number of cards in the entry");
iveresov@1696 76 for (int i = 0; i < cards_num(); i += UnrollFactor) {
iveresov@1696 77 sum += (_cards[i] != NullEntry);
iveresov@1696 78 sum += (_cards[i + 1] != NullEntry);
iveresov@1696 79 sum += (_cards[i + 2] != NullEntry);
iveresov@1696 80 sum += (_cards[i + 3] != NullEntry);
iveresov@1696 81 }
ysr@777 82 #else
iveresov@1696 83 for (int i = 0; i < cards_num(); i++) {
iveresov@1696 84 sum += (_cards[i] != NullEntry);
ysr@777 85 }
ysr@777 86 #endif
ysr@777 87 // Otherwise, we're full.
ysr@777 88 return sum;
ysr@777 89 }
ysr@777 90
johnc@1242 91 SparsePRTEntry::AddCardResult SparsePRTEntry::add_card(CardIdx_t card_index) {
ysr@777 92 #if UNROLL_CARD_LOOPS
iveresov@1696 93 assert((cards_num() & (UnrollFactor - 1)) == 0, "Invalid number of cards in the entry");
iveresov@1696 94 CardIdx_t c;
iveresov@1696 95 for (int i = 0; i < cards_num(); i += UnrollFactor) {
iveresov@1696 96 c = _cards[i];
iveresov@1696 97 if (c == card_index) return found;
iveresov@1696 98 if (c == NullEntry) { _cards[i] = card_index; return added; }
iveresov@1696 99 c = _cards[i + 1];
iveresov@1696 100 if (c == card_index) return found;
iveresov@1696 101 if (c == NullEntry) { _cards[i + 1] = card_index; return added; }
iveresov@1696 102 c = _cards[i + 2];
iveresov@1696 103 if (c == card_index) return found;
iveresov@1696 104 if (c == NullEntry) { _cards[i + 2] = card_index; return added; }
iveresov@1696 105 c = _cards[i + 3];
iveresov@1696 106 if (c == card_index) return found;
iveresov@1696 107 if (c == NullEntry) { _cards[i + 3] = card_index; return added; }
iveresov@1696 108 }
ysr@777 109 #else
iveresov@1696 110 for (int i = 0; i < cards_num(); i++) {
johnc@1242 111 CardIdx_t c = _cards[i];
ysr@777 112 if (c == card_index) return found;
iveresov@1696 113 if (c == NullEntry) { _cards[i] = card_index; return added; }
ysr@777 114 }
ysr@777 115 #endif
ysr@777 116 // Otherwise, we're full.
ysr@777 117 return overflow;
ysr@777 118 }
ysr@777 119
johnc@1242 120 void SparsePRTEntry::copy_cards(CardIdx_t* cards) const {
ysr@777 121 #if UNROLL_CARD_LOOPS
iveresov@1696 122 assert((cards_num() & (UnrollFactor - 1)) == 0, "Invalid number of cards in the entry");
iveresov@1696 123 for (int i = 0; i < cards_num(); i += UnrollFactor) {
iveresov@1696 124 cards[i] = _cards[i];
iveresov@1696 125 cards[i + 1] = _cards[i + 1];
iveresov@1696 126 cards[i + 2] = _cards[i + 2];
iveresov@1696 127 cards[i + 3] = _cards[i + 3];
iveresov@1696 128 }
ysr@777 129 #else
iveresov@1696 130 for (int i = 0; i < cards_num(); i++) {
ysr@777 131 cards[i] = _cards[i];
ysr@777 132 }
ysr@777 133 #endif
ysr@777 134 }
ysr@777 135
ysr@777 136 void SparsePRTEntry::copy_cards(SparsePRTEntry* e) const {
ysr@777 137 copy_cards(&e->_cards[0]);
ysr@777 138 }
ysr@777 139
ysr@777 140 // ----------------------------------------------------------------------
ysr@777 141
ysr@777 142 RSHashTable::RSHashTable(size_t capacity) :
ysr@777 143 _capacity(capacity), _capacity_mask(capacity-1),
ysr@777 144 _occupied_entries(0), _occupied_cards(0),
iveresov@1696 145 _entries((SparsePRTEntry*)NEW_C_HEAP_ARRAY(char, SparsePRTEntry::size() * capacity)),
johnc@1242 146 _buckets(NEW_C_HEAP_ARRAY(int, capacity)),
ysr@777 147 _free_list(NullEntry), _free_region(0)
ysr@777 148 {
ysr@777 149 clear();
ysr@777 150 }
ysr@777 151
ysr@777 152 RSHashTable::~RSHashTable() {
ysr@777 153 if (_entries != NULL) {
ysr@777 154 FREE_C_HEAP_ARRAY(SparsePRTEntry, _entries);
ysr@777 155 _entries = NULL;
ysr@777 156 }
ysr@777 157 if (_buckets != NULL) {
johnc@1242 158 FREE_C_HEAP_ARRAY(int, _buckets);
ysr@777 159 _buckets = NULL;
ysr@777 160 }
ysr@777 161 }
ysr@777 162
ysr@777 163 void RSHashTable::clear() {
ysr@777 164 _occupied_entries = 0;
ysr@777 165 _occupied_cards = 0;
ysr@777 166 guarantee(_entries != NULL, "INV");
ysr@777 167 guarantee(_buckets != NULL, "INV");
johnc@1242 168
johnc@1242 169 guarantee(_capacity <= ((size_t)1 << (sizeof(int)*BitsPerByte-1)) - 1,
johnc@1242 170 "_capacity too large");
johnc@1242 171
ysr@777 172 // This will put -1 == NullEntry in the key field of all entries.
iveresov@1696 173 memset(_entries, NullEntry, _capacity * SparsePRTEntry::size());
iveresov@1696 174 memset(_buckets, NullEntry, _capacity * sizeof(int));
ysr@777 175 _free_list = NullEntry;
ysr@777 176 _free_region = 0;
ysr@777 177 }
ysr@777 178
johnc@1242 179 bool RSHashTable::add_card(RegionIdx_t region_ind, CardIdx_t card_index) {
ysr@777 180 SparsePRTEntry* e = entry_for_region_ind_create(region_ind);
ysr@777 181 assert(e != NULL && e->r_ind() == region_ind,
ysr@777 182 "Postcondition of call above.");
ysr@777 183 SparsePRTEntry::AddCardResult res = e->add_card(card_index);
ysr@777 184 if (res == SparsePRTEntry::added) _occupied_cards++;
ysr@777 185 #if SPARSE_PRT_VERBOSE
ysr@777 186 gclog_or_tty->print_cr(" after add_card[%d]: valid-cards = %d.",
iveresov@1696 187 pointer_delta(e, _entries, SparsePRTEntry::size()),
iveresov@1696 188 e->num_valid_cards());
ysr@777 189 #endif
ysr@777 190 assert(e->num_valid_cards() > 0, "Postcondition");
ysr@777 191 return res != SparsePRTEntry::overflow;
ysr@777 192 }
ysr@777 193
johnc@1242 194 bool RSHashTable::get_cards(RegionIdx_t region_ind, CardIdx_t* cards) {
johnc@1242 195 int ind = (int) (region_ind & capacity_mask());
johnc@1242 196 int cur_ind = _buckets[ind];
ysr@777 197 SparsePRTEntry* cur;
ysr@777 198 while (cur_ind != NullEntry &&
ysr@777 199 (cur = entry(cur_ind))->r_ind() != region_ind) {
ysr@777 200 cur_ind = cur->next_index();
ysr@777 201 }
ysr@777 202
ysr@777 203 if (cur_ind == NullEntry) return false;
ysr@777 204 // Otherwise...
ysr@777 205 assert(cur->r_ind() == region_ind, "Postcondition of loop + test above.");
ysr@777 206 assert(cur->num_valid_cards() > 0, "Inv");
ysr@777 207 cur->copy_cards(cards);
ysr@777 208 return true;
ysr@777 209 }
ysr@777 210
iveresov@1696 211 SparsePRTEntry* RSHashTable::get_entry(RegionIdx_t region_ind) {
iveresov@1696 212 int ind = (int) (region_ind & capacity_mask());
iveresov@1696 213 int cur_ind = _buckets[ind];
iveresov@1696 214 SparsePRTEntry* cur;
iveresov@1696 215 while (cur_ind != NullEntry &&
iveresov@1696 216 (cur = entry(cur_ind))->r_ind() != region_ind) {
iveresov@1696 217 cur_ind = cur->next_index();
iveresov@1696 218 }
iveresov@1696 219
iveresov@1696 220 if (cur_ind == NullEntry) return NULL;
iveresov@1696 221 // Otherwise...
iveresov@1696 222 assert(cur->r_ind() == region_ind, "Postcondition of loop + test above.");
iveresov@1696 223 assert(cur->num_valid_cards() > 0, "Inv");
iveresov@1696 224 return cur;
iveresov@1696 225 }
iveresov@1696 226
johnc@1242 227 bool RSHashTable::delete_entry(RegionIdx_t region_ind) {
johnc@1242 228 int ind = (int) (region_ind & capacity_mask());
johnc@1242 229 int* prev_loc = &_buckets[ind];
johnc@1242 230 int cur_ind = *prev_loc;
ysr@777 231 SparsePRTEntry* cur;
ysr@777 232 while (cur_ind != NullEntry &&
ysr@777 233 (cur = entry(cur_ind))->r_ind() != region_ind) {
ysr@777 234 prev_loc = cur->next_index_addr();
ysr@777 235 cur_ind = *prev_loc;
ysr@777 236 }
ysr@777 237
ysr@777 238 if (cur_ind == NullEntry) return false;
ysr@777 239 // Otherwise, splice out "cur".
ysr@777 240 *prev_loc = cur->next_index();
ysr@777 241 _occupied_cards -= cur->num_valid_cards();
ysr@777 242 free_entry(cur_ind);
ysr@777 243 _occupied_entries--;
ysr@777 244 return true;
ysr@777 245 }
ysr@777 246
johnc@1242 247 SparsePRTEntry*
johnc@1242 248 RSHashTable::entry_for_region_ind(RegionIdx_t region_ind) const {
ysr@777 249 assert(occupied_entries() < capacity(), "Precondition");
johnc@1242 250 int ind = (int) (region_ind & capacity_mask());
johnc@1242 251 int cur_ind = _buckets[ind];
ysr@777 252 SparsePRTEntry* cur;
ysr@777 253 while (cur_ind != NullEntry &&
ysr@777 254 (cur = entry(cur_ind))->r_ind() != region_ind) {
ysr@777 255 cur_ind = cur->next_index();
ysr@777 256 }
ysr@777 257
ysr@777 258 if (cur_ind != NullEntry) {
ysr@777 259 assert(cur->r_ind() == region_ind, "Loop postcondition + test");
ysr@777 260 return cur;
ysr@777 261 } else {
ysr@777 262 return NULL;
ysr@777 263 }
ysr@777 264 }
ysr@777 265
johnc@1242 266 SparsePRTEntry*
johnc@1242 267 RSHashTable::entry_for_region_ind_create(RegionIdx_t region_ind) {
ysr@777 268 SparsePRTEntry* res = entry_for_region_ind(region_ind);
ysr@777 269 if (res == NULL) {
johnc@1242 270 int new_ind = alloc_entry();
ysr@777 271 assert(0 <= new_ind && (size_t)new_ind < capacity(), "There should be room.");
ysr@777 272 res = entry(new_ind);
ysr@777 273 res->init(region_ind);
ysr@777 274 // Insert at front.
johnc@1242 275 int ind = (int) (region_ind & capacity_mask());
ysr@777 276 res->set_next_index(_buckets[ind]);
ysr@777 277 _buckets[ind] = new_ind;
ysr@777 278 _occupied_entries++;
ysr@777 279 }
ysr@777 280 return res;
ysr@777 281 }
ysr@777 282
johnc@1242 283 int RSHashTable::alloc_entry() {
johnc@1242 284 int res;
ysr@777 285 if (_free_list != NullEntry) {
ysr@777 286 res = _free_list;
ysr@777 287 _free_list = entry(res)->next_index();
ysr@777 288 return res;
ysr@777 289 } else if ((size_t) _free_region+1 < capacity()) {
ysr@777 290 res = _free_region;
ysr@777 291 _free_region++;
ysr@777 292 return res;
ysr@777 293 } else {
ysr@777 294 return NullEntry;
ysr@777 295 }
ysr@777 296 }
ysr@777 297
johnc@1242 298 void RSHashTable::free_entry(int fi) {
ysr@777 299 entry(fi)->set_next_index(_free_list);
ysr@777 300 _free_list = fi;
ysr@777 301 }
ysr@777 302
ysr@777 303 void RSHashTable::add_entry(SparsePRTEntry* e) {
ysr@777 304 assert(e->num_valid_cards() > 0, "Precondition.");
ysr@777 305 SparsePRTEntry* e2 = entry_for_region_ind_create(e->r_ind());
ysr@777 306 e->copy_cards(e2);
ysr@777 307 _occupied_cards += e2->num_valid_cards();
ysr@777 308 assert(e2->num_valid_cards() > 0, "Postcondition.");
ysr@777 309 }
ysr@777 310
johnc@1242 311 CardIdx_t /* RSHashTable:: */ RSHashTableIter::find_first_card_in_list() {
johnc@1242 312 CardIdx_t res;
ysr@777 313 while (_bl_ind != RSHashTable::NullEntry) {
ysr@777 314 res = _rsht->entry(_bl_ind)->card(0);
ysr@777 315 if (res != SparsePRTEntry::NullEntry) {
ysr@777 316 return res;
ysr@777 317 } else {
ysr@777 318 _bl_ind = _rsht->entry(_bl_ind)->next_index();
ysr@777 319 }
ysr@777 320 }
ysr@777 321 // Otherwise, none found:
ysr@777 322 return SparsePRTEntry::NullEntry;
ysr@777 323 }
ysr@777 324
johnc@1242 325 size_t /* RSHashTable:: */ RSHashTableIter::compute_card_ind(CardIdx_t ci) {
ysr@777 326 return
ysr@777 327 _heap_bot_card_ind
tonyp@1377 328 + (_rsht->entry(_bl_ind)->r_ind() * HeapRegion::CardsPerRegion)
ysr@777 329 + ci;
ysr@777 330 }
ysr@777 331
ysr@777 332 bool /* RSHashTable:: */ RSHashTableIter::has_next(size_t& card_index) {
ysr@777 333 _card_ind++;
johnc@1242 334 CardIdx_t ci;
iveresov@1696 335 if (_card_ind < SparsePRTEntry::cards_num() &&
ysr@777 336 ((ci = _rsht->entry(_bl_ind)->card(_card_ind)) !=
ysr@777 337 SparsePRTEntry::NullEntry)) {
ysr@777 338 card_index = compute_card_ind(ci);
ysr@777 339 return true;
ysr@777 340 }
ysr@777 341 // Otherwise, must find the next valid entry.
ysr@777 342 _card_ind = 0;
ysr@777 343
ysr@777 344 if (_bl_ind != RSHashTable::NullEntry) {
ysr@777 345 _bl_ind = _rsht->entry(_bl_ind)->next_index();
ysr@777 346 ci = find_first_card_in_list();
ysr@777 347 if (ci != SparsePRTEntry::NullEntry) {
ysr@777 348 card_index = compute_card_ind(ci);
ysr@777 349 return true;
ysr@777 350 }
ysr@777 351 }
ysr@777 352 // If we didn't return above, must go to the next non-null table index.
ysr@777 353 _tbl_ind++;
ysr@777 354 while ((size_t)_tbl_ind < _rsht->capacity()) {
ysr@777 355 _bl_ind = _rsht->_buckets[_tbl_ind];
ysr@777 356 ci = find_first_card_in_list();
ysr@777 357 if (ci != SparsePRTEntry::NullEntry) {
ysr@777 358 card_index = compute_card_ind(ci);
ysr@777 359 return true;
ysr@777 360 }
ysr@777 361 // Otherwise, try next entry.
ysr@777 362 _tbl_ind++;
ysr@777 363 }
ysr@777 364 // Otherwise, there were no entry.
ysr@777 365 return false;
ysr@777 366 }
ysr@777 367
johnc@1242 368 bool RSHashTable::contains_card(RegionIdx_t region_index, CardIdx_t card_index) const {
ysr@777 369 SparsePRTEntry* e = entry_for_region_ind(region_index);
ysr@777 370 return (e != NULL && e->contains_card(card_index));
ysr@777 371 }
ysr@777 372
ysr@777 373 size_t RSHashTable::mem_size() const {
johnc@1242 374 return sizeof(this) +
iveresov@1696 375 capacity() * (SparsePRTEntry::size() + sizeof(int));
ysr@777 376 }
ysr@777 377
ysr@777 378 // ----------------------------------------------------------------------
ysr@777 379
ysr@777 380 SparsePRT* SparsePRT::_head_expanded_list = NULL;
ysr@777 381
ysr@777 382 void SparsePRT::add_to_expanded_list(SparsePRT* sprt) {
ysr@777 383 // We could expand multiple times in a pause -- only put on list once.
ysr@777 384 if (sprt->expanded()) return;
ysr@777 385 sprt->set_expanded(true);
ysr@777 386 SparsePRT* hd = _head_expanded_list;
ysr@777 387 while (true) {
ysr@777 388 sprt->_next_expanded = hd;
ysr@777 389 SparsePRT* res =
ysr@777 390 (SparsePRT*)
ysr@777 391 Atomic::cmpxchg_ptr(sprt, &_head_expanded_list, hd);
ysr@777 392 if (res == hd) return;
ysr@777 393 else hd = res;
ysr@777 394 }
ysr@777 395 }
ysr@777 396
johnc@1242 397
ysr@777 398 SparsePRT* SparsePRT::get_from_expanded_list() {
ysr@777 399 SparsePRT* hd = _head_expanded_list;
ysr@777 400 while (hd != NULL) {
ysr@777 401 SparsePRT* next = hd->next_expanded();
ysr@777 402 SparsePRT* res =
ysr@777 403 (SparsePRT*)
ysr@777 404 Atomic::cmpxchg_ptr(next, &_head_expanded_list, hd);
ysr@777 405 if (res == hd) {
ysr@777 406 hd->set_next_expanded(NULL);
ysr@777 407 return hd;
ysr@777 408 } else {
ysr@777 409 hd = res;
ysr@777 410 }
ysr@777 411 }
ysr@777 412 return NULL;
ysr@777 413 }
ysr@777 414
ysr@777 415
ysr@777 416 void SparsePRT::cleanup_all() {
ysr@777 417 // First clean up all expanded tables so they agree on next and cur.
ysr@777 418 SparsePRT* sprt = get_from_expanded_list();
ysr@777 419 while (sprt != NULL) {
ysr@777 420 sprt->cleanup();
ysr@777 421 sprt = get_from_expanded_list();
ysr@777 422 }
ysr@777 423 }
ysr@777 424
ysr@777 425
ysr@777 426 SparsePRT::SparsePRT(HeapRegion* hr) :
ysr@777 427 _expanded(false), _next_expanded(NULL)
ysr@777 428 {
ysr@777 429 _cur = new RSHashTable(InitialCapacity);
ysr@777 430 _next = _cur;
ysr@777 431 }
ysr@777 432
johnc@1242 433
ysr@777 434 SparsePRT::~SparsePRT() {
ysr@777 435 assert(_next != NULL && _cur != NULL, "Inv");
ysr@777 436 if (_cur != _next) { delete _cur; }
ysr@777 437 delete _next;
ysr@777 438 }
ysr@777 439
ysr@777 440
ysr@777 441 size_t SparsePRT::mem_size() const {
ysr@777 442 // We ignore "_cur" here, because it either = _next, or else it is
ysr@777 443 // on the deleted list.
ysr@777 444 return sizeof(this) + _next->mem_size();
ysr@777 445 }
ysr@777 446
johnc@1242 447 bool SparsePRT::add_card(RegionIdx_t region_id, CardIdx_t card_index) {
ysr@777 448 #if SPARSE_PRT_VERBOSE
ysr@777 449 gclog_or_tty->print_cr(" Adding card %d from region %d to region %d sparse.",
ysr@777 450 card_index, region_id, _hr->hrs_index());
ysr@777 451 #endif
ysr@777 452 if (_next->occupied_entries() * 2 > _next->capacity()) {
ysr@777 453 expand();
ysr@777 454 }
ysr@777 455 return _next->add_card(region_id, card_index);
ysr@777 456 }
ysr@777 457
johnc@1242 458 bool SparsePRT::get_cards(RegionIdx_t region_id, CardIdx_t* cards) {
ysr@777 459 return _next->get_cards(region_id, cards);
ysr@777 460 }
ysr@777 461
iveresov@1696 462 SparsePRTEntry* SparsePRT::get_entry(RegionIdx_t region_id) {
iveresov@1696 463 return _next->get_entry(region_id);
iveresov@1696 464 }
iveresov@1696 465
johnc@1242 466 bool SparsePRT::delete_entry(RegionIdx_t region_id) {
ysr@777 467 return _next->delete_entry(region_id);
ysr@777 468 }
ysr@777 469
ysr@777 470 void SparsePRT::clear() {
ysr@777 471 // If they differ, _next is bigger then cur, so next has no chance of
ysr@777 472 // being the initial size.
ysr@777 473 if (_next != _cur) {
ysr@777 474 delete _next;
ysr@777 475 }
ysr@777 476
ysr@777 477 if (_cur->capacity() != InitialCapacity) {
ysr@777 478 delete _cur;
ysr@777 479 _cur = new RSHashTable(InitialCapacity);
ysr@777 480 } else {
ysr@777 481 _cur->clear();
ysr@777 482 }
ysr@777 483 _next = _cur;
ysr@777 484 }
ysr@777 485
ysr@777 486 void SparsePRT::cleanup() {
apetrusenko@1480 487 // Make sure that the current and next tables agree.
apetrusenko@1480 488 if (_cur != _next) {
apetrusenko@1480 489 delete _cur;
apetrusenko@1480 490 }
ysr@777 491 _cur = _next;
tonyp@1052 492 set_expanded(false);
ysr@777 493 }
ysr@777 494
ysr@777 495 void SparsePRT::expand() {
ysr@777 496 RSHashTable* last = _next;
ysr@777 497 _next = new RSHashTable(last->capacity() * 2);
ysr@777 498
ysr@777 499 #if SPARSE_PRT_VERBOSE
ysr@777 500 gclog_or_tty->print_cr(" Expanded sparse table for %d to %d.",
ysr@777 501 _hr->hrs_index(), _next->capacity());
ysr@777 502 #endif
ysr@777 503 for (size_t i = 0; i < last->capacity(); i++) {
ysr@777 504 SparsePRTEntry* e = last->entry((int)i);
ysr@777 505 if (e->valid_entry()) {
ysr@777 506 #if SPARSE_PRT_VERBOSE
ysr@777 507 gclog_or_tty->print_cr(" During expansion, transferred entry for %d.",
ysr@777 508 e->r_ind());
ysr@777 509 #endif
ysr@777 510 _next->add_entry(e);
ysr@777 511 }
ysr@777 512 }
apetrusenko@1480 513 if (last != _cur) {
apetrusenko@1480 514 delete last;
apetrusenko@1480 515 }
ysr@777 516 add_to_expanded_list(this);
ysr@777 517 }

mercurial