From 1a759a854ddcb2420e7005baa5f3d48d4607b9dd Mon Sep 17 00:00:00 2001 From: mgerdin Date: Mon, 8 Dec 2014 18:57:33 +0100 Subject: [PATCH] 8067655: Clean up G1 remembered set oop iteration Summary: Pass on the static type G1ParPushHeapRSClosure to allow oop_iterate devirtualization Reviewed-by: jmasa, kbarrett --- .../gc_implementation/g1/g1CollectedHeap.cpp | 2 +- .../gc_implementation/g1/g1CollectedHeap.hpp | 2 +- .../vm/gc_implementation/g1/g1OopClosures.hpp | 4 +- .../vm/gc_implementation/g1/g1RemSet.cpp | 19 ++-- .../vm/gc_implementation/g1/g1RemSet.hpp | 7 +- .../vm/gc_implementation/g1/heapRegion.cpp | 92 ++++++------------- .../vm/gc_implementation/g1/heapRegion.hpp | 18 +--- 7 files changed, 49 insertions(+), 95 deletions(-) diff --git a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index b7490f6b1..5fbd60abc 100644 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -4817,7 +4817,7 @@ void G1CollectedHeap:: g1_process_roots(OopClosure* scan_non_heap_roots, OopClosure* scan_non_heap_weak_roots, - OopsInHeapRegionClosure* scan_rs, + G1ParPushHeapRSClosure* scan_rs, CLDClosure* scan_strong_clds, CLDClosure* scan_weak_clds, CodeBlobClosure* scan_strong_code, diff --git a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp index 6aaa9dd5f..c6dca0077 100644 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp @@ -822,7 +822,7 @@ protected: // In the sequential case this param will be ignored. void g1_process_roots(OopClosure* scan_non_heap_roots, OopClosure* scan_non_heap_weak_roots, - OopsInHeapRegionClosure* scan_rs, + G1ParPushHeapRSClosure* scan_rs, CLDClosure* scan_strong_clds, CLDClosure* scan_weak_clds, CodeBlobClosure* scan_strong_code, diff --git a/src/share/vm/gc_implementation/g1/g1OopClosures.hpp b/src/share/vm/gc_implementation/g1/g1OopClosures.hpp index 79f8b52f6..961da5e1a 100644 --- a/src/share/vm/gc_implementation/g1/g1OopClosures.hpp +++ b/src/share/vm/gc_implementation/g1/g1OopClosures.hpp @@ -239,14 +239,14 @@ class G1UpdateRSOrPushRefOopClosure: public ExtendedOopClosure { G1CollectedHeap* _g1; G1RemSet* _g1_rem_set; HeapRegion* _from; - OopsInHeapRegionClosure* _push_ref_cl; + G1ParPushHeapRSClosure* _push_ref_cl; bool _record_refs_into_cset; uint _worker_i; public: G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h, G1RemSet* rs, - OopsInHeapRegionClosure* push_ref_cl, + G1ParPushHeapRSClosure* push_ref_cl, bool record_refs_into_cset, uint worker_i = 0); diff --git a/src/share/vm/gc_implementation/g1/g1RemSet.cpp b/src/share/vm/gc_implementation/g1/g1RemSet.cpp index b28fd2376..a72308d57 100644 --- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp +++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp @@ -80,7 +80,7 @@ G1RemSet::G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs) { _seq_task = new SubTasksDone(NumSeqTasks); guarantee(n_workers() > 0, "There should be some workers"); - _cset_rs_update_cl = NEW_C_HEAP_ARRAY(OopsInHeapRegionClosure*, n_workers(), mtGC); + _cset_rs_update_cl = NEW_C_HEAP_ARRAY(G1ParPushHeapRSClosure*, n_workers(), mtGC); for (uint i = 0; i < n_workers(); i++) { _cset_rs_update_cl[i] = NULL; } @@ -94,7 +94,7 @@ G1RemSet::~G1RemSet() { for (uint i = 0; i < n_workers(); i++) { assert(_cset_rs_update_cl[i] == NULL, "it should be"); } - FREE_C_HEAP_ARRAY(OopsInHeapRegionClosure*, _cset_rs_update_cl, mtGC); + FREE_C_HEAP_ARRAY(G1ParPushHeapRSClosure*, _cset_rs_update_cl, mtGC); } void CountNonCleanMemRegionClosure::do_MemRegion(MemRegion mr) { @@ -108,7 +108,7 @@ class ScanRSClosure : public HeapRegionClosure { size_t _cards_done, _cards; G1CollectedHeap* _g1h; - OopsInHeapRegionClosure* _oc; + G1ParPushHeapRSClosure* _oc; CodeBlobClosure* _code_root_cl; G1BlockOffsetSharedArray* _bot_shared; @@ -120,7 +120,7 @@ class ScanRSClosure : public HeapRegionClosure { bool _try_claimed; public: - ScanRSClosure(OopsInHeapRegionClosure* oc, + ScanRSClosure(G1ParPushHeapRSClosure* oc, CodeBlobClosure* code_root_cl, uint worker_i) : _oc(oc), @@ -142,8 +142,7 @@ public: void scanCard(size_t index, HeapRegion *r) { // Stack allocate the DirtyCardToOopClosure instance HeapRegionDCTOC cl(_g1h, r, _oc, - CardTableModRefBS::Precise, - HeapRegionDCTOC::IntoCSFilterKind); + CardTableModRefBS::Precise); // Set the "from" region in the closure. _oc->set_region(r); @@ -240,7 +239,7 @@ public: size_t cards_looked_up() { return _cards;} }; -void G1RemSet::scanRS(OopsInHeapRegionClosure* oc, +void G1RemSet::scanRS(G1ParPushHeapRSClosure* oc, CodeBlobClosure* code_root_cl, uint worker_i) { double rs_time_start = os::elapsedTime(); @@ -319,7 +318,7 @@ void G1RemSet::cleanupHRRS() { HeapRegionRemSet::cleanup(); } -void G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc, +void G1RemSet::oops_into_collection_set_do(G1ParPushHeapRSClosure* oc, CodeBlobClosure* code_root_cl, uint worker_i) { #if CARD_REPEAT_HISTO @@ -461,7 +460,7 @@ G1Mux2Closure::G1Mux2Closure(OopClosure *c1, OopClosure *c2) : G1UpdateRSOrPushRefOopClosure:: G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h, G1RemSet* rs, - OopsInHeapRegionClosure* push_ref_cl, + G1ParPushHeapRSClosure* push_ref_cl, bool record_refs_into_cset, uint worker_i) : _g1(g1h), _g1_rem_set(rs), _from(NULL), @@ -562,7 +561,7 @@ bool G1RemSet::refine_card(jbyte* card_ptr, uint worker_i, ct_freq_note_card(_ct_bs->index_for(start)); #endif - OopsInHeapRegionClosure* oops_in_heap_closure = NULL; + G1ParPushHeapRSClosure* oops_in_heap_closure = NULL; if (check_for_refs_into_cset) { // ConcurrentG1RefineThreads have worker numbers larger than what // _cset_rs_update_cl[] is set up to handle. But those threads should diff --git a/src/share/vm/gc_implementation/g1/g1RemSet.hpp b/src/share/vm/gc_implementation/g1/g1RemSet.hpp index 5a629fad2..6a63fd345 100644 --- a/src/share/vm/gc_implementation/g1/g1RemSet.hpp +++ b/src/share/vm/gc_implementation/g1/g1RemSet.hpp @@ -33,6 +33,7 @@ class G1CollectedHeap; class CardTableModRefBarrierSet; class ConcurrentG1Refine; +class G1ParPushHeapRSClosure; // A G1RemSet in which each heap region has a rem set that records the // external heap references into it. Uses a mod ref bs to track updates, @@ -68,7 +69,7 @@ protected: // Used for caching the closure that is responsible for scanning // references into the collection set. - OopsInHeapRegionClosure** _cset_rs_update_cl; + G1ParPushHeapRSClosure** _cset_rs_update_cl; // Print the given summary info virtual void print_summary_info(G1RemSetSummary * summary, const char * header = NULL); @@ -95,7 +96,7 @@ public: // partitioning the work to be done. It should be the same as // the "i" passed to the calling thread's work(i) function. // In the sequential case this param will be ignored. - void oops_into_collection_set_do(OopsInHeapRegionClosure* blk, + void oops_into_collection_set_do(G1ParPushHeapRSClosure* blk, CodeBlobClosure* code_root_cl, uint worker_i); @@ -107,7 +108,7 @@ public: void prepare_for_oops_into_collection_set_do(); void cleanup_after_oops_into_collection_set_do(); - void scanRS(OopsInHeapRegionClosure* oc, + void scanRS(G1ParPushHeapRSClosure* oc, CodeBlobClosure* code_root_cl, uint worker_i); diff --git a/src/share/vm/gc_implementation/g1/heapRegion.cpp b/src/share/vm/gc_implementation/g1/heapRegion.cpp index 3a7251b56..dda946dbf 100644 --- a/src/share/vm/gc_implementation/g1/heapRegion.cpp +++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp @@ -47,93 +47,55 @@ size_t HeapRegion::GrainWords = 0; size_t HeapRegion::CardsPerRegion = 0; HeapRegionDCTOC::HeapRegionDCTOC(G1CollectedHeap* g1, - HeapRegion* hr, ExtendedOopClosure* cl, - CardTableModRefBS::PrecisionStyle precision, - FilterKind fk) : + HeapRegion* hr, + G1ParPushHeapRSClosure* cl, + CardTableModRefBS::PrecisionStyle precision) : DirtyCardToOopClosure(hr, cl, precision, NULL), - _hr(hr), _fk(fk), _g1(g1) { } + _hr(hr), _rs_scan(cl), _g1(g1) { } FilterOutOfRegionClosure::FilterOutOfRegionClosure(HeapRegion* r, OopClosure* oc) : _r_bottom(r->bottom()), _r_end(r->end()), _oc(oc) { } -template -HeapWord* walk_mem_region_loop(ClosureType* cl, G1CollectedHeap* g1h, - HeapRegion* hr, - HeapWord* cur, HeapWord* top) { - oop cur_oop = oop(cur); - size_t 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, hr)) { - // Bottom lies entirely below top, so we can call the - // non-memRegion version of oop_iterate below. - cur_oop->oop_iterate(cl); - } - cur = next_obj; - cur_oop = oop(cur); - oop_size = hr->block_size(cur); - next_obj = cur + oop_size; - } - return cur; -} - void HeapRegionDCTOC::walk_mem_region(MemRegion mr, HeapWord* bottom, HeapWord* top) { G1CollectedHeap* g1h = _g1; size_t oop_size; - ExtendedOopClosure* cl2 = NULL; - - FilterIntoCSClosure intoCSFilt(this, g1h, _cl); - FilterOutOfRegionClosure outOfRegionFilt(_hr, _cl); - - switch (_fk) { - case NoFilterKind: cl2 = _cl; break; - case IntoCSFilterKind: cl2 = &intoCSFilt; break; - case OutOfRegionFilterKind: cl2 = &outOfRegionFilt; break; - default: ShouldNotReachHere(); - } + 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(bottom), _hr)) { - oop_size = oop(bottom)->oop_iterate(cl2, mr); + if (!g1h->is_obj_dead(oop(cur), _hr)) { + oop_size = oop(cur)->oop_iterate(_rs_scan, mr); } else { - oop_size = _hr->block_size(bottom); + oop_size = _hr->block_size(cur); } - bottom += oop_size; - - if (bottom < top) { - // We replicate the loop below for several kinds of possible filters. - switch (_fk) { - case NoFilterKind: - bottom = walk_mem_region_loop(_cl, g1h, _hr, bottom, top); - break; - - case IntoCSFilterKind: { - FilterIntoCSClosure filt(this, g1h, _cl); - bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top); - break; - } - - case OutOfRegionFilterKind: { - FilterOutOfRegionClosure filt(_hr, _cl); - bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top); - break; - } - - default: - ShouldNotReachHere(); + 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, _hr)) { + // 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(bottom), _hr)) { - oop(bottom)->oop_iterate(cl2, mr); + if (!g1h->is_obj_dead(oop(cur), _hr)) { + oop(cur)->oop_iterate(_rs_scan, mr); } } } diff --git a/src/share/vm/gc_implementation/g1/heapRegion.hpp b/src/share/vm/gc_implementation/g1/heapRegion.hpp index 16c0d719e..572ada5eb 100644 --- a/src/share/vm/gc_implementation/g1/heapRegion.hpp +++ b/src/share/vm/gc_implementation/g1/heapRegion.hpp @@ -67,17 +67,9 @@ class nmethod; // sets. class HeapRegionDCTOC : public DirtyCardToOopClosure { -public: - // Specification of possible DirtyCardToOopClosure filtering. - enum FilterKind { - NoFilterKind, - IntoCSFilterKind, - OutOfRegionFilterKind - }; - -protected: +private: HeapRegion* _hr; - FilterKind _fk; + G1ParPushHeapRSClosure* _rs_scan; G1CollectedHeap* _g1; // Walk the given memory region from bottom to (actual) top @@ -90,9 +82,9 @@ protected: public: HeapRegionDCTOC(G1CollectedHeap* g1, - HeapRegion* hr, ExtendedOopClosure* cl, - CardTableModRefBS::PrecisionStyle precision, - FilterKind fk); + HeapRegion* hr, + G1ParPushHeapRSClosure* cl, + CardTableModRefBS::PrecisionStyle precision); }; // The complicating factor is that BlockOffsetTable diverged -- GitLab