Mercurial > hg > truffle
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 |