--- old/src/share/vm/gc/g1/concurrentMark.cpp 2015-11-03 17:15:24.464154331 +0100 +++ new/src/share/vm/gc/g1/concurrentMark.cpp 2015-11-03 17:15:24.380153914 +0100 @@ -806,6 +806,7 @@ // 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; } @@ -1343,6 +1344,8 @@ // 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; } @@ -1432,7 +1435,9 @@ // 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; } @@ -2440,29 +2445,6 @@ 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 @@ -2541,13 +2523,6 @@ // 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);