< prev index next >
src/share/vm/gc/g1/concurrentMark.cpp
Print this page
@@ -804,10 +804,11 @@
virtual bool doHeapRegion(HeapRegion* r) {
// This closure can be called concurrently to the mutator, so we must make sure
// that the result of the getNextMarkedWordAddress() call is compared to the
// value passed to it as limit to detect any found bits.
+ // end never changes in G1.
HeapWord* end = r->end();
return _bitmap->getNextMarkedWordAddress(r->bottom(), end) != end;
}
};
@@ -1341,10 +1342,12 @@
_cm->set_card_bitmap_range(_card_bm, start_idx, end_idx, true /* is_par */);
// Add the size of this object to the number of marked bytes.
marked_bytes += (size_t)obj_sz * HeapWordSize;
+ // This will happen if we are handling a humongous object that spans
+ // several heap regions.
if (obj_end > hr->end()) {
break;
}
// Find the next marked object after this one.
start = _bm->getNextMarkedWordAddress(obj_end, ntams);
@@ -1430,11 +1433,13 @@
size_t exp_marked_bytes = _calc_cl.region_marked_bytes();
size_t act_marked_bytes = hr->next_marked_bytes();
// We're not OK if expected marked bytes > actual marked bytes. It means
// we have missed accounting some objects during the actual marking.
- if (exp_marked_bytes > act_marked_bytes) {
+ // For start_humongous regions, the size of the whole object will be
+ // in exp_marked_bytes, so this check does not apply in this case.
+ if (exp_marked_bytes > act_marked_bytes && !hr->is_starts_humongous()) {
failures += 1;
}
// Verify the bit, for this region, in the actual and expected
// (which was just calculated) region bit maps.
@@ -2438,33 +2443,10 @@
// _heap_end will not change underneath our feet; it only changes at
// yield points.
while (finger < _heap_end) {
assert(_g1h->is_in_g1_reserved(finger), "invariant");
- // Note on how this code handles humongous regions. In the
- // normal case the finger will reach the start of a "starts
- // humongous" (SH) region. Its end will either be the end of the
- // last "continues humongous" (CH) region in the sequence, or the
- // standard end of the SH region (if the SH is the only region in
- // the sequence). That way claim_region() will skip over the CH
- // regions. However, there is a subtle race between a CM thread
- // executing this method and a mutator thread doing a humongous
- // object allocation. The two are not mutually exclusive as the CM
- // thread does not need to hold the Heap_lock when it gets
- // here. So there is a chance that claim_region() will come across
- // a free region that's in the progress of becoming a SH or a CH
- // region. In the former case, it will either
- // a) Miss the update to the region's end, in which case it will
- // visit every subsequent CH region, will find their bitmaps
- // empty, and do nothing, or
- // b) Will observe the update of the region's end (in which case
- // it will skip the subsequent CH regions).
- // If it comes across a region that suddenly becomes CH, the
- // scenario will be similar to b). So, the race between
- // claim_region() and a humongous object allocation might force us
- // to do a bit of unnecessary work (due to some unnecessary bitmap
- // iterations) but it should not introduce and correctness issues.
HeapRegion* curr_region = _g1h->heap_region_containing(finger);
// Above heap_region_containing may return NULL as we always scan claim
// until the end of the heap. In this case, just jump to the next region.
HeapWord* end = curr_region != NULL ? curr_region->end() : finger + HeapRegion::GrainWords;
@@ -2539,17 +2521,10 @@
}
// Verify the global finger
HeapWord* global_finger = finger();
if (global_finger != NULL && global_finger < _heap_end) {
- // The global finger always points to a heap region boundary. We
- // use heap_region_containing() to get the containing region
- // given that the global finger could be pointing to a free region
- // which subsequently becomes continues humongous. If that
- // happens, heap_region_containing() will return the bottom of the
- // corresponding starts humongous region and the check below will
- // not hold any more.
// Since we always iterate over all regions, we might get a NULL HeapRegion
// here.
HeapRegion* global_hr = _g1h->heap_region_containing(global_finger);
guarantee(global_hr == NULL || global_finger == global_hr->bottom(),
"global finger: " PTR_FORMAT " region: " HR_FORMAT,
< prev index next >