8224160: Move G1RemSetScanClosure into g1RemSet.cpp file
Reviewed-by: kbarrett, sangheki
This commit is contained in:
parent
6d1a702a58
commit
8c6727240e
@ -308,158 +308,198 @@ void G1RemSet::initialize(size_t capacity, uint max_regions) {
|
||||
_scan_state->initialize(max_regions);
|
||||
}
|
||||
|
||||
G1ScanRSForRegionClosure::G1ScanRSForRegionClosure(G1RemSetScanState* scan_state,
|
||||
G1ScanCardClosure* scan_obj_on_card,
|
||||
G1ParScanThreadState* pss,
|
||||
G1GCPhaseTimes::GCParPhases phase,
|
||||
uint worker_i) :
|
||||
_g1h(G1CollectedHeap::heap()),
|
||||
_ct(_g1h->card_table()),
|
||||
_pss(pss),
|
||||
_scan_objs_on_card_cl(scan_obj_on_card),
|
||||
_scan_state(scan_state),
|
||||
_phase(phase),
|
||||
_worker_i(worker_i),
|
||||
_opt_refs_scanned(0),
|
||||
_opt_refs_memory_used(0),
|
||||
_cards_scanned(0),
|
||||
_cards_claimed(0),
|
||||
_cards_skipped(0),
|
||||
_rem_set_root_scan_time(),
|
||||
_rem_set_trim_partially_time(),
|
||||
_strong_code_root_scan_time(),
|
||||
_strong_code_trim_partially_time() {
|
||||
}
|
||||
class G1ScanRSForRegionClosure : public HeapRegionClosure {
|
||||
G1CollectedHeap* _g1h;
|
||||
G1CardTable *_ct;
|
||||
|
||||
void G1ScanRSForRegionClosure::claim_card(size_t card_index, const uint region_idx_for_card){
|
||||
_ct->set_card_claimed(card_index);
|
||||
_scan_state->add_dirty_region(region_idx_for_card);
|
||||
}
|
||||
G1ParScanThreadState* _pss;
|
||||
G1ScanCardClosure* _scan_objs_on_card_cl;
|
||||
|
||||
void G1ScanRSForRegionClosure::scan_card(MemRegion mr, uint region_idx_for_card) {
|
||||
HeapRegion* const card_region = _g1h->region_at(region_idx_for_card);
|
||||
assert(!card_region->is_young(), "Should not scan card in young region %u", region_idx_for_card);
|
||||
card_region->oops_on_card_seq_iterate_careful<true>(mr, _scan_objs_on_card_cl);
|
||||
_scan_objs_on_card_cl->trim_queue_partially();
|
||||
_cards_scanned++;
|
||||
}
|
||||
G1RemSetScanState* _scan_state;
|
||||
|
||||
void G1ScanRSForRegionClosure::scan_opt_rem_set_roots(HeapRegion* r) {
|
||||
EventGCPhaseParallel event;
|
||||
G1GCPhaseTimes::GCParPhases _phase;
|
||||
|
||||
G1OopStarChunkedList* opt_rem_set_list = _pss->oops_into_optional_region(r);
|
||||
uint _worker_i;
|
||||
|
||||
G1ScanCardClosure scan_cl(_g1h, _pss);
|
||||
G1ScanRSForOptionalClosure cl(_g1h, &scan_cl);
|
||||
_opt_refs_scanned += opt_rem_set_list->oops_do(&cl, _pss->closures()->raw_strong_oops());
|
||||
_opt_refs_memory_used += opt_rem_set_list->used_memory();
|
||||
size_t _opt_refs_scanned;
|
||||
size_t _opt_refs_memory_used;
|
||||
|
||||
event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(_phase));
|
||||
}
|
||||
size_t _cards_scanned;
|
||||
size_t _cards_claimed;
|
||||
size_t _cards_skipped;
|
||||
|
||||
void G1ScanRSForRegionClosure::scan_rem_set_roots(HeapRegion* r) {
|
||||
EventGCPhaseParallel event;
|
||||
uint const region_idx = r->hrm_index();
|
||||
Tickspan _rem_set_root_scan_time;
|
||||
Tickspan _rem_set_trim_partially_time;
|
||||
|
||||
if (_scan_state->claim_iter(region_idx)) {
|
||||
// If we ever free the collection set concurrently, we should also
|
||||
// clear the card table concurrently therefore we won't need to
|
||||
// add regions of the collection set to the dirty cards region.
|
||||
_scan_state->add_dirty_region(region_idx);
|
||||
Tickspan _strong_code_root_scan_time;
|
||||
Tickspan _strong_code_trim_partially_time;
|
||||
|
||||
void claim_card(size_t card_index, const uint region_idx_for_card) {
|
||||
_ct->set_card_claimed(card_index);
|
||||
_scan_state->add_dirty_region(region_idx_for_card);
|
||||
}
|
||||
|
||||
if (r->rem_set()->cardset_is_empty()) {
|
||||
return;
|
||||
void scan_card(MemRegion mr, uint region_idx_for_card) {
|
||||
HeapRegion* const card_region = _g1h->region_at(region_idx_for_card);
|
||||
assert(!card_region->is_young(), "Should not scan card in young region %u", region_idx_for_card);
|
||||
card_region->oops_on_card_seq_iterate_careful<true>(mr, _scan_objs_on_card_cl);
|
||||
_scan_objs_on_card_cl->trim_queue_partially();
|
||||
_cards_scanned++;
|
||||
}
|
||||
|
||||
// We claim cards in blocks so as to reduce the contention.
|
||||
size_t const block_size = G1RSetScanBlockSize;
|
||||
void scan_opt_rem_set_roots(HeapRegion* r) {
|
||||
EventGCPhaseParallel event;
|
||||
|
||||
HeapRegionRemSetIterator iter(r->rem_set());
|
||||
size_t card_index;
|
||||
G1OopStarChunkedList* opt_rem_set_list = _pss->oops_into_optional_region(r);
|
||||
|
||||
size_t claimed_card_block = _scan_state->iter_claimed_next(region_idx, block_size);
|
||||
for (size_t current_card = 0; iter.has_next(card_index); current_card++) {
|
||||
if (current_card >= claimed_card_block + block_size) {
|
||||
claimed_card_block = _scan_state->iter_claimed_next(region_idx, block_size);
|
||||
G1ScanCardClosure scan_cl(_g1h, _pss);
|
||||
G1ScanRSForOptionalClosure cl(_g1h, &scan_cl);
|
||||
_opt_refs_scanned += opt_rem_set_list->oops_do(&cl, _pss->closures()->raw_strong_oops());
|
||||
_opt_refs_memory_used += opt_rem_set_list->used_memory();
|
||||
|
||||
event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(_phase));
|
||||
}
|
||||
|
||||
void scan_rem_set_roots(HeapRegion* r) {
|
||||
EventGCPhaseParallel event;
|
||||
uint const region_idx = r->hrm_index();
|
||||
|
||||
if (_scan_state->claim_iter(region_idx)) {
|
||||
// If we ever free the collection set concurrently, we should also
|
||||
// clear the card table concurrently therefore we won't need to
|
||||
// add regions of the collection set to the dirty cards region.
|
||||
_scan_state->add_dirty_region(region_idx);
|
||||
}
|
||||
if (current_card < claimed_card_block) {
|
||||
_cards_skipped++;
|
||||
continue;
|
||||
}
|
||||
_cards_claimed++;
|
||||
|
||||
HeapWord* const card_start = _g1h->bot()->address_for_index_raw(card_index);
|
||||
uint const region_idx_for_card = _g1h->addr_to_region(card_start);
|
||||
if (r->rem_set()->cardset_is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We claim cards in blocks so as to reduce the contention.
|
||||
size_t const block_size = G1RSetScanBlockSize;
|
||||
|
||||
HeapRegionRemSetIterator iter(r->rem_set());
|
||||
size_t card_index;
|
||||
|
||||
size_t claimed_card_block = _scan_state->iter_claimed_next(region_idx, block_size);
|
||||
for (size_t current_card = 0; iter.has_next(card_index); current_card++) {
|
||||
if (current_card >= claimed_card_block + block_size) {
|
||||
claimed_card_block = _scan_state->iter_claimed_next(region_idx, block_size);
|
||||
}
|
||||
if (current_card < claimed_card_block) {
|
||||
_cards_skipped++;
|
||||
continue;
|
||||
}
|
||||
_cards_claimed++;
|
||||
|
||||
HeapWord* const card_start = _g1h->bot()->address_for_index_raw(card_index);
|
||||
uint const region_idx_for_card = _g1h->addr_to_region(card_start);
|
||||
|
||||
#ifdef ASSERT
|
||||
HeapRegion* hr = _g1h->region_at_or_null(region_idx_for_card);
|
||||
assert(hr == NULL || hr->is_in_reserved(card_start),
|
||||
"Card start " PTR_FORMAT " to scan outside of region %u", p2i(card_start), _g1h->region_at(region_idx_for_card)->hrm_index());
|
||||
HeapRegion* hr = _g1h->region_at_or_null(region_idx_for_card);
|
||||
assert(hr == NULL || hr->is_in_reserved(card_start),
|
||||
"Card start " PTR_FORMAT " to scan outside of region %u", p2i(card_start), _g1h->region_at(region_idx_for_card)->hrm_index());
|
||||
#endif
|
||||
HeapWord* const top = _scan_state->scan_top(region_idx_for_card);
|
||||
if (card_start >= top) {
|
||||
continue;
|
||||
HeapWord* const top = _scan_state->scan_top(region_idx_for_card);
|
||||
if (card_start >= top) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the card is dirty, then G1 will scan it during Update RS.
|
||||
if (_ct->is_card_claimed(card_index) || _ct->is_card_dirty(card_index)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// We claim lazily (so races are possible but they're benign), which reduces the
|
||||
// number of duplicate scans (the rsets of the regions in the cset can intersect).
|
||||
// Claim the card after checking bounds above: the remembered set may contain
|
||||
// random cards into current survivor, and we would then have an incorrectly
|
||||
// claimed card in survivor space. Card table clear does not reset the card table
|
||||
// of survivor space regions.
|
||||
claim_card(card_index, region_idx_for_card);
|
||||
|
||||
MemRegion const mr(card_start, MIN2(card_start + BOTConstants::N_words, top));
|
||||
|
||||
scan_card(mr, region_idx_for_card);
|
||||
}
|
||||
|
||||
// If the card is dirty, then G1 will scan it during Update RS.
|
||||
if (_ct->is_card_claimed(card_index) || _ct->is_card_dirty(card_index)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// We claim lazily (so races are possible but they're benign), which reduces the
|
||||
// number of duplicate scans (the rsets of the regions in the cset can intersect).
|
||||
// Claim the card after checking bounds above: the remembered set may contain
|
||||
// random cards into current survivor, and we would then have an incorrectly
|
||||
// claimed card in survivor space. Card table clear does not reset the card table
|
||||
// of survivor space regions.
|
||||
claim_card(card_index, region_idx_for_card);
|
||||
|
||||
MemRegion const mr(card_start, MIN2(card_start + BOTConstants::N_words, top));
|
||||
|
||||
scan_card(mr, region_idx_for_card);
|
||||
}
|
||||
event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(_phase));
|
||||
}
|
||||
|
||||
void G1ScanRSForRegionClosure::scan_strong_code_roots(HeapRegion* r) {
|
||||
EventGCPhaseParallel event;
|
||||
// We pass a weak code blobs closure to the remembered set scanning because we want to avoid
|
||||
// treating the nmethods visited to act as roots for concurrent marking.
|
||||
// We only want to make sure that the oops in the nmethods are adjusted with regard to the
|
||||
// objects copied by the current evacuation.
|
||||
r->strong_code_roots_do(_pss->closures()->weak_codeblobs());
|
||||
event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(G1GCPhaseTimes::CodeRoots));
|
||||
}
|
||||
|
||||
bool G1ScanRSForRegionClosure::do_heap_region(HeapRegion* r) {
|
||||
assert(r->in_collection_set(), "Region %u is not in the collection set.", r->hrm_index());
|
||||
uint const region_idx = r->hrm_index();
|
||||
|
||||
// The individual references for the optional remembered set are per-worker, so we
|
||||
// always need to scan them.
|
||||
if (r->has_index_in_opt_cset()) {
|
||||
G1EvacPhaseWithTrimTimeTracker timer(_pss, _rem_set_root_scan_time, _rem_set_trim_partially_time);
|
||||
scan_opt_rem_set_roots(r);
|
||||
event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(_phase));
|
||||
}
|
||||
|
||||
// Do an early out if we know we are complete.
|
||||
if (_scan_state->iter_is_complete(region_idx)) {
|
||||
void scan_strong_code_roots(HeapRegion* r) {
|
||||
EventGCPhaseParallel event;
|
||||
// We pass a weak code blobs closure to the remembered set scanning because we want to avoid
|
||||
// treating the nmethods visited to act as roots for concurrent marking.
|
||||
// We only want to make sure that the oops in the nmethods are adjusted with regard to the
|
||||
// objects copied by the current evacuation.
|
||||
r->strong_code_roots_do(_pss->closures()->weak_codeblobs());
|
||||
event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(G1GCPhaseTimes::CodeRoots));
|
||||
}
|
||||
|
||||
public:
|
||||
G1ScanRSForRegionClosure(G1RemSetScanState* scan_state,
|
||||
G1ScanCardClosure* scan_obj_on_card,
|
||||
G1ParScanThreadState* pss,
|
||||
G1GCPhaseTimes::GCParPhases phase,
|
||||
uint worker_i) :
|
||||
_g1h(G1CollectedHeap::heap()),
|
||||
_ct(_g1h->card_table()),
|
||||
_pss(pss),
|
||||
_scan_objs_on_card_cl(scan_obj_on_card),
|
||||
_scan_state(scan_state),
|
||||
_phase(phase),
|
||||
_worker_i(worker_i),
|
||||
_opt_refs_scanned(0),
|
||||
_opt_refs_memory_used(0),
|
||||
_cards_scanned(0),
|
||||
_cards_claimed(0),
|
||||
_cards_skipped(0),
|
||||
_rem_set_root_scan_time(),
|
||||
_rem_set_trim_partially_time(),
|
||||
_strong_code_root_scan_time(),
|
||||
_strong_code_trim_partially_time() { }
|
||||
|
||||
bool do_heap_region(HeapRegion* r) {
|
||||
assert(r->in_collection_set(), "Region %u is not in the collection set.", r->hrm_index());
|
||||
uint const region_idx = r->hrm_index();
|
||||
|
||||
// The individual references for the optional remembered set are per-worker, so we
|
||||
// always need to scan them.
|
||||
if (r->has_index_in_opt_cset()) {
|
||||
G1EvacPhaseWithTrimTimeTracker timer(_pss, _rem_set_root_scan_time, _rem_set_trim_partially_time);
|
||||
scan_opt_rem_set_roots(r);
|
||||
}
|
||||
|
||||
// Do an early out if we know we are complete.
|
||||
if (_scan_state->iter_is_complete(region_idx)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
G1EvacPhaseWithTrimTimeTracker timer(_pss, _rem_set_root_scan_time, _rem_set_trim_partially_time);
|
||||
scan_rem_set_roots(r);
|
||||
}
|
||||
|
||||
if (_scan_state->set_iter_complete(region_idx)) {
|
||||
G1EvacPhaseWithTrimTimeTracker timer(_pss, _strong_code_root_scan_time, _strong_code_trim_partially_time);
|
||||
// Scan the strong code root list attached to the current region
|
||||
scan_strong_code_roots(r);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
G1EvacPhaseWithTrimTimeTracker timer(_pss, _rem_set_root_scan_time, _rem_set_trim_partially_time);
|
||||
scan_rem_set_roots(r);
|
||||
}
|
||||
Tickspan rem_set_root_scan_time() const { return _rem_set_root_scan_time; }
|
||||
Tickspan rem_set_trim_partially_time() const { return _rem_set_trim_partially_time; }
|
||||
|
||||
if (_scan_state->set_iter_complete(region_idx)) {
|
||||
G1EvacPhaseWithTrimTimeTracker timer(_pss, _strong_code_root_scan_time, _strong_code_trim_partially_time);
|
||||
// Scan the strong code root list attached to the current region
|
||||
scan_strong_code_roots(r);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
Tickspan strong_code_root_scan_time() const { return _strong_code_root_scan_time; }
|
||||
Tickspan strong_code_root_trim_partially_time() const { return _strong_code_trim_partially_time; }
|
||||
|
||||
size_t cards_scanned() const { return _cards_scanned; }
|
||||
size_t cards_claimed() const { return _cards_claimed; }
|
||||
size_t cards_skipped() const { return _cards_skipped; }
|
||||
|
||||
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_rem_set(G1ParScanThreadState* pss,
|
||||
uint worker_i,
|
||||
|
@ -130,59 +130,4 @@ public:
|
||||
void rebuild_rem_set(G1ConcurrentMark* cm, WorkGang* workers, uint worker_id_offset);
|
||||
};
|
||||
|
||||
class G1ScanRSForRegionClosure : public HeapRegionClosure {
|
||||
G1CollectedHeap* _g1h;
|
||||
G1CardTable *_ct;
|
||||
|
||||
G1ParScanThreadState* _pss;
|
||||
G1ScanCardClosure* _scan_objs_on_card_cl;
|
||||
|
||||
G1RemSetScanState* _scan_state;
|
||||
|
||||
G1GCPhaseTimes::GCParPhases _phase;
|
||||
|
||||
uint _worker_i;
|
||||
|
||||
size_t _opt_refs_scanned;
|
||||
size_t _opt_refs_memory_used;
|
||||
|
||||
size_t _cards_scanned;
|
||||
size_t _cards_claimed;
|
||||
size_t _cards_skipped;
|
||||
|
||||
Tickspan _rem_set_root_scan_time;
|
||||
Tickspan _rem_set_trim_partially_time;
|
||||
|
||||
Tickspan _strong_code_root_scan_time;
|
||||
Tickspan _strong_code_trim_partially_time;
|
||||
|
||||
void claim_card(size_t card_index, const uint region_idx_for_card);
|
||||
void scan_card(MemRegion mr, uint region_idx_for_card);
|
||||
|
||||
void scan_opt_rem_set_roots(HeapRegion* r);
|
||||
void scan_rem_set_roots(HeapRegion* r);
|
||||
void scan_strong_code_roots(HeapRegion* r);
|
||||
public:
|
||||
G1ScanRSForRegionClosure(G1RemSetScanState* scan_state,
|
||||
G1ScanCardClosure* scan_obj_on_card,
|
||||
G1ParScanThreadState* pss,
|
||||
G1GCPhaseTimes::GCParPhases phase,
|
||||
uint worker_i);
|
||||
|
||||
bool do_heap_region(HeapRegion* r);
|
||||
|
||||
Tickspan rem_set_root_scan_time() const { return _rem_set_root_scan_time; }
|
||||
Tickspan rem_set_trim_partially_time() const { return _rem_set_trim_partially_time; }
|
||||
|
||||
Tickspan strong_code_root_scan_time() const { return _strong_code_root_scan_time; }
|
||||
Tickspan strong_code_root_trim_partially_time() const { return _strong_code_trim_partially_time; }
|
||||
|
||||
size_t cards_scanned() const { return _cards_scanned; }
|
||||
size_t cards_claimed() const { return _cards_claimed; }
|
||||
size_t cards_skipped() const { return _cards_skipped; }
|
||||
|
||||
size_t opt_refs_scanned() const { return _opt_refs_scanned; }
|
||||
size_t opt_refs_memory_used() const { return _opt_refs_memory_used; }
|
||||
};
|
||||
|
||||
#endif // SHARE_GC_G1_G1REMSET_HPP
|
||||
|
Loading…
Reference in New Issue
Block a user