Mon, 08 Dec 2014 18:57:33 +0100
8067655: Clean up G1 remembered set oop iteration
Summary: Pass on the static type G1ParPushHeapRSClosure to allow oop_iterate devirtualization
Reviewed-by: jmasa, kbarrett
1.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Jun 18 20:18:58 2015 +0300 1.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Mon Dec 08 18:57:33 2014 +0100 1.3 @@ -4817,7 +4817,7 @@ 1.4 G1CollectedHeap:: 1.5 g1_process_roots(OopClosure* scan_non_heap_roots, 1.6 OopClosure* scan_non_heap_weak_roots, 1.7 - OopsInHeapRegionClosure* scan_rs, 1.8 + G1ParPushHeapRSClosure* scan_rs, 1.9 CLDClosure* scan_strong_clds, 1.10 CLDClosure* scan_weak_clds, 1.11 CodeBlobClosure* scan_strong_code,
2.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Jun 18 20:18:58 2015 +0300 2.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Mon Dec 08 18:57:33 2014 +0100 2.3 @@ -822,7 +822,7 @@ 2.4 // In the sequential case this param will be ignored. 2.5 void g1_process_roots(OopClosure* scan_non_heap_roots, 2.6 OopClosure* scan_non_heap_weak_roots, 2.7 - OopsInHeapRegionClosure* scan_rs, 2.8 + G1ParPushHeapRSClosure* scan_rs, 2.9 CLDClosure* scan_strong_clds, 2.10 CLDClosure* scan_weak_clds, 2.11 CodeBlobClosure* scan_strong_code,
3.1 --- a/src/share/vm/gc_implementation/g1/g1OopClosures.hpp Thu Jun 18 20:18:58 2015 +0300 3.2 +++ b/src/share/vm/gc_implementation/g1/g1OopClosures.hpp Mon Dec 08 18:57:33 2014 +0100 3.3 @@ -239,14 +239,14 @@ 3.4 G1CollectedHeap* _g1; 3.5 G1RemSet* _g1_rem_set; 3.6 HeapRegion* _from; 3.7 - OopsInHeapRegionClosure* _push_ref_cl; 3.8 + G1ParPushHeapRSClosure* _push_ref_cl; 3.9 bool _record_refs_into_cset; 3.10 uint _worker_i; 3.11 3.12 public: 3.13 G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h, 3.14 G1RemSet* rs, 3.15 - OopsInHeapRegionClosure* push_ref_cl, 3.16 + G1ParPushHeapRSClosure* push_ref_cl, 3.17 bool record_refs_into_cset, 3.18 uint worker_i = 0); 3.19
4.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp Thu Jun 18 20:18:58 2015 +0300 4.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp Mon Dec 08 18:57:33 2014 +0100 4.3 @@ -80,7 +80,7 @@ 4.4 { 4.5 _seq_task = new SubTasksDone(NumSeqTasks); 4.6 guarantee(n_workers() > 0, "There should be some workers"); 4.7 - _cset_rs_update_cl = NEW_C_HEAP_ARRAY(OopsInHeapRegionClosure*, n_workers(), mtGC); 4.8 + _cset_rs_update_cl = NEW_C_HEAP_ARRAY(G1ParPushHeapRSClosure*, n_workers(), mtGC); 4.9 for (uint i = 0; i < n_workers(); i++) { 4.10 _cset_rs_update_cl[i] = NULL; 4.11 } 4.12 @@ -94,7 +94,7 @@ 4.13 for (uint i = 0; i < n_workers(); i++) { 4.14 assert(_cset_rs_update_cl[i] == NULL, "it should be"); 4.15 } 4.16 - FREE_C_HEAP_ARRAY(OopsInHeapRegionClosure*, _cset_rs_update_cl, mtGC); 4.17 + FREE_C_HEAP_ARRAY(G1ParPushHeapRSClosure*, _cset_rs_update_cl, mtGC); 4.18 } 4.19 4.20 void CountNonCleanMemRegionClosure::do_MemRegion(MemRegion mr) { 4.21 @@ -108,7 +108,7 @@ 4.22 size_t _cards_done, _cards; 4.23 G1CollectedHeap* _g1h; 4.24 4.25 - OopsInHeapRegionClosure* _oc; 4.26 + G1ParPushHeapRSClosure* _oc; 4.27 CodeBlobClosure* _code_root_cl; 4.28 4.29 G1BlockOffsetSharedArray* _bot_shared; 4.30 @@ -120,7 +120,7 @@ 4.31 bool _try_claimed; 4.32 4.33 public: 4.34 - ScanRSClosure(OopsInHeapRegionClosure* oc, 4.35 + ScanRSClosure(G1ParPushHeapRSClosure* oc, 4.36 CodeBlobClosure* code_root_cl, 4.37 uint worker_i) : 4.38 _oc(oc), 4.39 @@ -142,8 +142,7 @@ 4.40 void scanCard(size_t index, HeapRegion *r) { 4.41 // Stack allocate the DirtyCardToOopClosure instance 4.42 HeapRegionDCTOC cl(_g1h, r, _oc, 4.43 - CardTableModRefBS::Precise, 4.44 - HeapRegionDCTOC::IntoCSFilterKind); 4.45 + CardTableModRefBS::Precise); 4.46 4.47 // Set the "from" region in the closure. 4.48 _oc->set_region(r); 4.49 @@ -240,7 +239,7 @@ 4.50 size_t cards_looked_up() { return _cards;} 4.51 }; 4.52 4.53 -void G1RemSet::scanRS(OopsInHeapRegionClosure* oc, 4.54 +void G1RemSet::scanRS(G1ParPushHeapRSClosure* oc, 4.55 CodeBlobClosure* code_root_cl, 4.56 uint worker_i) { 4.57 double rs_time_start = os::elapsedTime(); 4.58 @@ -319,7 +318,7 @@ 4.59 HeapRegionRemSet::cleanup(); 4.60 } 4.61 4.62 -void G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc, 4.63 +void G1RemSet::oops_into_collection_set_do(G1ParPushHeapRSClosure* oc, 4.64 CodeBlobClosure* code_root_cl, 4.65 uint worker_i) { 4.66 #if CARD_REPEAT_HISTO 4.67 @@ -461,7 +460,7 @@ 4.68 G1UpdateRSOrPushRefOopClosure:: 4.69 G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h, 4.70 G1RemSet* rs, 4.71 - OopsInHeapRegionClosure* push_ref_cl, 4.72 + G1ParPushHeapRSClosure* push_ref_cl, 4.73 bool record_refs_into_cset, 4.74 uint worker_i) : 4.75 _g1(g1h), _g1_rem_set(rs), _from(NULL), 4.76 @@ -562,7 +561,7 @@ 4.77 ct_freq_note_card(_ct_bs->index_for(start)); 4.78 #endif 4.79 4.80 - OopsInHeapRegionClosure* oops_in_heap_closure = NULL; 4.81 + G1ParPushHeapRSClosure* oops_in_heap_closure = NULL; 4.82 if (check_for_refs_into_cset) { 4.83 // ConcurrentG1RefineThreads have worker numbers larger than what 4.84 // _cset_rs_update_cl[] is set up to handle. But those threads should
5.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.hpp Thu Jun 18 20:18:58 2015 +0300 5.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.hpp Mon Dec 08 18:57:33 2014 +0100 5.3 @@ -33,6 +33,7 @@ 5.4 class G1CollectedHeap; 5.5 class CardTableModRefBarrierSet; 5.6 class ConcurrentG1Refine; 5.7 +class G1ParPushHeapRSClosure; 5.8 5.9 // A G1RemSet in which each heap region has a rem set that records the 5.10 // external heap references into it. Uses a mod ref bs to track updates, 5.11 @@ -68,7 +69,7 @@ 5.12 5.13 // Used for caching the closure that is responsible for scanning 5.14 // references into the collection set. 5.15 - OopsInHeapRegionClosure** _cset_rs_update_cl; 5.16 + G1ParPushHeapRSClosure** _cset_rs_update_cl; 5.17 5.18 // Print the given summary info 5.19 virtual void print_summary_info(G1RemSetSummary * summary, const char * header = NULL); 5.20 @@ -95,7 +96,7 @@ 5.21 // partitioning the work to be done. It should be the same as 5.22 // the "i" passed to the calling thread's work(i) function. 5.23 // In the sequential case this param will be ignored. 5.24 - void oops_into_collection_set_do(OopsInHeapRegionClosure* blk, 5.25 + void oops_into_collection_set_do(G1ParPushHeapRSClosure* blk, 5.26 CodeBlobClosure* code_root_cl, 5.27 uint worker_i); 5.28 5.29 @@ -107,7 +108,7 @@ 5.30 void prepare_for_oops_into_collection_set_do(); 5.31 void cleanup_after_oops_into_collection_set_do(); 5.32 5.33 - void scanRS(OopsInHeapRegionClosure* oc, 5.34 + void scanRS(G1ParPushHeapRSClosure* oc, 5.35 CodeBlobClosure* code_root_cl, 5.36 uint worker_i); 5.37
6.1 --- a/src/share/vm/gc_implementation/g1/heapRegion.cpp Thu Jun 18 20:18:58 2015 +0300 6.2 +++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp Mon Dec 08 18:57:33 2014 +0100 6.3 @@ -47,93 +47,55 @@ 6.4 size_t HeapRegion::CardsPerRegion = 0; 6.5 6.6 HeapRegionDCTOC::HeapRegionDCTOC(G1CollectedHeap* g1, 6.7 - HeapRegion* hr, ExtendedOopClosure* cl, 6.8 - CardTableModRefBS::PrecisionStyle precision, 6.9 - FilterKind fk) : 6.10 + HeapRegion* hr, 6.11 + G1ParPushHeapRSClosure* cl, 6.12 + CardTableModRefBS::PrecisionStyle precision) : 6.13 DirtyCardToOopClosure(hr, cl, precision, NULL), 6.14 - _hr(hr), _fk(fk), _g1(g1) { } 6.15 + _hr(hr), _rs_scan(cl), _g1(g1) { } 6.16 6.17 FilterOutOfRegionClosure::FilterOutOfRegionClosure(HeapRegion* r, 6.18 OopClosure* oc) : 6.19 _r_bottom(r->bottom()), _r_end(r->end()), _oc(oc) { } 6.20 6.21 -template<class ClosureType> 6.22 -HeapWord* walk_mem_region_loop(ClosureType* cl, G1CollectedHeap* g1h, 6.23 - HeapRegion* hr, 6.24 - HeapWord* cur, HeapWord* top) { 6.25 - oop cur_oop = oop(cur); 6.26 - size_t oop_size = hr->block_size(cur); 6.27 - HeapWord* next_obj = cur + oop_size; 6.28 - while (next_obj < top) { 6.29 - // Keep filtering the remembered set. 6.30 - if (!g1h->is_obj_dead(cur_oop, hr)) { 6.31 - // Bottom lies entirely below top, so we can call the 6.32 - // non-memRegion version of oop_iterate below. 6.33 - cur_oop->oop_iterate(cl); 6.34 - } 6.35 - cur = next_obj; 6.36 - cur_oop = oop(cur); 6.37 - oop_size = hr->block_size(cur); 6.38 - next_obj = cur + oop_size; 6.39 - } 6.40 - return cur; 6.41 -} 6.42 - 6.43 void HeapRegionDCTOC::walk_mem_region(MemRegion mr, 6.44 HeapWord* bottom, 6.45 HeapWord* top) { 6.46 G1CollectedHeap* g1h = _g1; 6.47 size_t oop_size; 6.48 - ExtendedOopClosure* cl2 = NULL; 6.49 - 6.50 - FilterIntoCSClosure intoCSFilt(this, g1h, _cl); 6.51 - FilterOutOfRegionClosure outOfRegionFilt(_hr, _cl); 6.52 - 6.53 - switch (_fk) { 6.54 - case NoFilterKind: cl2 = _cl; break; 6.55 - case IntoCSFilterKind: cl2 = &intoCSFilt; break; 6.56 - case OutOfRegionFilterKind: cl2 = &outOfRegionFilt; break; 6.57 - default: ShouldNotReachHere(); 6.58 - } 6.59 + HeapWord* cur = bottom; 6.60 6.61 // Start filtering what we add to the remembered set. If the object is 6.62 // not considered dead, either because it is marked (in the mark bitmap) 6.63 // or it was allocated after marking finished, then we add it. Otherwise 6.64 // we can safely ignore the object. 6.65 - if (!g1h->is_obj_dead(oop(bottom), _hr)) { 6.66 - oop_size = oop(bottom)->oop_iterate(cl2, mr); 6.67 + if (!g1h->is_obj_dead(oop(cur), _hr)) { 6.68 + oop_size = oop(cur)->oop_iterate(_rs_scan, mr); 6.69 } else { 6.70 - oop_size = _hr->block_size(bottom); 6.71 + oop_size = _hr->block_size(cur); 6.72 } 6.73 6.74 - bottom += oop_size; 6.75 + cur += oop_size; 6.76 6.77 - if (bottom < top) { 6.78 - // We replicate the loop below for several kinds of possible filters. 6.79 - switch (_fk) { 6.80 - case NoFilterKind: 6.81 - bottom = walk_mem_region_loop(_cl, g1h, _hr, bottom, top); 6.82 - break; 6.83 - 6.84 - case IntoCSFilterKind: { 6.85 - FilterIntoCSClosure filt(this, g1h, _cl); 6.86 - bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top); 6.87 - break; 6.88 - } 6.89 - 6.90 - case OutOfRegionFilterKind: { 6.91 - FilterOutOfRegionClosure filt(_hr, _cl); 6.92 - bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top); 6.93 - break; 6.94 - } 6.95 - 6.96 - default: 6.97 - ShouldNotReachHere(); 6.98 + if (cur < top) { 6.99 + oop cur_oop = oop(cur); 6.100 + oop_size = _hr->block_size(cur); 6.101 + HeapWord* next_obj = cur + oop_size; 6.102 + while (next_obj < top) { 6.103 + // Keep filtering the remembered set. 6.104 + if (!g1h->is_obj_dead(cur_oop, _hr)) { 6.105 + // Bottom lies entirely below top, so we can call the 6.106 + // non-memRegion version of oop_iterate below. 6.107 + cur_oop->oop_iterate(_rs_scan); 6.108 + } 6.109 + cur = next_obj; 6.110 + cur_oop = oop(cur); 6.111 + oop_size = _hr->block_size(cur); 6.112 + next_obj = cur + oop_size; 6.113 } 6.114 6.115 // Last object. Need to do dead-obj filtering here too. 6.116 - if (!g1h->is_obj_dead(oop(bottom), _hr)) { 6.117 - oop(bottom)->oop_iterate(cl2, mr); 6.118 + if (!g1h->is_obj_dead(oop(cur), _hr)) { 6.119 + oop(cur)->oop_iterate(_rs_scan, mr); 6.120 } 6.121 } 6.122 }
7.1 --- a/src/share/vm/gc_implementation/g1/heapRegion.hpp Thu Jun 18 20:18:58 2015 +0300 7.2 +++ b/src/share/vm/gc_implementation/g1/heapRegion.hpp Mon Dec 08 18:57:33 2014 +0100 7.3 @@ -67,17 +67,9 @@ 7.4 // sets. 7.5 7.6 class HeapRegionDCTOC : public DirtyCardToOopClosure { 7.7 -public: 7.8 - // Specification of possible DirtyCardToOopClosure filtering. 7.9 - enum FilterKind { 7.10 - NoFilterKind, 7.11 - IntoCSFilterKind, 7.12 - OutOfRegionFilterKind 7.13 - }; 7.14 - 7.15 -protected: 7.16 +private: 7.17 HeapRegion* _hr; 7.18 - FilterKind _fk; 7.19 + G1ParPushHeapRSClosure* _rs_scan; 7.20 G1CollectedHeap* _g1; 7.21 7.22 // Walk the given memory region from bottom to (actual) top 7.23 @@ -90,9 +82,9 @@ 7.24 7.25 public: 7.26 HeapRegionDCTOC(G1CollectedHeap* g1, 7.27 - HeapRegion* hr, ExtendedOopClosure* cl, 7.28 - CardTableModRefBS::PrecisionStyle precision, 7.29 - FilterKind fk); 7.30 + HeapRegion* hr, 7.31 + G1ParPushHeapRSClosure* cl, 7.32 + CardTableModRefBS::PrecisionStyle precision); 7.33 }; 7.34 7.35 // The complicating factor is that BlockOffsetTable diverged