1.1 --- a/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Mon Jul 21 09:40:19 2014 +0200 1.2 +++ b/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Mon Jul 21 09:40:19 2014 +0200 1.3 @@ -1048,20 +1048,16 @@ 1.4 return _code_roots.mem_size(); 1.5 } 1.6 1.7 -//-------------------- Iteration -------------------- 1.8 - 1.9 HeapRegionRemSetIterator:: HeapRegionRemSetIterator(HeapRegionRemSet* hrrs) : 1.10 _hrrs(hrrs), 1.11 _g1h(G1CollectedHeap::heap()), 1.12 _coarse_map(&hrrs->_other_regions._coarse_map), 1.13 - _fine_grain_regions(hrrs->_other_regions._fine_grain_regions), 1.14 _bosa(hrrs->bosa()), 1.15 _is(Sparse), 1.16 // Set these values so that we increment to the first region. 1.17 _coarse_cur_region_index(-1), 1.18 _coarse_cur_region_cur_card(HeapRegion::CardsPerRegion-1), 1.19 - _cur_region_cur_card(0), 1.20 - _fine_array_index(-1), 1.21 + _cur_card_in_prt(HeapRegion::CardsPerRegion), 1.22 _fine_cur_prt(NULL), 1.23 _n_yielded_coarse(0), 1.24 _n_yielded_fine(0), 1.25 @@ -1093,58 +1089,59 @@ 1.26 return true; 1.27 } 1.28 1.29 -void HeapRegionRemSetIterator::fine_find_next_non_null_prt() { 1.30 - // Otherwise, find the next bucket list in the array. 1.31 - _fine_array_index++; 1.32 - while (_fine_array_index < (int) OtherRegionsTable::_max_fine_entries) { 1.33 - _fine_cur_prt = _fine_grain_regions[_fine_array_index]; 1.34 - if (_fine_cur_prt != NULL) return; 1.35 - else _fine_array_index++; 1.36 - } 1.37 - assert(_fine_cur_prt == NULL, "Loop post"); 1.38 -} 1.39 - 1.40 bool HeapRegionRemSetIterator::fine_has_next(size_t& card_index) { 1.41 if (fine_has_next()) { 1.42 - _cur_region_cur_card = 1.43 - _fine_cur_prt->_bm.get_next_one_offset(_cur_region_cur_card + 1); 1.44 + _cur_card_in_prt = 1.45 + _fine_cur_prt->_bm.get_next_one_offset(_cur_card_in_prt + 1); 1.46 } 1.47 - while (!fine_has_next()) { 1.48 - if (_cur_region_cur_card == (size_t) HeapRegion::CardsPerRegion) { 1.49 - _cur_region_cur_card = 0; 1.50 - _fine_cur_prt = _fine_cur_prt->collision_list_next(); 1.51 + if (_cur_card_in_prt == HeapRegion::CardsPerRegion) { 1.52 + // _fine_cur_prt may still be NULL in case if there are not PRTs at all for 1.53 + // the remembered set. 1.54 + if (_fine_cur_prt == NULL || _fine_cur_prt->next() == NULL) { 1.55 + return false; 1.56 } 1.57 - if (_fine_cur_prt == NULL) { 1.58 - fine_find_next_non_null_prt(); 1.59 - if (_fine_cur_prt == NULL) return false; 1.60 - } 1.61 - assert(_fine_cur_prt != NULL && _cur_region_cur_card == 0, 1.62 - "inv."); 1.63 - HeapWord* r_bot = 1.64 - _fine_cur_prt->hr()->bottom(); 1.65 - _cur_region_card_offset = _bosa->index_for(r_bot); 1.66 - _cur_region_cur_card = _fine_cur_prt->_bm.get_next_one_offset(0); 1.67 + PerRegionTable* next_prt = _fine_cur_prt->next(); 1.68 + switch_to_prt(next_prt); 1.69 + _cur_card_in_prt = _fine_cur_prt->_bm.get_next_one_offset(_cur_card_in_prt + 1); 1.70 } 1.71 - assert(fine_has_next(), "Or else we exited the loop via the return."); 1.72 - card_index = _cur_region_card_offset + _cur_region_cur_card; 1.73 + 1.74 + card_index = _cur_region_card_offset + _cur_card_in_prt; 1.75 + guarantee(_cur_card_in_prt < HeapRegion::CardsPerRegion, 1.76 + err_msg("Card index "SIZE_FORMAT" must be within the region", _cur_card_in_prt)); 1.77 return true; 1.78 } 1.79 1.80 bool HeapRegionRemSetIterator::fine_has_next() { 1.81 - return 1.82 - _fine_cur_prt != NULL && 1.83 - _cur_region_cur_card < HeapRegion::CardsPerRegion; 1.84 + return _cur_card_in_prt != HeapRegion::CardsPerRegion; 1.85 +} 1.86 + 1.87 +void HeapRegionRemSetIterator::switch_to_prt(PerRegionTable* prt) { 1.88 + assert(prt != NULL, "Cannot switch to NULL prt"); 1.89 + _fine_cur_prt = prt; 1.90 + 1.91 + HeapWord* r_bot = _fine_cur_prt->hr()->bottom(); 1.92 + _cur_region_card_offset = _bosa->index_for(r_bot); 1.93 + 1.94 + // The bitmap scan for the PRT always scans from _cur_region_cur_card + 1. 1.95 + // To avoid special-casing this start case, and not miss the first bitmap 1.96 + // entry, initialize _cur_region_cur_card with -1 instead of 0. 1.97 + _cur_card_in_prt = (size_t)-1; 1.98 } 1.99 1.100 bool HeapRegionRemSetIterator::has_next(size_t& card_index) { 1.101 switch (_is) { 1.102 - case Sparse: 1.103 + case Sparse: { 1.104 if (_sparse_iter.has_next(card_index)) { 1.105 _n_yielded_sparse++; 1.106 return true; 1.107 } 1.108 // Otherwise, deliberate fall-through 1.109 _is = Fine; 1.110 + PerRegionTable* initial_fine_prt = _hrrs->_other_regions._first_all_fine_prts; 1.111 + if (initial_fine_prt != NULL) { 1.112 + switch_to_prt(_hrrs->_other_regions._first_all_fine_prts); 1.113 + } 1.114 + } 1.115 case Fine: 1.116 if (fine_has_next(card_index)) { 1.117 _n_yielded_fine++;