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

Print this page
rev 2724 : 6484965: G1: piggy-back liveness accounting phase on marking
Summary: Remove the separate counting phase of concurrent marking by tracking the amount of marked bytes and the cards spanned by marked objects in marking task/worker thread local data structures, which are updated as individual objects are marked.
Reviewed-by:

*** 846,856 **** // structures. void finalize_for_evac_failure(); // An attempt to evacuate "obj" has failed; take necessary steps. oop handle_evacuation_failure_par(OopsInHeapRegionClosure* cl, oop obj, ! bool should_mark_root); void handle_evacuation_failure_common(oop obj, markOop m); // ("Weak") Reference processing support. // // G1 has 2 instances of the referece processor class. One --- 846,857 ---- // structures. void finalize_for_evac_failure(); // An attempt to evacuate "obj" has failed; take necessary steps. oop handle_evacuation_failure_par(OopsInHeapRegionClosure* cl, oop obj, ! bool should_mark_root, ! int worker_i); void handle_evacuation_failure_common(oop obj, markOop m); // ("Weak") Reference processing support. // // G1 has 2 instances of the referece processor class. One
*** 1662,1671 **** --- 1663,1684 ---- HeapWord* _start_word; // size of a GCLab in words size_t _gclab_word_size; + // The size of the marked objects in this bitmap + size_t _marked_bytes; + + // Card bitmap associated with cards spanned by the live objects. + // It's sized for _gclab_word_size _plus_ 1 additional card + // in case the lab does not start at a card boundary + BitMap _card_bm; + + // Card number of the base of the LAB. Used to encode + // indices into the bitmap above. + intptr_t _bottom_card_num; + static int shifter() { return MinObjAlignment - 1; } // how many heap words does a single bitmap word corresponds to?
*** 1691,1711 **** // starts from the middle of the bitmap, we need to add enough // space (i.e. up to a bitmap word) to ensure that we have // enough bits in the bitmap. return bits_in_bitmap + BitsPerWord - 1; } public: GCLabBitMap(HeapWord* heap_start, size_t gclab_word_size) : BitMap(bitmap_size_in_bits(gclab_word_size)), _cm(G1CollectedHeap::heap()->concurrent_mark()), _shifter(shifter()), _bitmap_word_covers_words(bitmap_word_covers_words()), _heap_start(heap_start), _gclab_word_size(gclab_word_size), _real_start_word(NULL), _real_end_word(NULL), ! _start_word(NULL) { guarantee( size_in_words() >= bitmap_size_in_words(), "just making sure"); } --- 1704,1730 ---- // starts from the middle of the bitmap, we need to add enough // space (i.e. up to a bitmap word) to ensure that we have // enough bits in the bitmap. return bits_in_bitmap + BitsPerWord - 1; } + public: GCLabBitMap(HeapWord* heap_start, size_t gclab_word_size) : BitMap(bitmap_size_in_bits(gclab_word_size)), _cm(G1CollectedHeap::heap()->concurrent_mark()), _shifter(shifter()), _bitmap_word_covers_words(bitmap_word_covers_words()), _heap_start(heap_start), _gclab_word_size(gclab_word_size), _real_start_word(NULL), _real_end_word(NULL), ! _start_word(NULL), ! _marked_bytes(0), ! _card_bm((((gclab_word_size * BytesPerWord) + CardTableModRefBS::card_size - 1) >> ! CardTableModRefBS::card_shift) + 1, ! false /* in_resource_area*/), ! _bottom_card_num(0) { guarantee( size_in_words() >= bitmap_size_in_words(), "just making sure"); }
*** 1734,1753 **** (_start_word + _gclab_word_size + _bitmap_word_covers_words) > _real_end_word; return ret2; } ! inline bool mark(HeapWord* addr) { guarantee(use_local_bitmaps, "invariant"); assert(fields_well_formed(), "invariant"); if (addr >= _real_start_word && addr < _real_end_word) { assert(!isMarked(addr), "should not have already been marked"); // first mark it on the bitmap at_put(heapWordToOffset(addr), true); return true; } else { return false; } } --- 1753,1791 ---- (_start_word + _gclab_word_size + _bitmap_word_covers_words) > _real_end_word; return ret2; } ! inline bool mark(HeapWord* addr, size_t obj_size) { guarantee(use_local_bitmaps, "invariant"); assert(fields_well_formed(), "invariant"); if (addr >= _real_start_word && addr < _real_end_word) { assert(!isMarked(addr), "should not have already been marked"); // first mark it on the bitmap at_put(heapWordToOffset(addr), true); + MemRegion mr(addr, obj_size); + + // Add to the marked_bytes total + _marked_bytes += mr.byte_size(); + + // Set the bits associated with the cards spanned by the + // object + intptr_t start_card_num = + intptr_t(uintptr_t(mr.start()) >> CardTableModRefBS::card_shift); + intptr_t last_card_num = + intptr_t(uintptr_t(mr.last()) >> CardTableModRefBS::card_shift); + + BitMap::idx_t start_idx = start_card_num - _bottom_card_num; + BitMap::idx_t last_idx = last_card_num - _bottom_card_num; + + _card_bm.set_range(start_idx, last_idx); + // set_range is exclusive so set the bit for last_idx + _card_bm.set_bit(last_idx); + return true; } else { return false; } }
*** 1769,1778 **** --- 1807,1823 ---- size_t diff = pointer_delta(start, _heap_start) % _bitmap_word_covers_words; _start_word = start - diff; + // Initialize _bottom_card_num for the card bitmap + _bottom_card_num = + intptr_t(uintptr_t(_real_start_word) >> CardTableModRefBS::card_shift); + + _marked_bytes = 0; + _card_bm.clear(); + assert(fields_well_formed(), "invariant"); } #ifndef PRODUCT void verify() {
*** 1780,1790 **** GCLabBitMapClosure cl(_cm, this); iterate(&cl); } #endif // PRODUCT ! void retire() { guarantee(use_local_bitmaps, "invariant"); assert(fields_well_formed(), "invariant"); if (_start_word != NULL) { CMBitMap* mark_bitmap = _cm->nextMarkBitMap(); --- 1825,1835 ---- GCLabBitMapClosure cl(_cm, this); iterate(&cl); } #endif // PRODUCT ! void retire(int worker_i) { guarantee(use_local_bitmaps, "invariant"); assert(fields_well_formed(), "invariant"); if (_start_word != NULL) { CMBitMap* mark_bitmap = _cm->nextMarkBitMap();
*** 1794,1804 **** mark_bitmap->mostly_disjoint_range_union(this, 0, // always start from the start of the bitmap _start_word, gclab_real_word_size()); ! _cm->grayRegionIfNecessary(MemRegion(_real_start_word, _real_end_word)); #ifndef PRODUCT if (use_local_bitmaps && verify_local_bitmaps) verify(); #endif // PRODUCT --- 1839,1862 ---- mark_bitmap->mostly_disjoint_range_union(this, 0, // always start from the start of the bitmap _start_word, gclab_real_word_size()); ! ! // Note that not all objects copied into the LAB will have a bit set ! // in the LAB bitmap (the LAB bitmap is used to propagate marks). ! // So we can't just add the entire lab and its bitmap to the count ! // data. The marking information has been recorded in _marked_bytes ! // and _card_bm. ! MemRegion lab_region(_real_start_word, _real_end_word); ! _cm->add_to_count_data_for_region(lab_region, ! &_card_bm, ! _bottom_card_num, ! _marked_bytes, ! worker_i); ! ! _cm->grayRegionIfNecessary(lab_region); #ifndef PRODUCT if (use_local_bitmaps && verify_local_bitmaps) verify(); #endif // PRODUCT
*** 1816,1833 **** class G1ParGCAllocBuffer: public ParGCAllocBuffer { private: bool _retired; bool _should_mark_objects; GCLabBitMap _bitmap; public: ! G1ParGCAllocBuffer(size_t gclab_word_size); ! inline bool mark(HeapWord* addr) { guarantee(use_local_bitmaps, "invariant"); assert(_should_mark_objects, "invariant"); ! return _bitmap.mark(addr); } inline void set_buf(HeapWord* buf) { if (use_local_bitmaps && _should_mark_objects) { _bitmap.set_buffer(buf); --- 1874,1892 ---- class G1ParGCAllocBuffer: public ParGCAllocBuffer { private: bool _retired; bool _should_mark_objects; GCLabBitMap _bitmap; + int _worker_i; public: ! G1ParGCAllocBuffer(size_t gclab_word_size, int worker_i); ! inline bool mark(HeapWord* addr, size_t obj_size) { guarantee(use_local_bitmaps, "invariant"); assert(_should_mark_objects, "invariant"); ! return _bitmap.mark(addr, obj_size); } inline void set_buf(HeapWord* buf) { if (use_local_bitmaps && _should_mark_objects) { _bitmap.set_buffer(buf);
*** 1838,1848 **** inline void retire(bool end_of_gc, bool retain) { if (_retired) return; if (use_local_bitmaps && _should_mark_objects) { ! _bitmap.retire(); } ParGCAllocBuffer::retire(end_of_gc, retain); _retired = true; } }; --- 1897,1907 ---- inline void retire(bool end_of_gc, bool retain) { if (_retired) return; if (use_local_bitmaps && _should_mark_objects) { ! _bitmap.retire(_worker_i); } ParGCAllocBuffer::retire(end_of_gc, retain); _retired = true; } };