comparison src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp @ 20213:ff7b317d2af8

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
author tschatzl
date Mon, 21 Jul 2014 09:40:19 +0200
parents 78bbf4d43a14
children 8cc89a893545
comparison
equal deleted inserted replaced
20212:d7e2d5f2846b 20213:ff7b317d2af8
1046 1046
1047 size_t HeapRegionRemSet::strong_code_roots_mem_size() { 1047 size_t HeapRegionRemSet::strong_code_roots_mem_size() {
1048 return _code_roots.mem_size(); 1048 return _code_roots.mem_size();
1049 } 1049 }
1050 1050
1051 //-------------------- Iteration --------------------
1052
1053 HeapRegionRemSetIterator:: HeapRegionRemSetIterator(HeapRegionRemSet* hrrs) : 1051 HeapRegionRemSetIterator:: HeapRegionRemSetIterator(HeapRegionRemSet* hrrs) :
1054 _hrrs(hrrs), 1052 _hrrs(hrrs),
1055 _g1h(G1CollectedHeap::heap()), 1053 _g1h(G1CollectedHeap::heap()),
1056 _coarse_map(&hrrs->_other_regions._coarse_map), 1054 _coarse_map(&hrrs->_other_regions._coarse_map),
1057 _fine_grain_regions(hrrs->_other_regions._fine_grain_regions),
1058 _bosa(hrrs->bosa()), 1055 _bosa(hrrs->bosa()),
1059 _is(Sparse), 1056 _is(Sparse),
1060 // Set these values so that we increment to the first region. 1057 // Set these values so that we increment to the first region.
1061 _coarse_cur_region_index(-1), 1058 _coarse_cur_region_index(-1),
1062 _coarse_cur_region_cur_card(HeapRegion::CardsPerRegion-1), 1059 _coarse_cur_region_cur_card(HeapRegion::CardsPerRegion-1),
1063 _cur_region_cur_card(0), 1060 _cur_card_in_prt(HeapRegion::CardsPerRegion),
1064 _fine_array_index(-1),
1065 _fine_cur_prt(NULL), 1061 _fine_cur_prt(NULL),
1066 _n_yielded_coarse(0), 1062 _n_yielded_coarse(0),
1067 _n_yielded_fine(0), 1063 _n_yielded_fine(0),
1068 _n_yielded_sparse(0), 1064 _n_yielded_sparse(0),
1069 _sparse_iter(&hrrs->_other_regions._sparse_table) {} 1065 _sparse_iter(&hrrs->_other_regions._sparse_table) {}
1091 // If we didn't return false above, then we can yield a card. 1087 // If we didn't return false above, then we can yield a card.
1092 card_index = _cur_region_card_offset + _coarse_cur_region_cur_card; 1088 card_index = _cur_region_card_offset + _coarse_cur_region_cur_card;
1093 return true; 1089 return true;
1094 } 1090 }
1095 1091
1096 void HeapRegionRemSetIterator::fine_find_next_non_null_prt() {
1097 // Otherwise, find the next bucket list in the array.
1098 _fine_array_index++;
1099 while (_fine_array_index < (int) OtherRegionsTable::_max_fine_entries) {
1100 _fine_cur_prt = _fine_grain_regions[_fine_array_index];
1101 if (_fine_cur_prt != NULL) return;
1102 else _fine_array_index++;
1103 }
1104 assert(_fine_cur_prt == NULL, "Loop post");
1105 }
1106
1107 bool HeapRegionRemSetIterator::fine_has_next(size_t& card_index) { 1092 bool HeapRegionRemSetIterator::fine_has_next(size_t& card_index) {
1108 if (fine_has_next()) { 1093 if (fine_has_next()) {
1109 _cur_region_cur_card = 1094 _cur_card_in_prt =
1110 _fine_cur_prt->_bm.get_next_one_offset(_cur_region_cur_card + 1); 1095 _fine_cur_prt->_bm.get_next_one_offset(_cur_card_in_prt + 1);
1111 } 1096 }
1112 while (!fine_has_next()) { 1097 if (_cur_card_in_prt == HeapRegion::CardsPerRegion) {
1113 if (_cur_region_cur_card == (size_t) HeapRegion::CardsPerRegion) { 1098 // _fine_cur_prt may still be NULL in case if there are not PRTs at all for
1114 _cur_region_cur_card = 0; 1099 // the remembered set.
1115 _fine_cur_prt = _fine_cur_prt->collision_list_next(); 1100 if (_fine_cur_prt == NULL || _fine_cur_prt->next() == NULL) {
1116 } 1101 return false;
1117 if (_fine_cur_prt == NULL) { 1102 }
1118 fine_find_next_non_null_prt(); 1103 PerRegionTable* next_prt = _fine_cur_prt->next();
1119 if (_fine_cur_prt == NULL) return false; 1104 switch_to_prt(next_prt);
1120 } 1105 _cur_card_in_prt = _fine_cur_prt->_bm.get_next_one_offset(_cur_card_in_prt + 1);
1121 assert(_fine_cur_prt != NULL && _cur_region_cur_card == 0, 1106 }
1122 "inv."); 1107
1123 HeapWord* r_bot = 1108 card_index = _cur_region_card_offset + _cur_card_in_prt;
1124 _fine_cur_prt->hr()->bottom(); 1109 guarantee(_cur_card_in_prt < HeapRegion::CardsPerRegion,
1125 _cur_region_card_offset = _bosa->index_for(r_bot); 1110 err_msg("Card index "SIZE_FORMAT" must be within the region", _cur_card_in_prt));
1126 _cur_region_cur_card = _fine_cur_prt->_bm.get_next_one_offset(0);
1127 }
1128 assert(fine_has_next(), "Or else we exited the loop via the return.");
1129 card_index = _cur_region_card_offset + _cur_region_cur_card;
1130 return true; 1111 return true;
1131 } 1112 }
1132 1113
1133 bool HeapRegionRemSetIterator::fine_has_next() { 1114 bool HeapRegionRemSetIterator::fine_has_next() {
1134 return 1115 return _cur_card_in_prt != HeapRegion::CardsPerRegion;
1135 _fine_cur_prt != NULL && 1116 }
1136 _cur_region_cur_card < HeapRegion::CardsPerRegion; 1117
1118 void HeapRegionRemSetIterator::switch_to_prt(PerRegionTable* prt) {
1119 assert(prt != NULL, "Cannot switch to NULL prt");
1120 _fine_cur_prt = prt;
1121
1122 HeapWord* r_bot = _fine_cur_prt->hr()->bottom();
1123 _cur_region_card_offset = _bosa->index_for(r_bot);
1124
1125 // The bitmap scan for the PRT always scans from _cur_region_cur_card + 1.
1126 // To avoid special-casing this start case, and not miss the first bitmap
1127 // entry, initialize _cur_region_cur_card with -1 instead of 0.
1128 _cur_card_in_prt = (size_t)-1;
1137 } 1129 }
1138 1130
1139 bool HeapRegionRemSetIterator::has_next(size_t& card_index) { 1131 bool HeapRegionRemSetIterator::has_next(size_t& card_index) {
1140 switch (_is) { 1132 switch (_is) {
1141 case Sparse: 1133 case Sparse: {
1142 if (_sparse_iter.has_next(card_index)) { 1134 if (_sparse_iter.has_next(card_index)) {
1143 _n_yielded_sparse++; 1135 _n_yielded_sparse++;
1144 return true; 1136 return true;
1145 } 1137 }
1146 // Otherwise, deliberate fall-through 1138 // Otherwise, deliberate fall-through
1147 _is = Fine; 1139 _is = Fine;
1140 PerRegionTable* initial_fine_prt = _hrrs->_other_regions._first_all_fine_prts;
1141 if (initial_fine_prt != NULL) {
1142 switch_to_prt(_hrrs->_other_regions._first_all_fine_prts);
1143 }
1144 }
1148 case Fine: 1145 case Fine:
1149 if (fine_has_next(card_index)) { 1146 if (fine_has_next(card_index)) {
1150 _n_yielded_fine++; 1147 _n_yielded_fine++;
1151 return true; 1148 return true;
1152 } 1149 }