< prev index next >
src/hotspot/share/gc/g1/g1RemSet.cpp
Print this page
rev 49826 : imported patch 6672778-partial-queue-trimming
rev 49827 : imported patch 6672778-refactoring
rev 49828 : imported patch 6672778-stefanj-review
*** 31,40 ****
--- 31,41 ----
#include "gc/g1/g1ConcurrentRefine.hpp"
#include "gc/g1/g1FromCardCache.hpp"
#include "gc/g1/g1GCPhaseTimes.hpp"
#include "gc/g1/g1HotCardCache.hpp"
#include "gc/g1/g1OopClosures.inline.hpp"
+ #include "gc/g1/g1RootClosures.hpp"
#include "gc/g1/g1RemSet.hpp"
#include "gc/g1/heapRegion.inline.hpp"
#include "gc/g1/heapRegionManager.inline.hpp"
#include "gc/g1/heapRegionRemSet.hpp"
#include "gc/shared/gcTraceTime.inline.hpp"
*** 304,353 ****
_scan_state->initialize(max_regions);
}
G1ScanRSForRegionClosure::G1ScanRSForRegionClosure(G1RemSetScanState* scan_state,
G1ScanObjsDuringScanRSClosure* scan_obj_on_card,
! CodeBlobClosure* code_root_cl,
uint worker_i) :
! _scan_state(scan_state),
_scan_objs_on_card_cl(scan_obj_on_card),
! _code_root_cl(code_root_cl),
! _strong_code_root_scan_time_sec(0.0),
_cards_claimed(0),
_cards_scanned(0),
_cards_skipped(0),
! _worker_i(worker_i) {
! _g1h = G1CollectedHeap::heap();
! _bot = _g1h->bot();
! _ct = _g1h->card_table();
}
void G1ScanRSForRegionClosure::scan_card(MemRegion mr, uint region_idx_for_card) {
HeapRegion* const card_region = _g1h->region_at(region_idx_for_card);
_scan_objs_on_card_cl->set_region(card_region);
card_region->oops_on_card_seq_iterate_careful<true>(mr, _scan_objs_on_card_cl);
_cards_scanned++;
}
! void G1ScanRSForRegionClosure::scan_strong_code_roots(HeapRegion* r) {
! double scan_start = os::elapsedTime();
! r->strong_code_roots_do(_code_root_cl);
! _strong_code_root_scan_time_sec += (os::elapsedTime() - scan_start);
! }
- 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);
- }
-
- bool G1ScanRSForRegionClosure::do_heap_region(HeapRegion* r) {
- assert(r->in_collection_set(), "should only be called on elements of CS.");
- uint region_idx = r->hrm_index();
-
- if (_scan_state->iter_is_complete(region_idx)) {
- return false;
- }
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);
--- 305,347 ----
_scan_state->initialize(max_regions);
}
G1ScanRSForRegionClosure::G1ScanRSForRegionClosure(G1RemSetScanState* scan_state,
G1ScanObjsDuringScanRSClosure* scan_obj_on_card,
! G1ParScanThreadState* pss,
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),
! _worker_i(worker_i),
_cards_claimed(0),
_cards_scanned(0),
_cards_skipped(0),
! _rem_set_root_scan_time(),
! _rem_set_trim_partially_time(),
! _strong_code_root_scan_time(),
! _strong_code_trim_partially_time() {
! }
!
! 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);
}
void G1ScanRSForRegionClosure::scan_card(MemRegion mr, uint region_idx_for_card) {
HeapRegion* const card_region = _g1h->region_at(region_idx_for_card);
_scan_objs_on_card_cl->set_region(card_region);
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++;
}
! void G1ScanRSForRegionClosure::scan_rem_set_roots(HeapRegion* r) {
! 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);
*** 395,431 ****
MemRegion const mr(card_start, MIN2(card_start + BOTConstants::N_words, top));
scan_card(mr, region_idx_for_card);
}
if (_scan_state->set_iter_complete(region_idx)) {
// Scan the strong code root list attached to the current region
scan_strong_code_roots(r);
}
return false;
}
! void G1RemSet::scan_rem_set(G1ParScanThreadState* pss,
! CodeBlobClosure* heap_region_codeblobs,
! uint worker_i) {
! double rs_time_start = os::elapsedTime();
!
G1ScanObjsDuringScanRSClosure scan_cl(_g1h, pss);
! G1ScanRSForRegionClosure cl(_scan_state, &scan_cl, heap_region_codeblobs, worker_i);
_g1h->collection_set_iterate_from(&cl, worker_i);
- double scan_rs_time_sec = (os::elapsedTime() - rs_time_start) -
- cl.strong_code_root_scan_time_sec();
-
G1GCPhaseTimes* p = _g1p->phase_times();
! p->record_time_secs(G1GCPhaseTimes::ScanRS, worker_i, scan_rs_time_sec);
p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_scanned(), G1GCPhaseTimes::ScanRSScannedCards);
p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_claimed(), G1GCPhaseTimes::ScanRSClaimedCards);
p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_skipped(), G1GCPhaseTimes::ScanRSSkippedCards);
! p->record_time_secs(G1GCPhaseTimes::CodeRoots, worker_i, cl.strong_code_root_scan_time_sec());
}
// Closure used for updating rem sets. Only called during an evacuation pause.
class G1RefineCardClosure: public CardTableEntryClosure {
G1RemSet* _g1rs;
--- 389,444 ----
MemRegion const mr(card_start, MIN2(card_start + BOTConstants::N_words, top));
scan_card(mr, region_idx_for_card);
}
+ }
+
+ void G1ScanRSForRegionClosure::scan_strong_code_roots(HeapRegion* r) {
+ r->strong_code_roots_do(_pss->closures()->weak_codeblobs());
+ }
+
+ bool G1ScanRSForRegionClosure::do_heap_region(HeapRegion* r) {
+ assert(r->in_collection_set(),
+ "Should only be called on elements of the collection set but region %u is not.",
+ r->hrm_index());
+ uint const region_idx = r->hrm_index();
+
+ // 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;
}
! void G1RemSet::scan_rem_set(G1ParScanThreadState* pss, uint worker_i) {
G1ScanObjsDuringScanRSClosure scan_cl(_g1h, pss);
! G1ScanRSForRegionClosure cl(_scan_state, &scan_cl, pss, worker_i);
_g1h->collection_set_iterate_from(&cl, worker_i);
G1GCPhaseTimes* p = _g1p->phase_times();
! p->record_time_secs(G1GCPhaseTimes::ScanRS, worker_i, TicksToTimeHelper::seconds(cl.rem_set_root_scan_time()));
! p->add_time_secs(G1GCPhaseTimes::ObjCopy, worker_i, TicksToTimeHelper::seconds(cl.rem_set_trim_partially_time()));
!
p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_scanned(), G1GCPhaseTimes::ScanRSScannedCards);
p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_claimed(), G1GCPhaseTimes::ScanRSClaimedCards);
p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_skipped(), G1GCPhaseTimes::ScanRSSkippedCards);
! p->record_time_secs(G1GCPhaseTimes::CodeRoots, worker_i, TicksToTimeHelper::seconds(cl.strong_code_root_scan_time()));
! p->add_time_secs(G1GCPhaseTimes::ObjCopy, worker_i, TicksToTimeHelper::seconds(cl.strong_code_root_trim_partially_time()));
}
// Closure used for updating rem sets. Only called during an evacuation pause.
class G1RefineCardClosure: public CardTableEntryClosure {
G1RemSet* _g1rs;
*** 446,455 ****
--- 459,469 ----
assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
bool card_scanned = _g1rs->refine_card_during_gc(card_ptr, _update_rs_cl);
if (card_scanned) {
+ _update_rs_cl->trim_queue_partially();
_cards_scanned++;
} else {
_cards_skipped++;
}
return true;
*** 458,493 ****
size_t cards_scanned() const { return _cards_scanned; }
size_t cards_skipped() const { return _cards_skipped; }
};
void G1RemSet::update_rem_set(G1ParScanThreadState* pss, uint worker_i) {
! G1ScanObjsDuringUpdateRSClosure update_rs_cl(_g1h, pss, worker_i);
! G1RefineCardClosure refine_card_cl(_g1h, &update_rs_cl);
! G1GCParPhaseTimesTracker x(_g1p->phase_times(), G1GCPhaseTimes::UpdateRS, worker_i);
if (G1HotCardCache::default_use_cache()) {
! // Apply the closure to the entries of the hot card cache.
! G1GCParPhaseTimesTracker y(_g1p->phase_times(), G1GCPhaseTimes::ScanHCC, worker_i);
_g1h->iterate_hcc_closure(&refine_card_cl, worker_i);
}
! // Apply the closure to all remaining log entries.
_g1h->iterate_dirty_card_closure(&refine_card_cl, worker_i);
- G1GCPhaseTimes* p = _g1p->phase_times();
p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_scanned(), G1GCPhaseTimes::UpdateRSScannedCards);
p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_skipped(), G1GCPhaseTimes::UpdateRSSkippedCards);
}
void G1RemSet::cleanupHRRS() {
HeapRegionRemSet::cleanup();
}
! void G1RemSet::oops_into_collection_set_do(G1ParScanThreadState* pss,
! CodeBlobClosure* heap_region_codeblobs,
! uint worker_i) {
update_rem_set(pss, worker_i);
! scan_rem_set(pss, heap_region_codeblobs, worker_i);;
}
void G1RemSet::prepare_for_oops_into_collection_set_do() {
DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
dcqs.concatenate_logs();
--- 472,512 ----
size_t cards_scanned() const { return _cards_scanned; }
size_t cards_skipped() const { return _cards_skipped; }
};
void G1RemSet::update_rem_set(G1ParScanThreadState* pss, uint worker_i) {
! G1GCPhaseTimes* p = _g1p->phase_times();
! // Apply closure to log entries in the HCC.
if (G1HotCardCache::default_use_cache()) {
! G1EvacPhaseTimesTracker x(p, pss, G1GCPhaseTimes::ScanHCC, worker_i);
!
! G1ScanObjsDuringUpdateRSClosure scan_hcc_cl(_g1h, pss, worker_i);
! G1RefineCardClosure refine_card_cl(_g1h, &scan_hcc_cl);
_g1h->iterate_hcc_closure(&refine_card_cl, worker_i);
}
!
! // Now apply the closure to all remaining log entries.
! {
! G1EvacPhaseTimesTracker x(p, pss, G1GCPhaseTimes::UpdateRS, worker_i);
!
! G1ScanObjsDuringUpdateRSClosure update_rs_cl(_g1h, pss, worker_i);
! G1RefineCardClosure refine_card_cl(_g1h, &update_rs_cl);
_g1h->iterate_dirty_card_closure(&refine_card_cl, worker_i);
p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_scanned(), G1GCPhaseTimes::UpdateRSScannedCards);
p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_skipped(), G1GCPhaseTimes::UpdateRSSkippedCards);
+ }
}
void G1RemSet::cleanupHRRS() {
HeapRegionRemSet::cleanup();
}
! void G1RemSet::oops_into_collection_set_do(G1ParScanThreadState* pss, uint worker_i) {
update_rem_set(pss, worker_i);
! scan_rem_set(pss, worker_i);;
}
void G1RemSet::prepare_for_oops_into_collection_set_do() {
DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
dcqs.concatenate_logs();
< prev index next >