8037344: Use the "next" field to iterate over fine remembered instead of using the hash table

Mon, 21 Jul 2014 09:40:19 +0200

author
tschatzl
date
Mon, 21 Jul 2014 09:40:19 +0200
changeset 6927
ff7b317d2af8
parent 6926
d7e2d5f2846b
child 6928
8cc89a893545

8037344: Use the "next" field to iterate over fine remembered instead of using the hash table
Summary: After changes to the PerRegionTable where all these PRTs are linked together in an additional field, simplify iterating over all PRTs by using these links instead of walki
Reviewed-by: mgerdin, jwilhelm, brutisso

src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp file | annotate | diff | comparison | revisions
src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp file | annotate | diff | comparison | revisions
     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++;
     2.1 --- a/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp	Mon Jul 21 09:40:19 2014 +0200
     2.2 +++ b/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp	Mon Jul 21 09:40:19 2014 +0200
     2.3 @@ -432,26 +432,24 @@
     2.4  };
     2.5  
     2.6  class HeapRegionRemSetIterator : public StackObj {
     2.7 -
     2.8 -  // The region RSet over which we're iterating.
     2.9 + private:
    2.10 +  // The region RSet over which we are iterating.
    2.11    HeapRegionRemSet* _hrrs;
    2.12  
    2.13    // Local caching of HRRS fields.
    2.14    const BitMap*             _coarse_map;
    2.15 -  PerRegionTable**          _fine_grain_regions;
    2.16  
    2.17    G1BlockOffsetSharedArray* _bosa;
    2.18    G1CollectedHeap*          _g1h;
    2.19  
    2.20 -  // The number yielded since initialization.
    2.21 +  // The number of cards yielded since initialization.
    2.22    size_t _n_yielded_fine;
    2.23    size_t _n_yielded_coarse;
    2.24    size_t _n_yielded_sparse;
    2.25  
    2.26 -  // Indicates what granularity of table that we're currently iterating over.
    2.27 +  // Indicates what granularity of table that we are currently iterating over.
    2.28    // We start iterating over the sparse table, progress to the fine grain
    2.29    // table, and then finish with the coarse table.
    2.30 -  // See HeapRegionRemSetIterator::has_next().
    2.31    enum IterState {
    2.32      Sparse,
    2.33      Fine,
    2.34 @@ -459,38 +457,30 @@
    2.35    };
    2.36    IterState _is;
    2.37  
    2.38 -  // In both kinds of iteration, heap offset of first card of current
    2.39 -  // region.
    2.40 +  // For both Coarse and Fine remembered set iteration this contains the
    2.41 +  // first card number of the heap region we currently iterate over.
    2.42    size_t _cur_region_card_offset;
    2.43 -  // Card offset within cur region.
    2.44 -  size_t _cur_region_cur_card;
    2.45  
    2.46 -  // Coarse table iteration fields:
    2.47 -
    2.48 -  // Current region index;
    2.49 +  // Current region index for the Coarse remembered set iteration.
    2.50    int    _coarse_cur_region_index;
    2.51    size_t _coarse_cur_region_cur_card;
    2.52  
    2.53    bool coarse_has_next(size_t& card_index);
    2.54  
    2.55 -  // Fine table iteration fields:
    2.56 +  // The PRT we are currently iterating over.
    2.57 +  PerRegionTable* _fine_cur_prt;
    2.58 +  // Card offset within the current PRT.
    2.59 +  size_t _cur_card_in_prt;
    2.60  
    2.61 -  // Index of bucket-list we're working on.
    2.62 -  int _fine_array_index;
    2.63 -
    2.64 -  // Per Region Table we're doing within current bucket list.
    2.65 -  PerRegionTable* _fine_cur_prt;
    2.66 -
    2.67 -  /* SparsePRT::*/ SparsePRTIter _sparse_iter;
    2.68 -
    2.69 -  void fine_find_next_non_null_prt();
    2.70 -
    2.71 +  // Update internal variables when switching to the given PRT.
    2.72 +  void switch_to_prt(PerRegionTable* prt);
    2.73    bool fine_has_next();
    2.74    bool fine_has_next(size_t& card_index);
    2.75  
    2.76 -public:
    2.77 -  // We require an iterator to be initialized before use, so the
    2.78 -  // constructor does little.
    2.79 +  // The Sparse remembered set iterator.
    2.80 +  SparsePRTIter _sparse_iter;
    2.81 +
    2.82 + public:
    2.83    HeapRegionRemSetIterator(HeapRegionRemSet* hrrs);
    2.84  
    2.85    // If there remains one or more cards to be yielded, returns true and

mercurial