--- old/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp 2018-11-29 10:43:22.619961087 +0100 +++ new/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp 2018-11-29 10:43:22.184971667 +0100 @@ -224,35 +224,35 @@ template void iterate(Fn fn) const PRODUCT_RETURN; }; -// Root Regions are regions that are not empty at the beginning of a -// marking cycle and which we might collect during an evacuation pause -// while the cycle is active. Given that, during evacuation pauses, we -// do not copy objects that are explicitly marked, what we have to do -// for the root regions is to scan them and mark all objects reachable -// from them. According to the SATB assumptions, we only need to visit -// each object once during marking. So, as long as we finish this scan -// before the next evacuation pause, we can copy the objects from the -// root regions without having to mark them or do anything else to them. -// -// Currently, we only support root region scanning once (at the start -// of the marking cycle) and the root regions are all the survivor -// regions populated during the initial-mark pause. +// Root Regions are regions that contain objects from nTAMS to top. These are roots +// for marking, i.e. their referenced objects must be kept alive to maintain the +// SATB invariant. +// We could scan and mark them through during the initial-mark pause, but for +// pause time reasons we move this work to the concurrent phase. +// We need to complete this procedure before the next GC because it might determine +// that some of these "root objects" are dead, potentially dropping some required +// references. +// Root regions comprise of the complete contents of survivor regions, and any +// objects copied into old gen during GC. class G1CMRootRegions { -private: - const G1SurvivorRegions* _survivors; - G1ConcurrentMark* _cm; - - volatile bool _scan_in_progress; - volatile bool _should_abort; - volatile int _claimed_survivor_index; + HeapRegion** _root_regions; + uint _max_regions; + volatile size_t _cur_regions; + + volatile bool _scan_in_progress; + volatile bool _should_abort; + + volatile size_t _claimed_root_regions; void notify_scan_done(); public: G1CMRootRegions(); // We actually do most of the initialization in this method. - void init(const G1SurvivorRegions* survivors, G1ConcurrentMark* cm); + void reset(uint const max_regions); + void add(HeapRegion* hr); + // Reset the claiming / scanning of the root regions. void prepare_for_scan(); @@ -553,7 +553,7 @@ // them. void scan_root_regions(); - // Scan a single root region and mark everything reachable from it. + // Scan a single root region from nTAMS to top and mark everything reachable from it. void scan_root_region(HeapRegion* hr, uint worker_id); // Do concurrent phase of marking, to a tentative transitive closure.