mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-16 17:14:41 +02:00
8067655: Clean up G1 remembered set oop iteration
Pass on the static type G1ParPushHeapRSClosure to allow oop_iterate devirtualization Reviewed-by: jmasa, kbarrett
This commit is contained in:
parent
12273757f7
commit
cc786b287d
7 changed files with 48 additions and 94 deletions
|
@ -4609,7 +4609,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,
|
||||
|
|
|
@ -821,7 +821,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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ G1RemSet::G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs)
|
|||
_prev_period_summary()
|
||||
{
|
||||
_seq_task = new SubTasksDone(NumSeqTasks);
|
||||
_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,14 +94,14 @@ 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);
|
||||
FREE_C_HEAP_ARRAY(G1ParPushHeapRSClosure*, _cset_rs_update_cl);
|
||||
}
|
||||
|
||||
class ScanRSClosure : public HeapRegionClosure {
|
||||
size_t _cards_done, _cards;
|
||||
G1CollectedHeap* _g1h;
|
||||
|
||||
OopsInHeapRegionClosure* _oc;
|
||||
G1ParPushHeapRSClosure* _oc;
|
||||
CodeBlobClosure* _code_root_cl;
|
||||
|
||||
G1BlockOffsetSharedArray* _bot_shared;
|
||||
|
@ -113,7 +113,7 @@ class ScanRSClosure : public HeapRegionClosure {
|
|||
bool _try_claimed;
|
||||
|
||||
public:
|
||||
ScanRSClosure(OopsInHeapRegionClosure* oc,
|
||||
ScanRSClosure(G1ParPushHeapRSClosure* oc,
|
||||
CodeBlobClosure* code_root_cl,
|
||||
uint worker_i) :
|
||||
_oc(oc),
|
||||
|
@ -135,8 +135,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);
|
||||
|
@ -231,7 +230,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();
|
||||
|
@ -301,7 +300,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
|
||||
|
@ -417,7 +416,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),
|
||||
|
@ -518,7 +517,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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -48,93 +48,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<class ClosureType>
|
||||
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;
|
||||
cur += 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;
|
||||
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);
|
||||
}
|
||||
|
||||
case OutOfRegionFilterKind: {
|
||||
FilterOutOfRegionClosure filt(_hr, _cl);
|
||||
bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue