comparison src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp @ 807:d44bdab1c03d

6843694: G1: assert(index < _vs.committed_size(),"bad index"), g1BlockOffsetTable.inline.hpp:55 Summary: For heaps larger than 32Gb, the number of heap regions overflows the data type used to hold the region index in the SparsePRT structure. Changed the region indexes, card indexes, and RSet hash table buckets to ints and added some size overflow guarantees. Reviewed-by: ysr, tonyp
author johnc
date Thu, 11 Jun 2009 17:19:33 -0700
parents 215f81b4d9b3
children df6caf649ff7
comparison
equal deleted inserted replaced
806:821269eca479 807:d44bdab1c03d
107 } 107 }
108 assert(fl == NULL, "Loop condition."); 108 assert(fl == NULL, "Loop condition.");
109 return new PerRegionTable(hr); 109 return new PerRegionTable(hr);
110 } 110 }
111 111
112 void add_card_work(short from_card, bool par) { 112 void add_card_work(CardIdx_t from_card, bool par) {
113 if (!_bm.at(from_card)) { 113 if (!_bm.at(from_card)) {
114 if (par) { 114 if (par) {
115 if (_bm.par_at_put(from_card, 1)) { 115 if (_bm.par_at_put(from_card, 1)) {
116 #if PRT_COUNT_OCCUPIED 116 #if PRT_COUNT_OCCUPIED
117 Atomic::inc(&_occupied); 117 Atomic::inc(&_occupied);
139 // If the test below fails, then this table was reused concurrently 139 // If the test below fails, then this table was reused concurrently
140 // with this operation. This is OK, since the old table was coarsened, 140 // with this operation. This is OK, since the old table was coarsened,
141 // and adding a bit to the new table is never incorrect. 141 // and adding a bit to the new table is never incorrect.
142 if (loc_hr->is_in_reserved(from)) { 142 if (loc_hr->is_in_reserved(from)) {
143 size_t hw_offset = pointer_delta((HeapWord*)from, loc_hr->bottom()); 143 size_t hw_offset = pointer_delta((HeapWord*)from, loc_hr->bottom());
144 size_t from_card = 144 CardIdx_t from_card = (CardIdx_t)
145 hw_offset >> 145 hw_offset >> (CardTableModRefBS::card_shift - LogHeapWordSize);
146 (CardTableModRefBS::card_shift - LogHeapWordSize); 146
147 147 assert(0 <= from_card && from_card < CardsPerRegion, "Must be in range.");
148 add_card_work((short) from_card, par); 148 add_card_work(from_card, par);
149 } 149 }
150 } 150 }
151 151
152 public: 152 public:
153 153
188 #if PRT_COUNT_OCCUPIED 188 #if PRT_COUNT_OCCUPIED
189 recount_occupied(); 189 recount_occupied();
190 #endif 190 #endif
191 } 191 }
192 192
193 void add_card(short from_card_index) { 193 void add_card(CardIdx_t from_card_index) {
194 add_card_work(from_card_index, /*parallel*/ true); 194 add_card_work(from_card_index, /*parallel*/ true);
195 } 195 }
196 196
197 void seq_add_card(short from_card_index) { 197 void seq_add_card(CardIdx_t from_card_index) {
198 add_card_work(from_card_index, /*parallel*/ false); 198 add_card_work(from_card_index, /*parallel*/ false);
199 } 199 }
200 200
201 // (Destructively) union the bitmap of the current table into the given 201 // (Destructively) union the bitmap of the current table into the given
202 // bitmap (which is assumed to be of the same size.) 202 // bitmap (which is assumed to be of the same size.)
602 _from_card_cache[tid][cur_hrs_ind] = from_card; 602 _from_card_cache[tid][cur_hrs_ind] = from_card;
603 } 603 }
604 604
605 // Note that this may be a continued H region. 605 // Note that this may be a continued H region.
606 HeapRegion* from_hr = _g1h->heap_region_containing_raw(from); 606 HeapRegion* from_hr = _g1h->heap_region_containing_raw(from);
607 size_t from_hrs_ind = (size_t)from_hr->hrs_index(); 607 RegionIdx_t from_hrs_ind = (RegionIdx_t) from_hr->hrs_index();
608 608
609 // If the region is already coarsened, return. 609 // If the region is already coarsened, return.
610 if (_coarse_map.at(from_hrs_ind)) { 610 if (_coarse_map.at(from_hrs_ind)) {
611 #if HRRS_VERBOSE 611 #if HRRS_VERBOSE
612 gclog_or_tty->print_cr(" coarse map hit."); 612 gclog_or_tty->print_cr(" coarse map hit.");
625 if (prt == NULL) { 625 if (prt == NULL) {
626 626
627 uintptr_t from_hr_bot_card_index = 627 uintptr_t from_hr_bot_card_index =
628 uintptr_t(from_hr->bottom()) 628 uintptr_t(from_hr->bottom())
629 >> CardTableModRefBS::card_shift; 629 >> CardTableModRefBS::card_shift;
630 int card_index = from_card - from_hr_bot_card_index; 630 CardIdx_t card_index = from_card - from_hr_bot_card_index;
631 assert(0 <= card_index && card_index < PosParPRT::CardsPerRegion, 631 assert(0 <= card_index && card_index < PosParPRT::CardsPerRegion,
632 "Must be in range."); 632 "Must be in range.");
633 if (G1HRRSUseSparseTable && 633 if (G1HRRSUseSparseTable &&
634 _sparse_table.add_card((short) from_hrs_ind, card_index)) { 634 _sparse_table.add_card(from_hrs_ind, card_index)) {
635 if (G1RecordHRRSOops) { 635 if (G1RecordHRRSOops) {
636 HeapRegionRemSet::record(hr(), from); 636 HeapRegionRemSet::record(hr(), from);
637 #if HRRS_VERBOSE 637 #if HRRS_VERBOSE
638 gclog_or_tty->print(" Added card " PTR_FORMAT " to region " 638 gclog_or_tty->print(" Added card " PTR_FORMAT " to region "
639 "[" PTR_FORMAT "...) for ref " PTR_FORMAT ".\n", 639 "[" PTR_FORMAT "...) for ref " PTR_FORMAT ".\n",
654 tid, from_hrs_ind, cur_hrs_ind); 654 tid, from_hrs_ind, cur_hrs_ind);
655 #endif 655 #endif
656 } 656 }
657 657
658 // Otherwise, transfer from sparse to fine-grain. 658 // Otherwise, transfer from sparse to fine-grain.
659 short cards[SparsePRTEntry::CardsPerEntry]; 659 CardIdx_t cards[SparsePRTEntry::CardsPerEntry];
660 if (G1HRRSUseSparseTable) { 660 if (G1HRRSUseSparseTable) {
661 bool res = _sparse_table.get_cards((short) from_hrs_ind, &cards[0]); 661 bool res = _sparse_table.get_cards(from_hrs_ind, &cards[0]);
662 assert(res, "There should have been an entry"); 662 assert(res, "There should have been an entry");
663 } 663 }
664 664
665 if (_n_fine_entries == _max_fine_entries) { 665 if (_n_fine_entries == _max_fine_entries) {
666 prt = delete_region_table(); 666 prt = delete_region_table();
677 _n_fine_entries++; 677 _n_fine_entries++;
678 678
679 // Add in the cards from the sparse table. 679 // Add in the cards from the sparse table.
680 if (G1HRRSUseSparseTable) { 680 if (G1HRRSUseSparseTable) {
681 for (int i = 0; i < SparsePRTEntry::CardsPerEntry; i++) { 681 for (int i = 0; i < SparsePRTEntry::CardsPerEntry; i++) {
682 short c = cards[i]; 682 CardIdx_t c = cards[i];
683 if (c != SparsePRTEntry::NullEntry) { 683 if (c != SparsePRTEntry::NullEntry) {
684 prt->add_card(c); 684 prt->add_card(c);
685 } 685 }
686 } 686 }
687 // Now we can delete the sparse entry. 687 // Now we can delete the sparse entry.
688 bool res = _sparse_table.delete_entry((short) from_hrs_ind); 688 bool res = _sparse_table.delete_entry(from_hrs_ind);
689 assert(res, "It should have been there."); 689 assert(res, "It should have been there.");
690 } 690 }
691 } 691 }
692 assert(prt != NULL && prt->hr() == from_hr, "consequence"); 692 assert(prt != NULL && prt->hr() == from_hr, "consequence");
693 } 693 }
1028 } 1028 }
1029 1029
1030 bool OtherRegionsTable::contains_reference_locked(oop* from) const { 1030 bool OtherRegionsTable::contains_reference_locked(oop* from) const {
1031 HeapRegion* hr = _g1h->heap_region_containing_raw(from); 1031 HeapRegion* hr = _g1h->heap_region_containing_raw(from);
1032 if (hr == NULL) return false; 1032 if (hr == NULL) return false;
1033 size_t hr_ind = hr->hrs_index(); 1033 RegionIdx_t hr_ind = (RegionIdx_t) hr->hrs_index();
1034 // Is this region in the coarse map? 1034 // Is this region in the coarse map?
1035 if (_coarse_map.at(hr_ind)) return true; 1035 if (_coarse_map.at(hr_ind)) return true;
1036 1036
1037 PosParPRT* prt = find_region_table(hr_ind & _mod_max_fine_entries_mask, 1037 PosParPRT* prt = find_region_table(hr_ind & _mod_max_fine_entries_mask,
1038 hr); 1038 hr);
1043 uintptr_t from_card = 1043 uintptr_t from_card =
1044 (uintptr_t(from) >> CardTableModRefBS::card_shift); 1044 (uintptr_t(from) >> CardTableModRefBS::card_shift);
1045 uintptr_t hr_bot_card_index = 1045 uintptr_t hr_bot_card_index =
1046 uintptr_t(hr->bottom()) >> CardTableModRefBS::card_shift; 1046 uintptr_t(hr->bottom()) >> CardTableModRefBS::card_shift;
1047 assert(from_card >= hr_bot_card_index, "Inv"); 1047 assert(from_card >= hr_bot_card_index, "Inv");
1048 int card_index = from_card - hr_bot_card_index; 1048 CardIdx_t card_index = from_card - hr_bot_card_index;
1049 return _sparse_table.contains_card((short)hr_ind, card_index); 1049 assert(0 <= card_index && card_index < PosParPRT::CardsPerRegion, "Must be in range.");
1050 return _sparse_table.contains_card(hr_ind, card_index);
1050 } 1051 }
1051 1052
1052 1053
1053 } 1054 }
1054 1055