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

Print this page
rev 3708 : 8000244: G1: Ergonomically set MarkStackSize and use virtual space for global marking stack
Summary: Set the value of MarkStackSize to a value based on the number of parallel marking threads with a reasonable minimum. Expand the marking stack if we have to restart marking due to an overflow up to a reasonable maximum. Allocate the underlying space for the marking stack from virtual memory.
Reviewed-by: jmasa
rev 3709 : imported patch reuse-old-marking-stack

@@ -61,11 +61,11 @@
   VirtualSpace _virtual_space; // underlying the bit map
   BitMap    _bm;               // the bit map itself
 
  public:
   // constructor
-  CMBitMapRO(ReservedSpace rs, int shifter);
+  CMBitMapRO(int shifter);
 
   enum { do_yield = true };
 
   // inquiries
   HeapWord* startWord()   const { return _bmStartWord; }

@@ -115,12 +115,15 @@
 
 class CMBitMap : public CMBitMapRO {
 
  public:
   // constructor
-  CMBitMap(ReservedSpace rs, int shifter) :
-    CMBitMapRO(rs, shifter) {}
+  CMBitMap(int shifter) :
+    CMBitMapRO(shifter) {}
+
+  // Allocates the back store for the marking bitmap
+  bool allocate(ReservedSpace heap_rs);
 
   // write marks
   void mark(HeapWord* addr) {
     assert(_bmStartWord <= addr && addr < (_bmStartWord + _bmWordSize),
            "outside underlying space?");

@@ -153,29 +156,37 @@
   // the run.  If there is no "1" bit at or after "addr", return an empty
   // MemRegion.
   MemRegion getAndClearMarkedRegion(HeapWord* addr, HeapWord* end_addr);
 };
 
-// Represents a marking stack used by the CM collector.
-// Ideally this should be GrowableArray<> just like MSC's marking stack(s).
+// Represents a marking stack used by ConcurrentMarking in the G1 collector.
 class CMMarkStack VALUE_OBJ_CLASS_SPEC {
+  ReservedSpace _rs;
+  VirtualSpace _virtual_space;   // Underlying backing store for actual stack
   ConcurrentMark* _cm;
   oop*   _base;        // bottom of stack
   jint   _index;       // one more than last occupied index
   jint   _capacity;    // max #elements
   jint   _saved_index; // value of _index saved at start of GC
   NOT_PRODUCT(jint _max_depth;)  // max depth plumbed during run
 
   bool   _overflow;
+  bool  _should_expand;
   DEBUG_ONLY(bool _drain_in_progress;)
   DEBUG_ONLY(bool _drain_in_progress_yields;)
 
  public:
   CMMarkStack(ConcurrentMark* cm);
   ~CMMarkStack();
 
-  void allocate(size_t size);
+#ifndef PRODUCT
+  jint max_depth() const {
+    return _max_depth;
+  }
+#endif
+
+  bool allocate(size_t capacity);
 
   oop pop() {
     if (!isEmpty()) {
       return _base[--_index] ;
     }

@@ -234,10 +245,16 @@
   int maxElems()    { return _capacity; }
 
   bool overflow() { return _overflow; }
   void clear_overflow() { _overflow = false; }
 
+  bool should_expand() const { return _should_expand; }
+  void set_should_expand();
+
+  // Expand the stack, typically in response to an overflow condition
+  void expand();
+
   int  size() { return _index; }
 
   void setEmpty()   { _index = 0; clear_overflow(); }
 
   // Record the current index.

@@ -342,10 +359,11 @@
 };
 
 class ConcurrentMarkThread;
 
 class ConcurrentMark: public CHeapObj<mtGC> {
+  friend class CMMarkStack;
   friend class ConcurrentMarkThread;
   friend class CMTask;
   friend class CMBitMapClosure;
   friend class CMGlobalObjectClosure;
   friend class CMRemarkTask;

@@ -575,10 +593,13 @@
 
   // Card index of the bottom of the G1 heap. Used for biasing indices into
   // the card bitmaps.
   intptr_t _heap_bottom_card_num;
 
+  // Set to true when initialization is complete
+  bool _completed_initialization;
+
 public:
   // Manipulation of the global mark stack.
   // Notice that the first mark_stack_push is CAS-based, whereas the
   // two below are Mutex-based. This is OK since the first one is only
   // called during evacuation pauses and doesn't compete with the

@@ -634,11 +655,11 @@
   // Attempts to steal an object from the task queues of other tasks
   bool try_stealing(uint worker_id, int* hash_seed, oop& obj) {
     return _task_queues->steal(worker_id, hash_seed, obj);
   }
 
-  ConcurrentMark(ReservedSpace rs, uint max_regions);
+  ConcurrentMark(G1CollectedHeap* g1h, ReservedSpace heap_rs);
   ~ConcurrentMark();
 
   ConcurrentMarkThread* cmThread() { return _cmThread; }
 
   CMBitMapRO* prevMarkBitMap() const { return _prevMarkBitMap; }

@@ -905,10 +926,15 @@
   // Similar to the above routine but we don't know the heap region that
   // contains the object to be marked/counted, which this routine looks up.
   // Should *not* be called from parallel code.
   inline bool mark_and_count(oop obj);
 
+  // Returns true if initialization was successfully completed.
+  bool completed_initialization() const {
+    return _completed_initialization;
+  }
+
 protected:
   // Clear all the per-task bitmaps and arrays used to store the
   // counting data.
   void clear_all_count_data();