src/share/vm/gc_implementation/g1/concurrentMark.hpp

changeset 3464
eff609af17d7
parent 3463
d30fa85f9994
child 3691
2a0172480595
     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

mercurial