8297692: Avoid sending per-region GCPhaseParallel JFR events in G1ScanCollectionSetRegionClosure
Reviewed-by: iwalulya, ayang, sangheki
This commit is contained in:
parent
6e28cd3b79
commit
a73226b18e
@ -755,27 +755,71 @@ public:
|
||||
|
||||
// Heap region closure to be applied to all regions in the current collection set
|
||||
// increment to fix up non-card related roots.
|
||||
class G1ScanCollectionSetRegionClosure : public G1HeapRegionClosure {
|
||||
class G1ScanCodeRootsClosure : public G1HeapRegionClosure {
|
||||
G1ParScanThreadState* _pss;
|
||||
G1RemSetScanState* _scan_state;
|
||||
|
||||
G1GCPhaseTimes::GCParPhases _scan_phase;
|
||||
G1GCPhaseTimes::GCParPhases _code_roots_phase;
|
||||
|
||||
uint _worker_id;
|
||||
|
||||
size_t _code_roots_scanned;
|
||||
|
||||
public:
|
||||
G1ScanCodeRootsClosure(G1RemSetScanState* scan_state,
|
||||
G1ParScanThreadState* pss,
|
||||
uint worker_id) :
|
||||
_pss(pss),
|
||||
_scan_state(scan_state),
|
||||
_worker_id(worker_id),
|
||||
_code_roots_scanned(0) { }
|
||||
|
||||
bool do_heap_region(G1HeapRegion* r) {
|
||||
// Scan the code root list attached to the current region
|
||||
G1ScanAndCountNMethodClosure cl(_pss->closures()->weak_nmethods());
|
||||
r->code_roots_do(&cl);
|
||||
_code_roots_scanned += cl.count();
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t code_roots_scanned() const { return _code_roots_scanned; }
|
||||
};
|
||||
|
||||
void G1RemSet::scan_collection_set_code_roots(G1ParScanThreadState* pss,
|
||||
uint worker_id,
|
||||
G1GCPhaseTimes::GCParPhases coderoots_phase,
|
||||
G1GCPhaseTimes::GCParPhases objcopy_phase) {
|
||||
EventGCPhaseParallel event;
|
||||
|
||||
Tickspan code_root_scan_time;
|
||||
Tickspan code_root_trim_partially_time;
|
||||
G1EvacPhaseWithTrimTimeTracker timer(pss, code_root_scan_time, code_root_trim_partially_time);
|
||||
|
||||
G1GCPhaseTimes* p = _g1h->phase_times();
|
||||
|
||||
G1ScanCodeRootsClosure cl(_scan_state, pss, worker_id);
|
||||
// Code roots work distribution occurs inside the iteration method. So scan all collection
|
||||
// set regions for all threads.
|
||||
_g1h->collection_set_iterate_increment_from(&cl, worker_id);
|
||||
|
||||
p->record_or_add_time_secs(coderoots_phase, worker_id, code_root_scan_time.seconds());
|
||||
p->add_time_secs(objcopy_phase, worker_id, code_root_trim_partially_time.seconds());
|
||||
|
||||
p->record_or_add_thread_work_item(coderoots_phase, worker_id, cl.code_roots_scanned(), G1GCPhaseTimes::CodeRootsScannedNMethods);
|
||||
|
||||
event.commit(GCId::current(), worker_id, G1GCPhaseTimes::phase_name(coderoots_phase));
|
||||
}
|
||||
|
||||
class G1ScanOptionalRemSetRootsClosure : public G1HeapRegionClosure {
|
||||
G1ParScanThreadState* _pss;
|
||||
|
||||
uint _worker_id;
|
||||
|
||||
G1GCPhaseTimes::GCParPhases _scan_phase;
|
||||
|
||||
size_t _opt_roots_scanned;
|
||||
|
||||
size_t _opt_refs_scanned;
|
||||
size_t _opt_refs_memory_used;
|
||||
|
||||
Tickspan _code_root_scan_time;
|
||||
Tickspan _code_trim_partially_time;
|
||||
|
||||
Tickspan _rem_set_opt_root_scan_time;
|
||||
Tickspan _rem_set_opt_trim_partially_time;
|
||||
|
||||
void scan_opt_rem_set_roots(G1HeapRegion* r) {
|
||||
G1OopStarChunkedList* opt_rem_set_list = _pss->oops_into_optional_region(r);
|
||||
|
||||
@ -786,91 +830,57 @@ class G1ScanCollectionSetRegionClosure : public G1HeapRegionClosure {
|
||||
}
|
||||
|
||||
public:
|
||||
G1ScanCollectionSetRegionClosure(G1RemSetScanState* scan_state,
|
||||
G1ParScanThreadState* pss,
|
||||
G1ScanOptionalRemSetRootsClosure(G1ParScanThreadState* pss,
|
||||
uint worker_id,
|
||||
G1GCPhaseTimes::GCParPhases scan_phase,
|
||||
G1GCPhaseTimes::GCParPhases code_roots_phase) :
|
||||
G1GCPhaseTimes::GCParPhases scan_phase) :
|
||||
_pss(pss),
|
||||
_scan_state(scan_state),
|
||||
_scan_phase(scan_phase),
|
||||
_code_roots_phase(code_roots_phase),
|
||||
_worker_id(worker_id),
|
||||
_code_roots_scanned(0),
|
||||
_scan_phase(scan_phase),
|
||||
_opt_roots_scanned(0),
|
||||
_opt_refs_scanned(0),
|
||||
_opt_refs_memory_used(0),
|
||||
_code_root_scan_time(),
|
||||
_code_trim_partially_time(),
|
||||
_rem_set_opt_root_scan_time(),
|
||||
_rem_set_opt_trim_partially_time() { }
|
||||
_opt_refs_memory_used(0) { }
|
||||
|
||||
bool do_heap_region(G1HeapRegion* r) {
|
||||
// The individual references for the optional remembered set are per-worker, so we
|
||||
// always need to scan them.
|
||||
bool do_heap_region(G1HeapRegion* r) override {
|
||||
if (r->has_index_in_opt_cset()) {
|
||||
EventGCPhaseParallel event;
|
||||
G1EvacPhaseWithTrimTimeTracker timer(_pss, _rem_set_opt_root_scan_time, _rem_set_opt_trim_partially_time);
|
||||
scan_opt_rem_set_roots(r);
|
||||
|
||||
event.commit(GCId::current(), _worker_id, G1GCPhaseTimes::phase_name(_scan_phase));
|
||||
}
|
||||
|
||||
// Scan code root remembered sets.
|
||||
{
|
||||
EventGCPhaseParallel event;
|
||||
G1EvacPhaseWithTrimTimeTracker timer(_pss, _code_root_scan_time, _code_trim_partially_time);
|
||||
G1ScanAndCountNMethodClosure cl(_pss->closures()->weak_nmethods());
|
||||
|
||||
// Scan the code root list attached to the current region
|
||||
r->code_roots_do(&cl);
|
||||
|
||||
_code_roots_scanned += cl.count();
|
||||
|
||||
event.commit(GCId::current(), _worker_id, G1GCPhaseTimes::phase_name(_code_roots_phase));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Tickspan code_root_scan_time() const { return _code_root_scan_time; }
|
||||
Tickspan code_root_trim_partially_time() const { return _code_trim_partially_time; }
|
||||
|
||||
size_t code_roots_scanned() const { return _code_roots_scanned; }
|
||||
|
||||
Tickspan rem_set_opt_root_scan_time() const { return _rem_set_opt_root_scan_time; }
|
||||
Tickspan rem_set_opt_trim_partially_time() const { return _rem_set_opt_trim_partially_time; }
|
||||
|
||||
size_t opt_roots_scanned() const { return _opt_roots_scanned; }
|
||||
size_t opt_refs_scanned() const { return _opt_refs_scanned; }
|
||||
size_t opt_refs_memory_used() const { return _opt_refs_memory_used; }
|
||||
};
|
||||
|
||||
void G1RemSet::scan_collection_set_regions(G1ParScanThreadState* pss,
|
||||
void G1RemSet::scan_collection_set_optional_roots(G1ParScanThreadState* pss,
|
||||
uint worker_id,
|
||||
G1GCPhaseTimes::GCParPhases scan_phase,
|
||||
G1GCPhaseTimes::GCParPhases coderoots_phase,
|
||||
G1GCPhaseTimes::GCParPhases objcopy_phase) {
|
||||
G1ScanCollectionSetRegionClosure cl(_scan_state, pss, worker_id, scan_phase, coderoots_phase);
|
||||
_g1h->collection_set_iterate_increment_from(&cl, worker_id);
|
||||
assert(scan_phase == G1GCPhaseTimes::OptScanHR, "must be");
|
||||
|
||||
EventGCPhaseParallel event;
|
||||
|
||||
Tickspan rem_set_opt_root_scan_time;
|
||||
Tickspan rem_set_opt_trim_partially_time;
|
||||
G1EvacPhaseWithTrimTimeTracker timer(pss, rem_set_opt_root_scan_time, rem_set_opt_trim_partially_time);
|
||||
|
||||
G1GCPhaseTimes* p = _g1h->phase_times();
|
||||
|
||||
p->record_or_add_time_secs(scan_phase, worker_id, cl.rem_set_opt_root_scan_time().seconds());
|
||||
p->record_or_add_time_secs(scan_phase, worker_id, cl.rem_set_opt_trim_partially_time().seconds());
|
||||
G1ScanOptionalRemSetRootsClosure cl(pss, worker_id, scan_phase);
|
||||
// The individual references for the optional remembered set are per-worker, so every worker
|
||||
// always need to scan all regions (no claimer).
|
||||
_g1h->collection_set_iterate_increment_from(&cl, worker_id);
|
||||
|
||||
p->record_or_add_time_secs(coderoots_phase, worker_id, cl.code_root_scan_time().seconds());
|
||||
p->record_or_add_thread_work_item(coderoots_phase, worker_id, cl.code_roots_scanned(), G1GCPhaseTimes::CodeRootsScannedNMethods);
|
||||
p->record_or_add_time_secs(scan_phase, worker_id, rem_set_opt_root_scan_time.seconds());
|
||||
p->record_or_add_time_secs(objcopy_phase, worker_id, rem_set_opt_trim_partially_time.seconds());
|
||||
|
||||
p->add_time_secs(objcopy_phase, worker_id, cl.code_root_trim_partially_time().seconds());
|
||||
|
||||
// At this time we record some metrics only for the evacuations after the initial one.
|
||||
if (scan_phase == G1GCPhaseTimes::OptScanHR) {
|
||||
p->record_or_add_thread_work_item(scan_phase, worker_id, cl.opt_roots_scanned(), G1GCPhaseTimes::ScanHRFoundRoots);
|
||||
p->record_or_add_thread_work_item(scan_phase, worker_id, cl.opt_refs_scanned(), G1GCPhaseTimes::ScanHRScannedOptRefs);
|
||||
p->record_or_add_thread_work_item(scan_phase, worker_id, cl.opt_refs_memory_used(), G1GCPhaseTimes::ScanHRUsedMemory);
|
||||
|
||||
event.commit(GCId::current(), worker_id, G1GCPhaseTimes::phase_name(scan_phase));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef ASSERT
|
||||
void G1RemSet::assert_scan_top_is_null(uint hrm_index) {
|
||||
|
@ -112,10 +112,14 @@ public:
|
||||
|
||||
// Do work for regions in the current increment of the collection set, scanning
|
||||
// non-card based (heap) roots.
|
||||
void scan_collection_set_regions(G1ParScanThreadState* pss,
|
||||
void scan_collection_set_code_roots(G1ParScanThreadState* pss,
|
||||
uint worker_id,
|
||||
G1GCPhaseTimes::GCParPhases coderoots_phase,
|
||||
G1GCPhaseTimes::GCParPhases objcopy_phase);
|
||||
|
||||
void scan_collection_set_optional_roots(G1ParScanThreadState* pss,
|
||||
uint worker_id,
|
||||
G1GCPhaseTimes::GCParPhases scan_phase,
|
||||
G1GCPhaseTimes::GCParPhases coderoots_phase,
|
||||
G1GCPhaseTimes::GCParPhases objcopy_phase);
|
||||
|
||||
// Two methods for concurrent refinement support, executed concurrently to
|
||||
|
@ -591,8 +591,10 @@ class G1EvacuateRegionsBaseTask : public WorkerTask {
|
||||
protected:
|
||||
G1CollectedHeap* _g1h;
|
||||
G1ParScanThreadStateSet* _per_thread_states;
|
||||
|
||||
G1ScannerTasksQueueSet* _task_queues;
|
||||
TaskTerminator _terminator;
|
||||
|
||||
uint _num_workers;
|
||||
|
||||
void evacuate_live_objects(G1ParScanThreadState* pss,
|
||||
@ -667,7 +669,22 @@ class G1EvacuateRegionsTask : public G1EvacuateRegionsBaseTask {
|
||||
void scan_roots(G1ParScanThreadState* pss, uint worker_id) {
|
||||
_root_processor->evacuate_roots(pss, worker_id);
|
||||
_g1h->rem_set()->scan_heap_roots(pss, worker_id, G1GCPhaseTimes::ScanHR, G1GCPhaseTimes::ObjCopy, _has_optional_evacuation_work);
|
||||
_g1h->rem_set()->scan_collection_set_regions(pss, worker_id, G1GCPhaseTimes::ScanHR, G1GCPhaseTimes::CodeRoots, G1GCPhaseTimes::ObjCopy);
|
||||
_g1h->rem_set()->scan_collection_set_code_roots(pss, worker_id, G1GCPhaseTimes::CodeRoots, G1GCPhaseTimes::ObjCopy);
|
||||
// There are no optional roots to scan right now.
|
||||
#ifdef ASSERT
|
||||
class VerifyOptionalCollectionSetRootsEmptyClosure : public G1HeapRegionClosure {
|
||||
G1ParScanThreadState* _pss;
|
||||
|
||||
public:
|
||||
VerifyOptionalCollectionSetRootsEmptyClosure(G1ParScanThreadState* pss) : _pss(pss) { }
|
||||
|
||||
bool do_heap_region(G1HeapRegion* r) override {
|
||||
assert(!r->has_index_in_opt_cset(), "must be");
|
||||
return false;
|
||||
}
|
||||
} cl(pss);
|
||||
_g1h->collection_set_iterate_increment_from(&cl, worker_id);
|
||||
#endif
|
||||
}
|
||||
|
||||
void evacuate_live_objects(G1ParScanThreadState* pss, uint worker_id) {
|
||||
@ -736,7 +753,8 @@ class G1EvacuateOptionalRegionsTask : public G1EvacuateRegionsBaseTask {
|
||||
|
||||
void scan_roots(G1ParScanThreadState* pss, uint worker_id) {
|
||||
_g1h->rem_set()->scan_heap_roots(pss, worker_id, G1GCPhaseTimes::OptScanHR, G1GCPhaseTimes::OptObjCopy, true /* remember_already_scanned_cards */);
|
||||
_g1h->rem_set()->scan_collection_set_regions(pss, worker_id, G1GCPhaseTimes::OptScanHR, G1GCPhaseTimes::OptCodeRoots, G1GCPhaseTimes::OptObjCopy);
|
||||
_g1h->rem_set()->scan_collection_set_code_roots(pss, worker_id, G1GCPhaseTimes::OptCodeRoots, G1GCPhaseTimes::OptObjCopy);
|
||||
_g1h->rem_set()->scan_collection_set_optional_roots(pss, worker_id, G1GCPhaseTimes::OptScanHR, G1GCPhaseTimes::ObjCopy);
|
||||
}
|
||||
|
||||
void evacuate_live_objects(G1ParScanThreadState* pss, uint worker_id) {
|
||||
|
Loading…
Reference in New Issue
Block a user