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

*** 61,71 **** VirtualSpace _virtual_space; // underlying the bit map BitMap _bm; // the bit map itself public: // constructor ! CMBitMapRO(ReservedSpace rs, int shifter); enum { do_yield = true }; // inquiries HeapWord* startWord() const { return _bmStartWord; } --- 61,71 ---- VirtualSpace _virtual_space; // underlying the bit map BitMap _bm; // the bit map itself public: // constructor ! CMBitMapRO(int shifter); enum { do_yield = true }; // inquiries HeapWord* startWord() const { return _bmStartWord; }
*** 115,126 **** class CMBitMap : public CMBitMapRO { public: // constructor ! CMBitMap(ReservedSpace rs, int shifter) : ! CMBitMapRO(rs, shifter) {} // write marks void mark(HeapWord* addr) { assert(_bmStartWord <= addr && addr < (_bmStartWord + _bmWordSize), "outside underlying space?"); --- 115,129 ---- class CMBitMap : public CMBitMapRO { public: // constructor ! 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,181 **** // 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). class CMMarkStack VALUE_OBJ_CLASS_SPEC { 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; DEBUG_ONLY(bool _drain_in_progress;) DEBUG_ONLY(bool _drain_in_progress_yields;) public: CMMarkStack(ConcurrentMark* cm); ~CMMarkStack(); ! void allocate(size_t size); oop pop() { if (!isEmpty()) { return _base[--_index] ; } --- 156,191 ---- // 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 ConcurrentMarking in the G1 collector. class CMMarkStack VALUE_OBJ_CLASS_SPEC { + 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(); ! #ifndef PRODUCT ! jint max_depth() const { ! return _max_depth; ! } ! #endif ! ! bool allocate(size_t capacity); oop pop() { if (!isEmpty()) { return _base[--_index] ; }
*** 234,243 **** --- 244,259 ---- 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,351 **** --- 358,368 ---- }; 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,584 **** --- 592,604 ---- // 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,644 **** // 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(); ConcurrentMarkThread* cmThread() { return _cmThread; } CMBitMapRO* prevMarkBitMap() const { return _prevMarkBitMap; } --- 654,664 ---- // 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(G1CollectedHeap* g1h, ReservedSpace heap_rs); ~ConcurrentMark(); ConcurrentMarkThread* cmThread() { return _cmThread; } CMBitMapRO* prevMarkBitMap() const { return _prevMarkBitMap; }
*** 905,914 **** --- 925,939 ---- // 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();