comparison src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp @ 6253:db823a892a55

7182260: G1: Fine grain RSet freeing bottleneck Summary: Chain the fine grain PerRegionTables in an individual RSet together and free them in bulk using a single operation. Reviewed-by: johnc, brutisso Contributed-by: Thomas Schatzl <thomas.schatzl@jku.at>
author johnc
date Tue, 17 Jul 2012 12:24:05 -0700
parents 24b9c7f4cae6
children 859cd1a76f8a
comparison
equal deleted inserted replaced
6252:d42fe3c3001d 6253:db823a892a55
32 #include "memory/space.inline.hpp" 32 #include "memory/space.inline.hpp"
33 #include "oops/oop.inline.hpp" 33 #include "oops/oop.inline.hpp"
34 #include "utilities/bitMap.inline.hpp" 34 #include "utilities/bitMap.inline.hpp"
35 #include "utilities/globalDefinitions.hpp" 35 #include "utilities/globalDefinitions.hpp"
36 36
37 // OtherRegionsTable
38
39 class PerRegionTable: public CHeapObj<mtGC> { 37 class PerRegionTable: public CHeapObj<mtGC> {
40 friend class OtherRegionsTable; 38 friend class OtherRegionsTable;
41 friend class HeapRegionRemSetIterator; 39 friend class HeapRegionRemSetIterator;
42 40
43 HeapRegion* _hr; 41 HeapRegion* _hr;
44 BitMap _bm; 42 BitMap _bm;
45 jint _occupied; 43 jint _occupied;
46 44
47 // next pointer for free/allocated lis 45 // next pointer for free/allocated 'all' list
48 PerRegionTable* _next; 46 PerRegionTable* _next;
49 47
48 // prev pointer for the allocated 'all' list
49 PerRegionTable* _prev;
50
51 // next pointer in collision list
52 PerRegionTable * _collision_list_next;
53
54 // Global free list of PRTs
50 static PerRegionTable* _free_list; 55 static PerRegionTable* _free_list;
51
52 #ifdef _MSC_VER
53 // For some reason even though the classes are marked as friend they are unable
54 // to access CardsPerRegion when private/protected. Only the windows c++ compiler
55 // says this Sun CC and linux gcc don't have a problem with access when private
56
57 public:
58
59 #endif // _MSC_VER
60 56
61 protected: 57 protected:
62 // We need access in order to union things into the base table. 58 // We need access in order to union things into the base table.
63 BitMap* bm() { return &_bm; } 59 BitMap* bm() { return &_bm; }
64 60
67 } 63 }
68 64
69 PerRegionTable(HeapRegion* hr) : 65 PerRegionTable(HeapRegion* hr) :
70 _hr(hr), 66 _hr(hr),
71 _occupied(0), 67 _occupied(0),
72 _bm(HeapRegion::CardsPerRegion, false /* in-resource-area */) 68 _bm(HeapRegion::CardsPerRegion, false /* in-resource-area */),
69 _collision_list_next(NULL), _next(NULL), _prev(NULL)
73 {} 70 {}
74 71
75 void add_card_work(CardIdx_t from_card, bool par) { 72 void add_card_work(CardIdx_t from_card, bool par) {
76 if (!_bm.at(from_card)) { 73 if (!_bm.at(from_card)) {
77 if (par) { 74 if (par) {
124 // Overkill, but if we ever need it... 121 // Overkill, but if we ever need it...
125 // guarantee(_occupied == _bm.count_one_bits(), "Check"); 122 // guarantee(_occupied == _bm.count_one_bits(), "Check");
126 return _occupied; 123 return _occupied;
127 } 124 }
128 125
129 void init(HeapRegion* hr) { 126 void init(HeapRegion* hr, bool clear_links_to_all_list) {
127 if (clear_links_to_all_list) {
128 set_next(NULL);
129 set_prev(NULL);
130 }
130 _hr = hr; 131 _hr = hr;
131 _next = NULL; 132 _collision_list_next = NULL;
132 _occupied = 0; 133 _occupied = 0;
133 _bm.clear(); 134 _bm.clear();
134 } 135 }
135 136
136 void add_reference(OopOrNarrowOopStar from) { 137 void add_reference(OopOrNarrowOopStar from) {
173 size_t card_ind = pointer_delta(from, hr()->bottom(), 174 size_t card_ind = pointer_delta(from, hr()->bottom(),
174 CardTableModRefBS::card_size); 175 CardTableModRefBS::card_size);
175 return _bm.at(card_ind); 176 return _bm.at(card_ind);
176 } 177 }
177 178
178 PerRegionTable* next() const { return _next; } 179 // Bulk-free the PRTs from prt to last, assumes that they are
179 void set_next(PerRegionTable* nxt) { _next = nxt; } 180 // linked together using their _next field.
180 PerRegionTable** next_addr() { return &_next; } 181 static void bulk_free(PerRegionTable* prt, PerRegionTable* last) {
181
182 static void free(PerRegionTable* prt) {
183 while (true) { 182 while (true) {
184 PerRegionTable* fl = _free_list; 183 PerRegionTable* fl = _free_list;
185 prt->set_next(fl); 184 last->set_next(fl);
186 PerRegionTable* res = 185 PerRegionTable* res = (PerRegionTable*) Atomic::cmpxchg_ptr(prt, &_free_list, fl);
187 (PerRegionTable*) 186 if (res == fl) {
188 Atomic::cmpxchg_ptr(prt, &_free_list, fl); 187 return;
189 if (res == fl) return; 188 }
190 } 189 }
191 ShouldNotReachHere(); 190 ShouldNotReachHere();
192 } 191 }
193 192
193 static void free(PerRegionTable* prt) {
194 bulk_free(prt, prt);
195 }
196
197 // Returns an initialized PerRegionTable instance.
194 static PerRegionTable* alloc(HeapRegion* hr) { 198 static PerRegionTable* alloc(HeapRegion* hr) {
195 PerRegionTable* fl = _free_list; 199 PerRegionTable* fl = _free_list;
196 while (fl != NULL) { 200 while (fl != NULL) {
197 PerRegionTable* nxt = fl->next(); 201 PerRegionTable* nxt = fl->next();
198 PerRegionTable* res = 202 PerRegionTable* res =
199 (PerRegionTable*) 203 (PerRegionTable*)
200 Atomic::cmpxchg_ptr(nxt, &_free_list, fl); 204 Atomic::cmpxchg_ptr(nxt, &_free_list, fl);
201 if (res == fl) { 205 if (res == fl) {
202 fl->init(hr); 206 fl->init(hr, true);
203 return fl; 207 return fl;
204 } else { 208 } else {
205 fl = _free_list; 209 fl = _free_list;
206 } 210 }
207 } 211 }
208 assert(fl == NULL, "Loop condition."); 212 assert(fl == NULL, "Loop condition.");
209 return new PerRegionTable(hr); 213 return new PerRegionTable(hr);
214 }
215
216 PerRegionTable* next() const { return _next; }
217 void set_next(PerRegionTable* next) { _next = next; }
218 PerRegionTable* prev() const { return _prev; }
219 void set_prev(PerRegionTable* prev) { _prev = prev; }
220
221 // Accessor and Modification routines for the pointer for the
222 // singly linked collision list that links the PRTs within the
223 // OtherRegionsTable::_fine_grain_regions hash table.
224 //
225 // It might be useful to also make the collision list doubly linked
226 // to avoid iteration over the collisions list during scrubbing/deletion.
227 // OTOH there might not be many collisions.
228
229 PerRegionTable* collision_list_next() const {
230 return _collision_list_next;
231 }
232
233 void set_collision_list_next(PerRegionTable* next) {
234 _collision_list_next = next;
235 }
236
237 PerRegionTable** collision_list_next_addr() {
238 return &_collision_list_next;
210 } 239 }
211 240
212 static size_t fl_mem_size() { 241 static size_t fl_mem_size() {
213 PerRegionTable* cur = _free_list; 242 PerRegionTable* cur = _free_list;
214 size_t res = 0; 243 size_t res = 0;
232 _m(Mutex::leaf, "An OtherRegionsTable lock", true), 261 _m(Mutex::leaf, "An OtherRegionsTable lock", true),
233 _hr(hr), 262 _hr(hr),
234 _coarse_map(G1CollectedHeap::heap()->max_regions(), 263 _coarse_map(G1CollectedHeap::heap()->max_regions(),
235 false /* in-resource-area */), 264 false /* in-resource-area */),
236 _fine_grain_regions(NULL), 265 _fine_grain_regions(NULL),
266 _first_all_fine_prts(NULL), _last_all_fine_prts(NULL),
237 _n_fine_entries(0), _n_coarse_entries(0), 267 _n_fine_entries(0), _n_coarse_entries(0),
238 _fine_eviction_start(0), 268 _fine_eviction_start(0),
239 _sparse_table(hr) 269 _sparse_table(hr)
240 { 270 {
241 typedef PerRegionTable* PerRegionTablePtr; 271 typedef PerRegionTable* PerRegionTablePtr;
260 } 290 }
261 291
262 for (size_t i = 0; i < _max_fine_entries; i++) { 292 for (size_t i = 0; i < _max_fine_entries; i++) {
263 _fine_grain_regions[i] = NULL; 293 _fine_grain_regions[i] = NULL;
264 } 294 }
295 }
296
297 void OtherRegionsTable::link_to_all(PerRegionTable* prt) {
298 // We always append to the beginning of the list for convenience;
299 // the order of entries in this list does not matter.
300 if (_first_all_fine_prts != NULL) {
301 assert(_first_all_fine_prts->prev() == NULL, "invariant");
302 _first_all_fine_prts->set_prev(prt);
303 prt->set_next(_first_all_fine_prts);
304 } else {
305 // this is the first element we insert. Adjust the "last" pointer
306 _last_all_fine_prts = prt;
307 assert(prt->next() == NULL, "just checking");
308 }
309 // the new element is always the first element without a predecessor
310 prt->set_prev(NULL);
311 _first_all_fine_prts = prt;
312
313 assert(prt->prev() == NULL, "just checking");
314 assert(_first_all_fine_prts == prt, "just checking");
315 assert((_first_all_fine_prts == NULL && _last_all_fine_prts == NULL) ||
316 (_first_all_fine_prts != NULL && _last_all_fine_prts != NULL),
317 "just checking");
318 assert(_last_all_fine_prts == NULL || _last_all_fine_prts->next() == NULL,
319 "just checking");
320 assert(_first_all_fine_prts == NULL || _first_all_fine_prts->prev() == NULL,
321 "just checking");
322 }
323
324 void OtherRegionsTable::unlink_from_all(PerRegionTable* prt) {
325 if (prt->prev() != NULL) {
326 assert(_first_all_fine_prts != prt, "just checking");
327 prt->prev()->set_next(prt->next());
328 // removing the last element in the list?
329 if (_last_all_fine_prts == prt) {
330 _last_all_fine_prts = prt->prev();
331 }
332 } else {
333 assert(_first_all_fine_prts == prt, "just checking");
334 _first_all_fine_prts = prt->next();
335 // list is empty now?
336 if (_first_all_fine_prts == NULL) {
337 _last_all_fine_prts = NULL;
338 }
339 }
340
341 if (prt->next() != NULL) {
342 prt->next()->set_prev(prt->prev());
343 }
344
345 prt->set_next(NULL);
346 prt->set_prev(NULL);
347
348 assert((_first_all_fine_prts == NULL && _last_all_fine_prts == NULL) ||
349 (_first_all_fine_prts != NULL && _last_all_fine_prts != NULL),
350 "just checking");
351 assert(_last_all_fine_prts == NULL || _last_all_fine_prts->next() == NULL,
352 "just checking");
353 assert(_first_all_fine_prts == NULL || _first_all_fine_prts->prev() == NULL,
354 "just checking");
265 } 355 }
266 356
267 int** OtherRegionsTable::_from_card_cache = NULL; 357 int** OtherRegionsTable::_from_card_cache = NULL;
268 size_t OtherRegionsTable::_from_card_cache_max_regions = 0; 358 size_t OtherRegionsTable::_from_card_cache_max_regions = 0;
269 size_t OtherRegionsTable::_from_card_cache_mem_size = 0; 359 size_t OtherRegionsTable::_from_card_cache_mem_size = 0;
384 } 474 }
385 } 475 }
386 476
387 if (_n_fine_entries == _max_fine_entries) { 477 if (_n_fine_entries == _max_fine_entries) {
388 prt = delete_region_table(); 478 prt = delete_region_table();
479 // There is no need to clear the links to the 'all' list here:
480 // prt will be reused immediately, i.e. remain in the 'all' list.
481 prt->init(from_hr, false /* clear_links_to_all_list */);
389 } else { 482 } else {
390 prt = PerRegionTable::alloc(from_hr); 483 prt = PerRegionTable::alloc(from_hr);
484 link_to_all(prt);
391 } 485 }
392 prt->init(from_hr);
393 486
394 PerRegionTable* first_prt = _fine_grain_regions[ind]; 487 PerRegionTable* first_prt = _fine_grain_regions[ind];
395 prt->set_next(first_prt); // XXX Maybe move to init? 488 prt->set_collision_list_next(first_prt);
396 _fine_grain_regions[ind] = prt; 489 _fine_grain_regions[ind] = prt;
397 _n_fine_entries++; 490 _n_fine_entries++;
398 491
399 if (G1HRRSUseSparseTable) { 492 if (G1HRRSUseSparseTable) {
400 // Transfer from sparse to fine-grain. 493 // Transfer from sparse to fine-grain.
436 PerRegionTable* 529 PerRegionTable*
437 OtherRegionsTable::find_region_table(size_t ind, HeapRegion* hr) const { 530 OtherRegionsTable::find_region_table(size_t ind, HeapRegion* hr) const {
438 assert(0 <= ind && ind < _max_fine_entries, "Preconditions."); 531 assert(0 <= ind && ind < _max_fine_entries, "Preconditions.");
439 PerRegionTable* prt = _fine_grain_regions[ind]; 532 PerRegionTable* prt = _fine_grain_regions[ind];
440 while (prt != NULL && prt->hr() != hr) { 533 while (prt != NULL && prt->hr() != hr) {
441 prt = prt->next(); 534 prt = prt->collision_list_next();
442 } 535 }
443 // Loop postcondition is the method postcondition. 536 // Loop postcondition is the method postcondition.
444 return prt; 537 return prt;
445 } 538 }
446 539
471 max = cur; 564 max = cur;
472 max_prev = prev; 565 max_prev = prev;
473 max_ind = i; 566 max_ind = i;
474 max_occ = cur_occ; 567 max_occ = cur_occ;
475 } 568 }
476 prev = cur->next_addr(); 569 prev = cur->collision_list_next_addr();
477 cur = cur->next(); 570 cur = cur->collision_list_next();
478 } 571 }
479 i = i + _fine_eviction_stride; 572 i = i + _fine_eviction_stride;
480 if (i >= _n_fine_entries) i = i - _n_fine_entries; 573 if (i >= _n_fine_entries) i = i - _n_fine_entries;
481 } 574 }
482 575
501 _n_coarse_entries); 594 _n_coarse_entries);
502 } 595 }
503 } 596 }
504 597
505 // Unsplice. 598 // Unsplice.
506 *max_prev = max->next(); 599 *max_prev = max->collision_list_next();
507 Atomic::inc(&_n_coarsenings); 600 Atomic::inc(&_n_coarsenings);
508 _n_fine_entries--; 601 _n_fine_entries--;
509 return max; 602 return max;
510 } 603 }
511 604
532 // Now do the fine-grained maps. 625 // Now do the fine-grained maps.
533 for (size_t i = 0; i < _max_fine_entries; i++) { 626 for (size_t i = 0; i < _max_fine_entries; i++) {
534 PerRegionTable* cur = _fine_grain_regions[i]; 627 PerRegionTable* cur = _fine_grain_regions[i];
535 PerRegionTable** prev = &_fine_grain_regions[i]; 628 PerRegionTable** prev = &_fine_grain_regions[i];
536 while (cur != NULL) { 629 while (cur != NULL) {
537 PerRegionTable* nxt = cur->next(); 630 PerRegionTable* nxt = cur->collision_list_next();
538 // If the entire region is dead, eliminate. 631 // If the entire region is dead, eliminate.
539 if (G1RSScrubVerbose) { 632 if (G1RSScrubVerbose) {
540 gclog_or_tty->print_cr(" For other region %u:", 633 gclog_or_tty->print_cr(" For other region %u:",
541 cur->hr()->hrs_index()); 634 cur->hr()->hrs_index());
542 } 635 }
543 if (!region_bm->at((size_t) cur->hr()->hrs_index())) { 636 if (!region_bm->at((size_t) cur->hr()->hrs_index())) {
544 *prev = nxt; 637 *prev = nxt;
545 cur->set_next(NULL); 638 cur->set_collision_list_next(NULL);
546 _n_fine_entries--; 639 _n_fine_entries--;
547 if (G1RSScrubVerbose) { 640 if (G1RSScrubVerbose) {
548 gclog_or_tty->print_cr(" deleted via region map."); 641 gclog_or_tty->print_cr(" deleted via region map.");
549 } 642 }
643 unlink_from_all(cur);
550 PerRegionTable::free(cur); 644 PerRegionTable::free(cur);
551 } else { 645 } else {
552 // Do fine-grain elimination. 646 // Do fine-grain elimination.
553 if (G1RSScrubVerbose) { 647 if (G1RSScrubVerbose) {
554 gclog_or_tty->print(" occ: before = %4d.", cur->occupied()); 648 gclog_or_tty->print(" occ: before = %4d.", cur->occupied());
558 gclog_or_tty->print_cr(" after = %4d.", cur->occupied()); 652 gclog_or_tty->print_cr(" after = %4d.", cur->occupied());
559 } 653 }
560 // Did that empty the table completely? 654 // Did that empty the table completely?
561 if (cur->occupied() == 0) { 655 if (cur->occupied() == 0) {
562 *prev = nxt; 656 *prev = nxt;
563 cur->set_next(NULL); 657 cur->set_collision_list_next(NULL);
564 _n_fine_entries--; 658 _n_fine_entries--;
659 unlink_from_all(cur);
565 PerRegionTable::free(cur); 660 PerRegionTable::free(cur);
566 } else { 661 } else {
567 prev = cur->next_addr(); 662 prev = cur->collision_list_next_addr();
568 } 663 }
569 } 664 }
570 cur = nxt; 665 cur = nxt;
571 } 666 }
572 } 667 }
585 return sum; 680 return sum;
586 } 681 }
587 682
588 size_t OtherRegionsTable::occ_fine() const { 683 size_t OtherRegionsTable::occ_fine() const {
589 size_t sum = 0; 684 size_t sum = 0;
590 for (size_t i = 0; i < _max_fine_entries; i++) { 685
591 PerRegionTable* cur = _fine_grain_regions[i]; 686 size_t num = 0;
592 while (cur != NULL) { 687 PerRegionTable * cur = _first_all_fine_prts;
593 sum += cur->occupied(); 688 while (cur != NULL) {
594 cur = cur->next(); 689 sum += cur->occupied();
595 } 690 cur = cur->next();
596 } 691 num++;
692 }
693 guarantee(num == _n_fine_entries, "just checking");
597 return sum; 694 return sum;
598 } 695 }
599 696
600 size_t OtherRegionsTable::occ_coarse() const { 697 size_t OtherRegionsTable::occ_coarse() const {
601 return (_n_coarse_entries * HeapRegion::CardsPerRegion); 698 return (_n_coarse_entries * HeapRegion::CardsPerRegion);
607 704
608 size_t OtherRegionsTable::mem_size() const { 705 size_t OtherRegionsTable::mem_size() const {
609 // Cast away const in this case. 706 // Cast away const in this case.
610 MutexLockerEx x((Mutex*)&_m, Mutex::_no_safepoint_check_flag); 707 MutexLockerEx x((Mutex*)&_m, Mutex::_no_safepoint_check_flag);
611 size_t sum = 0; 708 size_t sum = 0;
612 for (size_t i = 0; i < _max_fine_entries; i++) { 709 PerRegionTable * cur = _first_all_fine_prts;
613 PerRegionTable* cur = _fine_grain_regions[i]; 710 while (cur != NULL) {
614 while (cur != NULL) { 711 sum += cur->mem_size();
615 sum += cur->mem_size(); 712 cur = cur->next();
616 cur = cur->next();
617 }
618 } 713 }
619 sum += (sizeof(PerRegionTable*) * _max_fine_entries); 714 sum += (sizeof(PerRegionTable*) * _max_fine_entries);
620 sum += (_coarse_map.size_in_words() * HeapWordSize); 715 sum += (_coarse_map.size_in_words() * HeapWordSize);
621 sum += (_sparse_table.mem_size()); 716 sum += (_sparse_table.mem_size());
622 sum += sizeof(*this) - sizeof(_sparse_table); // Avoid double counting above. 717 sum += sizeof(*this) - sizeof(_sparse_table); // Avoid double counting above.
630 size_t OtherRegionsTable::fl_mem_size() { 725 size_t OtherRegionsTable::fl_mem_size() {
631 return PerRegionTable::fl_mem_size(); 726 return PerRegionTable::fl_mem_size();
632 } 727 }
633 728
634 void OtherRegionsTable::clear_fcc() { 729 void OtherRegionsTable::clear_fcc() {
730 size_t hrs_idx = hr()->hrs_index();
635 for (int i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) { 731 for (int i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) {
636 _from_card_cache[i][hr()->hrs_index()] = -1; 732 _from_card_cache[i][hrs_idx] = -1;
637 } 733 }
638 } 734 }
639 735
640 void OtherRegionsTable::clear() { 736 void OtherRegionsTable::clear() {
641 MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag); 737 MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag);
642 for (size_t i = 0; i < _max_fine_entries; i++) { 738 // if there are no entries, skip this step
643 PerRegionTable* cur = _fine_grain_regions[i]; 739 if (_first_all_fine_prts != NULL) {
644 while (cur != NULL) { 740 guarantee(_first_all_fine_prts != NULL && _last_all_fine_prts != NULL, "just checking");
645 PerRegionTable* nxt = cur->next(); 741 PerRegionTable::bulk_free(_first_all_fine_prts, _last_all_fine_prts);
646 PerRegionTable::free(cur); 742 memset(_fine_grain_regions, 0, _max_fine_entries * sizeof(_fine_grain_regions[0]));
647 cur = nxt; 743 } else {
648 } 744 guarantee(_first_all_fine_prts == NULL && _last_all_fine_prts == NULL, "just checking");
649 _fine_grain_regions[i] = NULL; 745 }
650 } 746
747 _first_all_fine_prts = _last_all_fine_prts = NULL;
651 _sparse_table.clear(); 748 _sparse_table.clear();
652 _coarse_map.clear(); 749 _coarse_map.clear();
653 _n_fine_entries = 0; 750 _n_fine_entries = 0;
654 _n_coarse_entries = 0; 751 _n_coarse_entries = 0;
655 752
684 HeapRegion* hr) { 781 HeapRegion* hr) {
685 assert(0 <= ind && ind < _max_fine_entries, "Preconditions."); 782 assert(0 <= ind && ind < _max_fine_entries, "Preconditions.");
686 PerRegionTable** prev_addr = &_fine_grain_regions[ind]; 783 PerRegionTable** prev_addr = &_fine_grain_regions[ind];
687 PerRegionTable* prt = *prev_addr; 784 PerRegionTable* prt = *prev_addr;
688 while (prt != NULL && prt->hr() != hr) { 785 while (prt != NULL && prt->hr() != hr) {
689 prev_addr = prt->next_addr(); 786 prev_addr = prt->collision_list_next_addr();
690 prt = prt->next(); 787 prt = prt->collision_list_next();
691 } 788 }
692 if (prt != NULL) { 789 if (prt != NULL) {
693 assert(prt->hr() == hr, "Loop postcondition."); 790 assert(prt->hr() == hr, "Loop postcondition.");
694 *prev_addr = prt->next(); 791 *prev_addr = prt->collision_list_next();
792 unlink_from_all(prt);
695 PerRegionTable::free(prt); 793 PerRegionTable::free(prt);
696 _n_fine_entries--; 794 _n_fine_entries--;
697 return true; 795 return true;
698 } else { 796 } else {
699 return false; 797 return false;
791 while (iter.has_next(card_index)) { 889 while (iter.has_next(card_index)) {
792 HeapWord* card_start = 890 HeapWord* card_start =
793 G1CollectedHeap::heap()->bot_shared()->address_for_index(card_index); 891 G1CollectedHeap::heap()->bot_shared()->address_for_index(card_index);
794 gclog_or_tty->print_cr(" Card " PTR_FORMAT, card_start); 892 gclog_or_tty->print_cr(" Card " PTR_FORMAT, card_start);
795 } 893 }
796
797 if (iter.n_yielded() != occupied()) { 894 if (iter.n_yielded() != occupied()) {
798 gclog_or_tty->print_cr("Yielded disagrees with occupied:"); 895 gclog_or_tty->print_cr("Yielded disagrees with occupied:");
799 gclog_or_tty->print_cr(" %6d yielded (%6d coarse, %6d fine).", 896 gclog_or_tty->print_cr(" %6d yielded (%6d coarse, %6d fine).",
800 iter.n_yielded(), 897 iter.n_yielded(),
801 iter.n_yielded_coarse(), iter.n_yielded_fine()); 898 iter.n_yielded_coarse(), iter.n_yielded_fine());
903 _fine_cur_prt->_bm.get_next_one_offset(_cur_region_cur_card + 1); 1000 _fine_cur_prt->_bm.get_next_one_offset(_cur_region_cur_card + 1);
904 } 1001 }
905 while (!fine_has_next()) { 1002 while (!fine_has_next()) {
906 if (_cur_region_cur_card == (size_t) HeapRegion::CardsPerRegion) { 1003 if (_cur_region_cur_card == (size_t) HeapRegion::CardsPerRegion) {
907 _cur_region_cur_card = 0; 1004 _cur_region_cur_card = 0;
908 _fine_cur_prt = _fine_cur_prt->next(); 1005 _fine_cur_prt = _fine_cur_prt->collision_list_next();
909 } 1006 }
910 if (_fine_cur_prt == NULL) { 1007 if (_fine_cur_prt == NULL) {
911 fine_find_next_non_null_prt(); 1008 fine_find_next_non_null_prt();
912 if (_fine_cur_prt == NULL) return false; 1009 if (_fine_cur_prt == NULL) return false;
913 } 1010 }