@@ -760,27 +760,71 @@ class G1ScanAndCountCodeBlobClosure : public CodeBlobClosure {
760
760
761
761
// Heap region closure to be applied to all regions in the current collection set
762
762
// increment to fix up non-card related roots.
763
- class G1ScanCollectionSetRegionClosure : public HeapRegionClosure {
763
+ class G1ScanCodeRootsClosure : public HeapRegionClosure {
764
764
G1ParScanThreadState* _pss;
765
765
G1RemSetScanState* _scan_state;
766
766
767
- G1GCPhaseTimes::GCParPhases _scan_phase;
768
- G1GCPhaseTimes::GCParPhases _code_roots_phase;
769
-
770
767
uint _worker_id;
771
768
772
769
size_t _code_roots_scanned;
773
770
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
+
774
823
size_t _opt_roots_scanned;
824
+
775
825
size_t _opt_refs_scanned;
776
826
size_t _opt_refs_memory_used;
777
827
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
-
784
828
void scan_opt_rem_set_roots (HeapRegion* r) {
785
829
G1OopStarChunkedList* opt_rem_set_list = _pss->oops_into_optional_region (r);
786
830
@@ -791,92 +835,58 @@ class G1ScanCollectionSetRegionClosure : public HeapRegionClosure {
791
835
}
792
836
793
837
public:
794
- G1ScanCollectionSetRegionClosure (G1RemSetScanState* scan_state,
795
- G1ParScanThreadState* pss,
838
+ G1ScanOptionalRemSetRootsClosure (G1ParScanThreadState* pss,
796
839
uint worker_id,
797
- G1GCPhaseTimes::GCParPhases scan_phase,
798
- G1GCPhaseTimes::GCParPhases code_roots_phase) :
840
+ G1GCPhaseTimes::GCParPhases scan_phase) :
799
841
_pss (pss),
800
- _scan_state (scan_state),
801
- _scan_phase (scan_phase),
802
- _code_roots_phase (code_roots_phase),
803
842
_worker_id (worker_id),
804
- _code_roots_scanned ( 0 ),
843
+ _scan_phase (scan_phase ),
805
844
_opt_roots_scanned (0 ),
806
845
_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 ) { }
812
847
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 {
816
849
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);
819
850
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));
836
851
}
837
-
838
852
return false ;
839
853
}
840
854
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
-
849
855
size_t opt_roots_scanned () const { return _opt_roots_scanned; }
850
856
size_t opt_refs_scanned () const { return _opt_refs_scanned; }
851
857
size_t opt_refs_memory_used () const { return _opt_refs_memory_used; }
852
858
};
853
859
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);
861
871
862
872
G1GCPhaseTimes* p = _g1h->phase_times ();
863
873
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);
866
878
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 () );
869
881
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);
871
885
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));
878
887
}
879
888
889
+
880
890
#ifdef ASSERT
881
891
void G1RemSet::assert_scan_top_is_null (uint hrm_index) {
882
892
assert (_scan_state->scan_top (hrm_index) == nullptr ,
0 commit comments