@@ -760,27 +760,71 @@ class G1ScanAndCountCodeBlobClosure : public CodeBlobClosure {
760760
761761// Heap region closure to be applied to all regions in the current collection set
762762// increment to fix up non-card related roots.
763- class G1ScanCollectionSetRegionClosure : public HeapRegionClosure {
763+ class G1ScanCodeRootsClosure : public HeapRegionClosure {
764764 G1ParScanThreadState* _pss;
765765 G1RemSetScanState* _scan_state;
766766
767- G1GCPhaseTimes::GCParPhases _scan_phase;
768- G1GCPhaseTimes::GCParPhases _code_roots_phase;
769-
770767 uint _worker_id;
771768
772769 size_t _code_roots_scanned;
773770
771+ public:
772+ G1ScanCodeRootsClosure (G1RemSetScanState* scan_state,
773+ G1ParScanThreadState* pss,
774+ uint worker_id) :
775+ _pss (pss),
776+ _scan_state (scan_state),
777+ _worker_id (worker_id),
778+ _code_roots_scanned (0 ) { }
779+
780+ bool do_heap_region (HeapRegion* r) {
781+ // Scan the code root list attached to the current region
782+ G1ScanAndCountCodeBlobClosure cl (_pss->closures ()->weak_codeblobs ());
783+ r->code_roots_do (&cl);
784+ _code_roots_scanned += cl.count ();
785+ return false ;
786+ }
787+
788+ size_t code_roots_scanned () const { return _code_roots_scanned; }
789+ };
790+
791+ void G1RemSet::scan_collection_set_code_roots (G1ParScanThreadState* pss,
792+ uint worker_id,
793+ G1GCPhaseTimes::GCParPhases coderoots_phase,
794+ G1GCPhaseTimes::GCParPhases objcopy_phase) {
795+ EventGCPhaseParallel event;
796+
797+ Tickspan code_root_scan_time;
798+ Tickspan code_root_trim_partially_time;
799+ G1EvacPhaseWithTrimTimeTracker timer (pss, code_root_scan_time, code_root_trim_partially_time);
800+
801+ G1GCPhaseTimes* p = _g1h->phase_times ();
802+
803+ G1ScanCodeRootsClosure cl (_scan_state, pss, worker_id);
804+ // Code roots work distribution occurs inside the iteration method. So scan all collection
805+ // set regions for all threads.
806+ _g1h->collection_set_iterate_increment_from (&cl, worker_id);
807+
808+ p->record_or_add_time_secs (coderoots_phase, worker_id, code_root_scan_time.seconds ());
809+ p->add_time_secs (objcopy_phase, worker_id, code_root_trim_partially_time.seconds ());
810+
811+ p->record_or_add_thread_work_item (coderoots_phase, worker_id, cl.code_roots_scanned (), G1GCPhaseTimes::CodeRootsScannedNMethods);
812+
813+ event.commit (GCId::current (), worker_id, G1GCPhaseTimes::phase_name (coderoots_phase));
814+ }
815+
816+ class G1ScanOptionalRemSetRootsClosure : public HeapRegionClosure {
817+ G1ParScanThreadState* _pss;
818+
819+ uint _worker_id;
820+
821+ G1GCPhaseTimes::GCParPhases _scan_phase;
822+
774823 size_t _opt_roots_scanned;
824+
775825 size_t _opt_refs_scanned;
776826 size_t _opt_refs_memory_used;
777827
778- Tickspan _code_root_scan_time;
779- Tickspan _code_trim_partially_time;
780-
781- Tickspan _rem_set_opt_root_scan_time;
782- Tickspan _rem_set_opt_trim_partially_time;
783-
784828 void scan_opt_rem_set_roots (HeapRegion* r) {
785829 G1OopStarChunkedList* opt_rem_set_list = _pss->oops_into_optional_region (r);
786830
@@ -791,92 +835,58 @@ class G1ScanCollectionSetRegionClosure : public HeapRegionClosure {
791835 }
792836
793837public:
794- G1ScanCollectionSetRegionClosure (G1RemSetScanState* scan_state,
795- G1ParScanThreadState* pss,
838+ G1ScanOptionalRemSetRootsClosure (G1ParScanThreadState* pss,
796839 uint worker_id,
797- G1GCPhaseTimes::GCParPhases scan_phase,
798- G1GCPhaseTimes::GCParPhases code_roots_phase) :
840+ G1GCPhaseTimes::GCParPhases scan_phase) :
799841 _pss (pss),
800- _scan_state (scan_state),
801- _scan_phase (scan_phase),
802- _code_roots_phase (code_roots_phase),
803842 _worker_id (worker_id),
804- _code_roots_scanned ( 0 ),
843+ _scan_phase (scan_phase ),
805844 _opt_roots_scanned (0 ),
806845 _opt_refs_scanned (0 ),
807- _opt_refs_memory_used (0 ),
808- _code_root_scan_time (),
809- _code_trim_partially_time (),
810- _rem_set_opt_root_scan_time (),
811- _rem_set_opt_trim_partially_time () { }
846+ _opt_refs_memory_used (0 ) { }
812847
813- bool do_heap_region (HeapRegion* r) {
814- // The individual references for the optional remembered set are per-worker, so we
815- // always need to scan them.
848+ bool do_heap_region (HeapRegion* r) override {
816849 if (r->has_index_in_opt_cset ()) {
817- EventGCPhaseParallel event;
818- G1EvacPhaseWithTrimTimeTracker timer (_pss, _rem_set_opt_root_scan_time, _rem_set_opt_trim_partially_time);
819850 scan_opt_rem_set_roots (r);
820-
821- event.commit (GCId::current (), _worker_id, G1GCPhaseTimes::phase_name (_scan_phase));
822- }
823-
824- // Scan code root remembered sets.
825- {
826- EventGCPhaseParallel event;
827- G1EvacPhaseWithTrimTimeTracker timer (_pss, _code_root_scan_time, _code_trim_partially_time);
828- G1ScanAndCountCodeBlobClosure cl (_pss->closures ()->weak_codeblobs ());
829-
830- // Scan the code root list attached to the current region
831- r->code_roots_do (&cl);
832-
833- _code_roots_scanned += cl.count ();
834-
835- event.commit (GCId::current (), _worker_id, G1GCPhaseTimes::phase_name (_code_roots_phase));
836851 }
837-
838852 return false ;
839853 }
840854
841- Tickspan code_root_scan_time () const { return _code_root_scan_time; }
842- Tickspan code_root_trim_partially_time () const { return _code_trim_partially_time; }
843-
844- size_t code_roots_scanned () const { return _code_roots_scanned; }
845-
846- Tickspan rem_set_opt_root_scan_time () const { return _rem_set_opt_root_scan_time; }
847- Tickspan rem_set_opt_trim_partially_time () const { return _rem_set_opt_trim_partially_time; }
848-
849855 size_t opt_roots_scanned () const { return _opt_roots_scanned; }
850856 size_t opt_refs_scanned () const { return _opt_refs_scanned; }
851857 size_t opt_refs_memory_used () const { return _opt_refs_memory_used; }
852858};
853859
854- void G1RemSet::scan_collection_set_regions (G1ParScanThreadState* pss,
855- uint worker_id,
856- G1GCPhaseTimes::GCParPhases scan_phase,
857- G1GCPhaseTimes::GCParPhases coderoots_phase,
858- G1GCPhaseTimes::GCParPhases objcopy_phase) {
859- G1ScanCollectionSetRegionClosure cl (_scan_state, pss, worker_id, scan_phase, coderoots_phase);
860- _g1h->collection_set_iterate_increment_from (&cl, worker_id);
860+ void G1RemSet::scan_collection_set_optional_roots (G1ParScanThreadState* pss,
861+ uint worker_id,
862+ G1GCPhaseTimes::GCParPhases scan_phase,
863+ G1GCPhaseTimes::GCParPhases objcopy_phase) {
864+ assert (scan_phase == G1GCPhaseTimes::OptScanHR, " must be" );
865+
866+ EventGCPhaseParallel event;
867+
868+ Tickspan rem_set_opt_root_scan_time;
869+ Tickspan rem_set_opt_trim_partially_time;
870+ G1EvacPhaseWithTrimTimeTracker timer (pss, rem_set_opt_root_scan_time, rem_set_opt_trim_partially_time);
861871
862872 G1GCPhaseTimes* p = _g1h->phase_times ();
863873
864- p->record_or_add_time_secs (scan_phase, worker_id, cl.rem_set_opt_root_scan_time ().seconds ());
865- p->record_or_add_time_secs (scan_phase, worker_id, cl.rem_set_opt_trim_partially_time ().seconds ());
874+ G1ScanOptionalRemSetRootsClosure cl (pss, worker_id, scan_phase);
875+ // The individual references for the optional remembered set are per-worker, so every worker
876+ // always need to scan all regions (no claimer).
877+ _g1h->collection_set_iterate_increment_from (&cl, worker_id);
866878
867- p->record_or_add_time_secs (coderoots_phase , worker_id, cl. code_root_scan_time () .seconds ());
868- p->record_or_add_thread_work_item (coderoots_phase , worker_id, cl. code_roots_scanned (), G1GCPhaseTimes::CodeRootsScannedNMethods );
879+ p->record_or_add_time_secs (scan_phase , worker_id, rem_set_opt_root_scan_time .seconds ());
880+ p->record_or_add_time_secs (objcopy_phase , worker_id, rem_set_opt_trim_partially_time. seconds () );
869881
870- p->add_time_secs (objcopy_phase, worker_id, cl.code_root_trim_partially_time ().seconds ());
882+ p->record_or_add_thread_work_item (scan_phase, worker_id, cl.opt_roots_scanned (), G1GCPhaseTimes::ScanHRFoundRoots);
883+ p->record_or_add_thread_work_item (scan_phase, worker_id, cl.opt_refs_scanned (), G1GCPhaseTimes::ScanHRScannedOptRefs);
884+ p->record_or_add_thread_work_item (scan_phase, worker_id, cl.opt_refs_memory_used (), G1GCPhaseTimes::ScanHRUsedMemory);
871885
872- // At this time we record some metrics only for the evacuations after the initial one.
873- if (scan_phase == G1GCPhaseTimes::OptScanHR) {
874- p->record_or_add_thread_work_item (scan_phase, worker_id, cl.opt_roots_scanned (), G1GCPhaseTimes::ScanHRFoundRoots);
875- p->record_or_add_thread_work_item (scan_phase, worker_id, cl.opt_refs_scanned (), G1GCPhaseTimes::ScanHRScannedOptRefs);
876- p->record_or_add_thread_work_item (scan_phase, worker_id, cl.opt_refs_memory_used (), G1GCPhaseTimes::ScanHRUsedMemory);
877- }
886+ event.commit (GCId::current (), worker_id, G1GCPhaseTimes::phase_name (scan_phase));
878887}
879888
889+
880890#ifdef ASSERT
881891void G1RemSet::assert_scan_top_is_null (uint hrm_index) {
882892 assert (_scan_state->scan_top (hrm_index) == nullptr ,
0 commit comments