提交 6e9c0cf3 编写于 作者: T tschatzl

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
上级 a1d9fed7
...@@ -1048,20 +1048,16 @@ size_t HeapRegionRemSet::strong_code_roots_mem_size() { ...@@ -1048,20 +1048,16 @@ size_t HeapRegionRemSet::strong_code_roots_mem_size() {
return _code_roots.mem_size(); return _code_roots.mem_size();
} }
//-------------------- Iteration --------------------
HeapRegionRemSetIterator:: HeapRegionRemSetIterator(HeapRegionRemSet* hrrs) : HeapRegionRemSetIterator:: HeapRegionRemSetIterator(HeapRegionRemSet* hrrs) :
_hrrs(hrrs), _hrrs(hrrs),
_g1h(G1CollectedHeap::heap()), _g1h(G1CollectedHeap::heap()),
_coarse_map(&hrrs->_other_regions._coarse_map), _coarse_map(&hrrs->_other_regions._coarse_map),
_fine_grain_regions(hrrs->_other_regions._fine_grain_regions),
_bosa(hrrs->bosa()), _bosa(hrrs->bosa()),
_is(Sparse), _is(Sparse),
// Set these values so that we increment to the first region. // Set these values so that we increment to the first region.
_coarse_cur_region_index(-1), _coarse_cur_region_index(-1),
_coarse_cur_region_cur_card(HeapRegion::CardsPerRegion-1), _coarse_cur_region_cur_card(HeapRegion::CardsPerRegion-1),
_cur_region_cur_card(0), _cur_card_in_prt(HeapRegion::CardsPerRegion),
_fine_array_index(-1),
_fine_cur_prt(NULL), _fine_cur_prt(NULL),
_n_yielded_coarse(0), _n_yielded_coarse(0),
_n_yielded_fine(0), _n_yielded_fine(0),
...@@ -1093,58 +1089,59 @@ bool HeapRegionRemSetIterator::coarse_has_next(size_t& card_index) { ...@@ -1093,58 +1089,59 @@ bool HeapRegionRemSetIterator::coarse_has_next(size_t& card_index) {
return true; return true;
} }
void HeapRegionRemSetIterator::fine_find_next_non_null_prt() {
// Otherwise, find the next bucket list in the array.
_fine_array_index++;
while (_fine_array_index < (int) OtherRegionsTable::_max_fine_entries) {
_fine_cur_prt = _fine_grain_regions[_fine_array_index];
if (_fine_cur_prt != NULL) return;
else _fine_array_index++;
}
assert(_fine_cur_prt == NULL, "Loop post");
}
bool HeapRegionRemSetIterator::fine_has_next(size_t& card_index) { bool HeapRegionRemSetIterator::fine_has_next(size_t& card_index) {
if (fine_has_next()) { if (fine_has_next()) {
_cur_region_cur_card = _cur_card_in_prt =
_fine_cur_prt->_bm.get_next_one_offset(_cur_region_cur_card + 1); _fine_cur_prt->_bm.get_next_one_offset(_cur_card_in_prt + 1);
} }
while (!fine_has_next()) { if (_cur_card_in_prt == HeapRegion::CardsPerRegion) {
if (_cur_region_cur_card == (size_t) HeapRegion::CardsPerRegion) { // _fine_cur_prt may still be NULL in case if there are not PRTs at all for
_cur_region_cur_card = 0; // the remembered set.
_fine_cur_prt = _fine_cur_prt->collision_list_next(); if (_fine_cur_prt == NULL || _fine_cur_prt->next() == NULL) {
} return false;
if (_fine_cur_prt == NULL) {
fine_find_next_non_null_prt();
if (_fine_cur_prt == NULL) return false;
} }
assert(_fine_cur_prt != NULL && _cur_region_cur_card == 0, PerRegionTable* next_prt = _fine_cur_prt->next();
"inv."); switch_to_prt(next_prt);
HeapWord* r_bot = _cur_card_in_prt = _fine_cur_prt->_bm.get_next_one_offset(_cur_card_in_prt + 1);
_fine_cur_prt->hr()->bottom();
_cur_region_card_offset = _bosa->index_for(r_bot);
_cur_region_cur_card = _fine_cur_prt->_bm.get_next_one_offset(0);
} }
assert(fine_has_next(), "Or else we exited the loop via the return.");
card_index = _cur_region_card_offset + _cur_region_cur_card; card_index = _cur_region_card_offset + _cur_card_in_prt;
guarantee(_cur_card_in_prt < HeapRegion::CardsPerRegion,
err_msg("Card index "SIZE_FORMAT" must be within the region", _cur_card_in_prt));
return true; return true;
} }
bool HeapRegionRemSetIterator::fine_has_next() { bool HeapRegionRemSetIterator::fine_has_next() {
return return _cur_card_in_prt != HeapRegion::CardsPerRegion;
_fine_cur_prt != NULL && }
_cur_region_cur_card < HeapRegion::CardsPerRegion;
void HeapRegionRemSetIterator::switch_to_prt(PerRegionTable* prt) {
assert(prt != NULL, "Cannot switch to NULL prt");
_fine_cur_prt = prt;
HeapWord* r_bot = _fine_cur_prt->hr()->bottom();
_cur_region_card_offset = _bosa->index_for(r_bot);
// The bitmap scan for the PRT always scans from _cur_region_cur_card + 1.
// To avoid special-casing this start case, and not miss the first bitmap
// entry, initialize _cur_region_cur_card with -1 instead of 0.
_cur_card_in_prt = (size_t)-1;
} }
bool HeapRegionRemSetIterator::has_next(size_t& card_index) { bool HeapRegionRemSetIterator::has_next(size_t& card_index) {
switch (_is) { switch (_is) {
case Sparse: case Sparse: {
if (_sparse_iter.has_next(card_index)) { if (_sparse_iter.has_next(card_index)) {
_n_yielded_sparse++; _n_yielded_sparse++;
return true; return true;
} }
// Otherwise, deliberate fall-through // Otherwise, deliberate fall-through
_is = Fine; _is = Fine;
PerRegionTable* initial_fine_prt = _hrrs->_other_regions._first_all_fine_prts;
if (initial_fine_prt != NULL) {
switch_to_prt(_hrrs->_other_regions._first_all_fine_prts);
}
}
case Fine: case Fine:
if (fine_has_next(card_index)) { if (fine_has_next(card_index)) {
_n_yielded_fine++; _n_yielded_fine++;
......
...@@ -432,26 +432,24 @@ public: ...@@ -432,26 +432,24 @@ public:
}; };
class HeapRegionRemSetIterator : public StackObj { class HeapRegionRemSetIterator : public StackObj {
private:
// The region RSet over which we're iterating. // The region RSet over which we are iterating.
HeapRegionRemSet* _hrrs; HeapRegionRemSet* _hrrs;
// Local caching of HRRS fields. // Local caching of HRRS fields.
const BitMap* _coarse_map; const BitMap* _coarse_map;
PerRegionTable** _fine_grain_regions;
G1BlockOffsetSharedArray* _bosa; G1BlockOffsetSharedArray* _bosa;
G1CollectedHeap* _g1h; G1CollectedHeap* _g1h;
// The number yielded since initialization. // The number of cards yielded since initialization.
size_t _n_yielded_fine; size_t _n_yielded_fine;
size_t _n_yielded_coarse; size_t _n_yielded_coarse;
size_t _n_yielded_sparse; size_t _n_yielded_sparse;
// Indicates what granularity of table that we're currently iterating over. // Indicates what granularity of table that we are currently iterating over.
// We start iterating over the sparse table, progress to the fine grain // We start iterating over the sparse table, progress to the fine grain
// table, and then finish with the coarse table. // table, and then finish with the coarse table.
// See HeapRegionRemSetIterator::has_next().
enum IterState { enum IterState {
Sparse, Sparse,
Fine, Fine,
...@@ -459,38 +457,30 @@ class HeapRegionRemSetIterator : public StackObj { ...@@ -459,38 +457,30 @@ class HeapRegionRemSetIterator : public StackObj {
}; };
IterState _is; IterState _is;
// In both kinds of iteration, heap offset of first card of current // For both Coarse and Fine remembered set iteration this contains the
// region. // first card number of the heap region we currently iterate over.
size_t _cur_region_card_offset; size_t _cur_region_card_offset;
// Card offset within cur region.
size_t _cur_region_cur_card;
// Coarse table iteration fields: // Current region index for the Coarse remembered set iteration.
// Current region index;
int _coarse_cur_region_index; int _coarse_cur_region_index;
size_t _coarse_cur_region_cur_card; size_t _coarse_cur_region_cur_card;
bool coarse_has_next(size_t& card_index); bool coarse_has_next(size_t& card_index);
// Fine table iteration fields: // The PRT we are currently iterating over.
// Index of bucket-list we're working on.
int _fine_array_index;
// Per Region Table we're doing within current bucket list.
PerRegionTable* _fine_cur_prt; PerRegionTable* _fine_cur_prt;
// Card offset within the current PRT.
size_t _cur_card_in_prt;
/* SparsePRT::*/ SparsePRTIter _sparse_iter; // Update internal variables when switching to the given PRT.
void switch_to_prt(PerRegionTable* prt);
void fine_find_next_non_null_prt();
bool fine_has_next(); bool fine_has_next();
bool fine_has_next(size_t& card_index); bool fine_has_next(size_t& card_index);
public: // The Sparse remembered set iterator.
// We require an iterator to be initialized before use, so the SparsePRTIter _sparse_iter;
// constructor does little.
public:
HeapRegionRemSetIterator(HeapRegionRemSet* hrrs); HeapRegionRemSetIterator(HeapRegionRemSet* hrrs);
// If there remains one or more cards to be yielded, returns true and // If there remains one or more cards to be yielded, returns true and
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册