1.1 --- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp Thu Jan 12 00:06:47 2012 -0800 1.2 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp Wed Jan 25 12:58:23 2012 -0500 1.3 @@ -349,10 +349,62 @@ 1.4 high_verbose // per object verbose 1.5 } CMVerboseLevel; 1.6 1.7 +class YoungList; 1.8 + 1.9 +// Root Regions are regions that are not empty at the beginning of a 1.10 +// marking cycle and which we might collect during an evacuation pause 1.11 +// while the cycle is active. Given that, during evacuation pauses, we 1.12 +// do not copy objects that are explicitly marked, what we have to do 1.13 +// for the root regions is to scan them and mark all objects reachable 1.14 +// from them. According to the SATB assumptions, we only need to visit 1.15 +// each object once during marking. So, as long as we finish this scan 1.16 +// before the next evacuation pause, we can copy the objects from the 1.17 +// root regions without having to mark them or do anything else to them. 1.18 +// 1.19 +// Currently, we only support root region scanning once (at the start 1.20 +// of the marking cycle) and the root regions are all the survivor 1.21 +// regions populated during the initial-mark pause. 1.22 +class CMRootRegions VALUE_OBJ_CLASS_SPEC { 1.23 +private: 1.24 + YoungList* _young_list; 1.25 + ConcurrentMark* _cm; 1.26 + 1.27 + volatile bool _scan_in_progress; 1.28 + volatile bool _should_abort; 1.29 + HeapRegion* volatile _next_survivor; 1.30 + 1.31 +public: 1.32 + CMRootRegions(); 1.33 + // We actually do most of the initialization in this method. 1.34 + void init(G1CollectedHeap* g1h, ConcurrentMark* cm); 1.35 + 1.36 + // Reset the claiming / scanning of the root regions. 1.37 + void prepare_for_scan(); 1.38 + 1.39 + // Forces get_next() to return NULL so that the iteration aborts early. 1.40 + void abort() { _should_abort = true; } 1.41 + 1.42 + // Return true if the CM thread are actively scanning root regions, 1.43 + // false otherwise. 1.44 + bool scan_in_progress() { return _scan_in_progress; } 1.45 + 1.46 + // Claim the next root region to scan atomically, or return NULL if 1.47 + // all have been claimed. 1.48 + HeapRegion* claim_next(); 1.49 + 1.50 + // Flag that we're done with root region scanning and notify anyone 1.51 + // who's waiting on it. If aborted is false, assume that all regions 1.52 + // have been claimed. 1.53 + void scan_finished(); 1.54 + 1.55 + // If CM threads are still scanning root regions, wait until they 1.56 + // are done. Return true if we had to wait, false otherwise. 1.57 + bool wait_until_scan_finished(); 1.58 +}; 1.59 1.60 class ConcurrentMarkThread; 1.61 1.62 -class ConcurrentMark: public CHeapObj { 1.63 +class ConcurrentMark : public CHeapObj { 1.64 friend class ConcurrentMarkThread; 1.65 friend class CMTask; 1.66 friend class CMBitMapClosure; 1.67 @@ -400,6 +452,9 @@ 1.68 HeapWord* _heap_start; 1.69 HeapWord* _heap_end; 1.70 1.71 + // Root region tracking and claiming. 1.72 + CMRootRegions _root_regions; 1.73 + 1.74 // For gray objects 1.75 CMMarkStack _markStack; // Grey objects behind global finger. 1.76 CMRegionStack _regionStack; // Grey regions behind global finger. 1.77 @@ -553,9 +608,9 @@ 1.78 bool has_overflown() { return _has_overflown; } 1.79 void set_has_overflown() { _has_overflown = true; } 1.80 void clear_has_overflown() { _has_overflown = false; } 1.81 + bool restart_for_overflow() { return _restart_for_overflow; } 1.82 1.83 bool has_aborted() { return _has_aborted; } 1.84 - bool restart_for_overflow() { return _restart_for_overflow; } 1.85 1.86 // Methods to enter the two overflow sync barriers 1.87 void enter_first_sync_barrier(int task_num); 1.88 @@ -691,6 +746,8 @@ 1.89 // Returns true if there are any aborted memory regions. 1.90 bool has_aborted_regions(); 1.91 1.92 + CMRootRegions* root_regions() { return &_root_regions; } 1.93 + 1.94 bool concurrent_marking_in_progress() { 1.95 return _concurrent_marking_in_progress; 1.96 } 1.97 @@ -741,8 +798,17 @@ 1.98 // G1CollectedHeap 1.99 1.100 // This notifies CM that a root during initial-mark needs to be 1.101 - // grayed. It is MT-safe. 1.102 - inline void grayRoot(oop obj, size_t word_size, uint worker_id); 1.103 + // grayed. It is MT-safe. word_size is the size of the object in 1.104 + // words. It is passed explicitly as sometimes we cannot calculate 1.105 + // it from the given object because it might be in an inconsistent 1.106 + // state (e.g., in to-space and being copied). So the caller is 1.107 + // responsible for dealing with this issue (e.g., get the size from 1.108 + // the from-space image when the to-space image might be 1.109 + // inconsistent) and always passing the size. hr is the region that 1.110 + // contains the object and it's passed optionally from callers who 1.111 + // might already have it (no point in recalculating it). 1.112 + inline void grayRoot(oop obj, size_t word_size, 1.113 + uint worker_id, HeapRegion* hr = NULL); 1.114 1.115 // It's used during evacuation pauses to gray a region, if 1.116 // necessary, and it's MT-safe. It assumes that the caller has 1.117 @@ -793,6 +859,13 @@ 1.118 void checkpointRootsInitialPre(); 1.119 void checkpointRootsInitialPost(); 1.120 1.121 + // Scan all the root regions and mark everything reachable from 1.122 + // them. 1.123 + void scanRootRegions(); 1.124 + 1.125 + // Scan a single root region and mark everything reachable from it. 1.126 + void scanRootRegion(HeapRegion* hr, uint worker_id); 1.127 + 1.128 // Do concurrent phase of marking, to a tentative transitive closure. 1.129 void markFromRoots(); 1.130 1.131 @@ -974,6 +1047,10 @@ 1.132 1.133 // Counts the given memory region in the task/worker counting 1.134 // data structures for the given worker id. 1.135 + inline void count_region(MemRegion mr, HeapRegion* hr, uint worker_id); 1.136 + 1.137 + // Counts the given memory region in the task/worker counting 1.138 + // data structures for the given worker id. 1.139 inline void count_region(MemRegion mr, uint worker_id); 1.140 1.141 // Counts the given object in the given task/worker counting 1.142 @@ -995,6 +1072,12 @@ 1.143 // Attempts to mark the given object and, if successful, counts 1.144 // the object in the task/worker counting structures for the 1.145 // given worker id. 1.146 + inline bool par_mark_and_count(oop obj, size_t word_size, 1.147 + HeapRegion* hr, uint worker_id); 1.148 + 1.149 + // Attempts to mark the given object and, if successful, counts 1.150 + // the object in the task/worker counting structures for the 1.151 + // given worker id. 1.152 inline bool par_mark_and_count(oop obj, HeapRegion* hr, uint worker_id); 1.153 1.154 // Similar to the above routine but we don't know the heap region that