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;
}
};