Mercurial > hg > graal-compiler
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 } |