# HG changeset patch # User tschatzl # Date 1409238341 -7200 # Node ID edb5f3b38aabf58e977822a600fc95ac6c3aa14a # Parent c35aec39d08e2abdd81eaefc030d8325dc6d7d20 8054808: Bitmap verification sometimes fails after Full GC aborts concurrent mark. Summary: The verification code that checked whether no bitmap mark had been found re-read HeapRegion::end() after the check on the bitmap. Concurrent humongous object allocation could have changed HeapRegion::end() in the meantime. Fix this by using the actual end of the region instead of HeapRegion::end() for comparison. Reviewed-by: brutisso, jmasa diff -r c35aec39d08e -r edb5f3b38aab src/share/vm/gc_implementation/g1/concurrentMark.cpp --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp Wed Sep 03 08:44:47 2014 +0000 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu Aug 28 17:05:41 2014 +0200 @@ -887,7 +887,16 @@ } virtual bool doHeapRegion(HeapRegion* r) { - return _bitmap->getNextMarkedWordAddress(r->bottom(), r->end()) != r->end(); + // 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. + // We can use the region's orig_end() for the limit and the comparison value + // as it always contains the "real" end of the region that never changes and + // has no side effects. + // Due to the latter, there can also be no problem with the compiler generating + // reloads of the orig_end() call. + HeapWord* end = r->orig_end(); + return _bitmap->getNextMarkedWordAddress(r->bottom(), end) != end; } }; diff -r c35aec39d08e -r edb5f3b38aab src/share/vm/gc_implementation/g1/heapRegion.hpp --- a/src/share/vm/gc_implementation/g1/heapRegion.hpp Wed Sep 03 08:44:47 2014 +0000 +++ b/src/share/vm/gc_implementation/g1/heapRegion.hpp Thu Aug 28 17:05:41 2014 +0200 @@ -570,7 +570,7 @@ void set_next_dirty_cards_region(HeapRegion* hr) { _next_dirty_cards_region = hr; } bool is_on_dirty_cards_region_list() const { return get_next_dirty_cards_region() != NULL; } - HeapWord* orig_end() { return _orig_end; } + HeapWord* orig_end() const { return _orig_end; } // Reset HR stuff to default values. void hr_clear(bool par, bool clear_space, bool locked = false);