7878#include " utilities/growableArray.hpp"
7979#include " utilities/powerOfTwo.hpp"
8080
81+ G1CMIsAliveClosure::G1CMIsAliveClosure () : _cm(nullptr ) { }
82+
83+ G1CMIsAliveClosure::G1CMIsAliveClosure (G1ConcurrentMark* cm) : _cm(cm) {
84+ assert (cm != nullptr , " must be" );
85+ }
86+
87+ void G1CMIsAliveClosure::initialize (G1ConcurrentMark* cm) {
88+ assert (cm != nullptr , " must be" );
89+ assert (_cm == nullptr , " double initialize" );
90+ _cm = cm;
91+ }
92+
8193bool G1CMBitMapClosure::do_addr (HeapWord* const addr) {
8294 assert (addr < _cm->finger (), " invariant" );
8395 assert (addr >= _task->finger (), " invariant" );
@@ -502,6 +514,7 @@ G1ConcurrentMark::G1ConcurrentMark(G1CollectedHeap* g1h,
502514 _max_concurrent_workers(0 ),
503515
504516 _region_mark_stats(NEW_C_HEAP_ARRAY(G1RegionMarkStats, _g1h->max_reserved_regions (), mtGC)),
517+ _top_at_mark_starts(NEW_C_HEAP_ARRAY(HeapWord*, _g1h->max_reserved_regions (), mtGC)),
505518 _top_at_rebuild_starts(NEW_C_HEAP_ARRAY(HeapWord*, _g1h->max_reserved_regions (), mtGC)),
506519 _needs_remembered_set_rebuild(false )
507520{
@@ -648,6 +661,7 @@ void G1ConcurrentMark::reset_at_marking_complete() {
648661}
649662
650663G1ConcurrentMark::~G1ConcurrentMark () {
664+ FREE_C_HEAP_ARRAY (HeapWord*, _top_at_mark_starts);
651665 FREE_C_HEAP_ARRAY (HeapWord*, _top_at_rebuild_starts);
652666 FREE_C_HEAP_ARRAY (G1RegionMarkStats, _region_mark_stats);
653667 // The G1ConcurrentMark instance is never freed.
@@ -693,7 +707,7 @@ class G1ClearBitMapTask : public WorkerTask {
693707 assert (_bitmap->get_next_marked_addr (r->bottom (), r->end ()) == r->end (), " Should not have marked bits" );
694708 return r->bottom ();
695709 }
696- assert (_bitmap->get_next_marked_addr (r ->top_at_mark_start (), r->end ()) == r->end (), " Should not have marked bits above tams" );
710+ assert (_bitmap->get_next_marked_addr (_cm ->top_at_mark_start (r ), r->end ()) == r->end (), " Should not have marked bits above tams" );
697711 }
698712 return r->end ();
699713 }
@@ -737,7 +751,7 @@ class G1ClearBitMapTask : public WorkerTask {
737751 }
738752 assert (cur >= end, " Must have completed iteration over the bitmap for region %u." , r->hrm_index ());
739753
740- r ->reset_top_at_mark_start ();
754+ _cm ->reset_top_at_mark_start (r );
741755
742756 return false ;
743757 }
@@ -849,9 +863,15 @@ void G1PreConcurrentStartTask::ResetMarkingStateTask::do_work(uint worker_id) {
849863}
850864
851865class NoteStartOfMarkHRClosure : public HeapRegionClosure {
866+ G1ConcurrentMark* _cm;
867+
852868public:
869+ NoteStartOfMarkHRClosure () : HeapRegionClosure(), _cm(G1CollectedHeap::heap()->concurrent_mark ()) { }
870+
853871 bool do_heap_region (HeapRegion* r) override {
854- r->note_start_of_marking ();
872+ if (r->is_old_or_humongous () && !r->is_collection_set_candidate ()) {
873+ _cm->update_top_at_mark_start (r);
874+ }
855875 return false ;
856876 }
857877};
@@ -1015,9 +1035,9 @@ void G1ConcurrentMark::scan_root_region(const MemRegion* region, uint worker_id)
10151035#ifdef ASSERT
10161036 HeapWord* last = region->last ();
10171037 HeapRegion* hr = _g1h->heap_region_containing (last);
1018- assert (hr->is_old () || hr-> top_at_mark_start () == hr->bottom (),
1038+ assert (hr->is_old () || top_at_mark_start (hr ) == hr->bottom (),
10191039 " Root regions must be old or survivor/eden but region %u is %s" , hr->hrm_index (), hr->get_type_str ());
1020- assert (hr-> top_at_mark_start () == region->start (),
1040+ assert (top_at_mark_start (hr ) == region->start (),
10211041 " MemRegion start should be equal to TAMS" );
10221042#endif
10231043
@@ -1079,11 +1099,11 @@ bool G1ConcurrentMark::wait_until_root_region_scan_finished() {
10791099}
10801100
10811101void G1ConcurrentMark::add_root_region (HeapRegion* r) {
1082- root_regions ()->add (r-> top_at_mark_start (), r->top ());
1102+ root_regions ()->add (top_at_mark_start (r ), r->top ());
10831103}
10841104
10851105bool G1ConcurrentMark::is_root_region (HeapRegion* r) {
1086- return root_regions ()->contains (MemRegion (r-> top_at_mark_start (), r->top ()));
1106+ return root_regions ()->contains (MemRegion (top_at_mark_start (r ), r->top ()));
10871107}
10881108
10891109void G1ConcurrentMark::root_region_scan_abort_and_wait () {
@@ -1250,7 +1270,7 @@ class G1UpdateRegionLivenessAndSelectForRebuildTask : public WorkerTask {
12501270 if (hr->is_starts_humongous ()) {
12511271 // The liveness of this humongous obj decided by either its allocation
12521272 // time (allocated after conc-mark-start, i.e. live) or conc-marking.
1253- const bool is_live = hr ->top_at_mark_start () == hr->bottom ()
1273+ const bool is_live = _cm ->top_at_mark_start (hr ) == hr->bottom ()
12541274 || _cm->contains_live_object (hr->hrm_index ());
12551275 if (is_live) {
12561276 const bool selected_for_rebuild = tracker->update_humongous_before_rebuild (hr);
@@ -1266,7 +1286,7 @@ class G1UpdateRegionLivenessAndSelectForRebuildTask : public WorkerTask {
12661286 reclaim_empty_humongous_region (hr);
12671287 }
12681288 } else if (hr->is_old ()) {
1269- hr->note_end_of_marking (_cm->live_bytes (hr->hrm_index ()));
1289+ hr->note_end_of_marking (_cm->top_at_mark_start (hr), _cm-> live_bytes (hr->hrm_index ()));
12701290
12711291 if (hr->live_bytes () != 0 ) {
12721292 if (tracker->update_old_before_rebuild (hr)) {
@@ -1386,7 +1406,7 @@ void G1ConcurrentMark::remark() {
13861406
13871407 // Unload Klasses, String, Code Cache, etc.
13881408 if (ClassUnloadingWithConcurrentMark) {
1389- G1CMIsAliveClosure is_alive (_g1h );
1409+ G1CMIsAliveClosure is_alive (this );
13901410 _g1h->unload_classes_and_code (" Class Unloading" , &is_alive, _gc_timer_cm);
13911411 }
13921412
@@ -1640,7 +1660,7 @@ class G1CMRefProcProxyTask : public RefProcProxyTask {
16401660
16411661 void work (uint worker_id) override {
16421662 assert (worker_id < _max_workers, " sanity" );
1643- G1CMIsAliveClosure is_alive (&_g1h );
1663+ G1CMIsAliveClosure is_alive (&_cm );
16441664 uint index = (_tm == RefProcThreadModel::Single) ? 0 : worker_id;
16451665 G1CMKeepAliveAndDrainClosure keep_alive (&_cm, _cm.task (index), _tm == RefProcThreadModel::Single);
16461666 BarrierEnqueueDiscoveredFieldClosure enqueue;
@@ -1719,7 +1739,7 @@ void G1ConcurrentMark::weak_refs_work() {
17191739
17201740 {
17211741 GCTraceTime (Debug, gc, phases) debug (" Weak Processing" , _gc_timer_cm);
1722- G1CMIsAliveClosure is_alive (_g1h );
1742+ G1CMIsAliveClosure is_alive (this );
17231743 WeakProcessor::weak_oops_do (_g1h->workers (), &is_alive, &do_nothing_cl, 1 );
17241744 }
17251745}
@@ -1898,9 +1918,9 @@ HeapRegion* G1ConcurrentMark::claim_region(uint worker_id) {
18981918 if (res == finger && curr_region != nullptr ) {
18991919 // we succeeded
19001920 HeapWord* bottom = curr_region->bottom ();
1901- HeapWord* limit = curr_region-> top_at_mark_start ();
1921+ HeapWord* limit = top_at_mark_start (curr_region );
19021922
1903- log_trace (gc, marking)(" Claim region %u bottom " PTR_FORMAT " tams " PTR_FORMAT, curr_region->hrm_index (), p2i (curr_region->bottom ()), p2i (curr_region-> top_at_mark_start ()));
1923+ log_trace (gc, marking)(" Claim region %u bottom " PTR_FORMAT " tams " PTR_FORMAT, curr_region->hrm_index (), p2i (curr_region->bottom ()), p2i (top_at_mark_start (curr_region )));
19041924 // notice that _finger == end cannot be guaranteed here since,
19051925 // someone else might have moved the finger even further
19061926 assert (_finger >= end, " the finger should have moved forward" );
@@ -2123,7 +2143,7 @@ void G1CMTask::setup_for_region(HeapRegion* hr) {
21232143void G1CMTask::update_region_limit () {
21242144 HeapRegion* hr = _curr_region;
21252145 HeapWord* bottom = hr->bottom ();
2126- HeapWord* limit = hr ->top_at_mark_start ();
2146+ HeapWord* limit = _cm ->top_at_mark_start (hr );
21272147
21282148 if (limit == bottom) {
21292149 // The region was collected underneath our feet.
0 commit comments