--- old/src/share/vm/gc_implementation/g1/concurrentMark.cpp 2014-07-14 09:54:08.853583224 +0200 +++ new/src/share/vm/gc_implementation/g1/concurrentMark.cpp 2014-07-14 09:54:08.768580739 +0200 @@ -891,6 +891,10 @@ guarantee(!g1h->mark_in_progress(), "invariant"); } +bool ConcurrentMark::nextMarkBitmapIsClear() { + return _nextMarkBitMap->getNextMarkedWordAddress(_heap_start, _heap_end) == _heap_end; +} + class NoteStartOfMarkHRClosure: public HeapRegionClosure { public: bool doHeapRegion(HeapRegion* r) { --- old/src/share/vm/gc_implementation/g1/concurrentMark.hpp 2014-07-14 09:54:09.477601466 +0200 +++ new/src/share/vm/gc_implementation/g1/concurrentMark.hpp 2014-07-14 09:54:09.394599039 +0200 @@ -736,6 +736,9 @@ // Clear the next marking bitmap (will be called concurrently). void clearNextBitmap(); + // Return whether the next mark bitmap has no marks set. + bool nextMarkBitmapIsClear(); + // These two do the work that needs to be done before and after the // initial root checkpoint. Since this checkpoint can be done at two // different points (i.e. an explicit pause or piggy-backed on a --- old/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp 2014-07-14 09:54:10.027617544 +0200 +++ new/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp 2014-07-14 09:54:09.946615176 +0200 @@ -283,7 +283,7 @@ SuspendibleThreadSetJoiner sts; _cm->clearNextBitmap(); } else { - g1h->check_bitmaps("Reset bitmaps"); + assert(!G1VerifyBitmaps || _cm->nextMarkBitmapIsClear(), "Next mark bitmap must be clear"); } }