# HG changeset patch # User tschatzl # Date 1496403921 -7200 # Node ID 69f8479862a2d9786a8eeca47b37ba94b1f60472 # Parent 14de3e5151a95855362ab5a56528458621f88c79 8162928: Micro-optimizations in scanning the remembered sets Reviewed-by: ehelin, kbarrett diff -r 14de3e5151a9 -r 69f8479862a2 hotspot/src/share/vm/gc/g1/g1RemSet.cpp --- a/hotspot/src/share/vm/gc/g1/g1RemSet.cpp Fri Jun 02 13:45:15 2017 +0200 +++ b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp Fri Jun 02 13:45:21 2017 +0200 @@ -305,13 +305,8 @@ _block_size = MAX2(G1RSetScanBlockSize, 1); } -void G1ScanRSClosure::scan_card(size_t index, HeapRegion *r) { - // Stack allocate the DirtyCardToOopClosure instance - HeapRegionDCTOC cl(_g1h, r, _push_heap_cl, CardTableModRefBS::Precise); - - // Set the "from" region in the closure. - _push_heap_cl->set_region(r); - MemRegion card_region(_bot->address_for_index(index), BOTConstants::N_words); +void G1ScanRSClosure::scan_card(size_t index, HeapWord* card_start, HeapRegion *r) { + MemRegion card_region(card_start, BOTConstants::N_words); MemRegion pre_gc_allocated(r->bottom(), r->scan_top()); MemRegion mr = pre_gc_allocated.intersection(card_region); if (!mr.is_empty() && !_ct_bs->is_card_claimed(index)) { @@ -319,8 +314,9 @@ // but they're benign), which reduces the number of duplicate // scans (the rsets of the regions in the cset can intersect). _ct_bs->set_card_claimed(index); + _push_heap_cl->set_region(r); + r->oops_on_card_seq_iterate_careful(mr, _push_heap_cl); _cards_done++; - cl.do_MemRegion(mr); } } @@ -367,7 +363,7 @@ // If the card is dirty, then we will scan it during updateRS. if (!card_region->in_collection_set() && !_ct_bs->is_card_dirty(card_index)) { - scan_card(card_index, card_region); + scan_card(card_index, card_start, card_region); } } if (_scan_state->set_iter_complete(region_idx)) { diff -r 14de3e5151a9 -r 69f8479862a2 hotspot/src/share/vm/gc/g1/g1RemSet.hpp --- a/hotspot/src/share/vm/gc/g1/g1RemSet.hpp Fri Jun 02 13:45:15 2017 +0200 +++ b/hotspot/src/share/vm/gc/g1/g1RemSet.hpp Fri Jun 02 13:45:21 2017 +0200 @@ -197,7 +197,7 @@ uint _worker_i; size_t _block_size; - void scan_card(size_t index, HeapRegion *r); + void scan_card(size_t index, HeapWord* card_start, HeapRegion *r); void scan_strong_code_roots(HeapRegion* r); public: G1ScanRSClosure(G1RemSetScanState* scan_state, diff -r 14de3e5151a9 -r 69f8479862a2 hotspot/src/share/vm/gc/g1/heapRegion.cpp --- a/hotspot/src/share/vm/gc/g1/heapRegion.cpp Fri Jun 02 13:45:15 2017 +0200 +++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp Fri Jun 02 13:45:21 2017 +0200 @@ -48,56 +48,6 @@ size_t HeapRegion::GrainWords = 0; size_t HeapRegion::CardsPerRegion = 0; -HeapRegionDCTOC::HeapRegionDCTOC(G1CollectedHeap* g1, - HeapRegion* hr, - G1ParPushHeapRSClosure* cl, - CardTableModRefBS::PrecisionStyle precision) : - DirtyCardToOopClosure(hr, cl, precision, NULL), - _hr(hr), _rs_scan(cl), _g1(g1) { } - -void HeapRegionDCTOC::walk_mem_region(MemRegion mr, - HeapWord* bottom, - HeapWord* top) { - G1CollectedHeap* g1h = _g1; - size_t oop_size; - HeapWord* cur = bottom; - - // Start filtering what we add to the remembered set. If the object is - // not considered dead, either because it is marked (in the mark bitmap) - // or it was allocated after marking finished, then we add it. Otherwise - // we can safely ignore the object. - if (!g1h->is_obj_dead(oop(cur))) { - oop_size = oop(cur)->oop_iterate_size(_rs_scan, mr); - } else { - oop_size = _hr->block_size(cur); - } - - cur += oop_size; - - if (cur < top) { - oop cur_oop = oop(cur); - oop_size = _hr->block_size(cur); - HeapWord* next_obj = cur + oop_size; - while (next_obj < top) { - // Keep filtering the remembered set. - if (!g1h->is_obj_dead(cur_oop)) { - // Bottom lies entirely below top, so we can call the - // non-memRegion version of oop_iterate below. - cur_oop->oop_iterate(_rs_scan); - } - cur = next_obj; - cur_oop = oop(cur); - oop_size = _hr->block_size(cur); - next_obj = cur + oop_size; - } - - // Last object. Need to do dead-obj filtering here too. - if (!g1h->is_obj_dead(oop(cur))) { - oop(cur)->oop_iterate(_rs_scan, mr); - } - } -} - size_t HeapRegion::max_region_size() { return HeapRegionBounds::max_size(); } diff -r 14de3e5151a9 -r 69f8479862a2 hotspot/src/share/vm/gc/g1/heapRegion.hpp --- a/hotspot/src/share/vm/gc/g1/heapRegion.hpp Fri Jun 02 13:45:15 2017 +0200 +++ b/hotspot/src/share/vm/gc/g1/heapRegion.hpp Fri Jun 02 13:45:21 2017 +0200 @@ -72,32 +72,6 @@ // sentinel value for hrm_index #define G1_NO_HRM_INDEX ((uint) -1) -// A dirty card to oop closure for heap regions. It -// knows how to get the G1 heap and how to use the bitmap -// in the concurrent marker used by G1 to filter remembered -// sets. - -class HeapRegionDCTOC : public DirtyCardToOopClosure { -private: - HeapRegion* _hr; - G1ParPushHeapRSClosure* _rs_scan; - G1CollectedHeap* _g1; - - // Walk the given memory region from bottom to (actual) top - // looking for objects and applying the oop closure (_cl) to - // them. The base implementation of this treats the area as - // blocks, where a block may or may not be an object. Sub- - // classes should override this to provide more accurate - // or possibly more efficient walking. - void walk_mem_region(MemRegion mr, HeapWord* bottom, HeapWord* top); - -public: - HeapRegionDCTOC(G1CollectedHeap* g1, - HeapRegion* hr, - G1ParPushHeapRSClosure* cl, - CardTableModRefBS::PrecisionStyle precision); -}; - // The complicating factor is that BlockOffsetTable diverged // significantly, and we need functionality that is only in the G1 version. // So I copied that code, which led to an alternate G1 version of