--- old/src/share/vm/gc/g1/concurrentMarkThread.cpp 2016-02-08 15:06:01.340847826 +0100 +++ new/src/share/vm/gc/g1/concurrentMarkThread.cpp 2016-02-08 15:06:01.228847821 +0100 @@ -141,9 +141,11 @@ // without the root regions have been scanned which would be a // correctness issue. - assert(!cm()->has_aborted(), "Aborting before root region scanning is finished not supported."); - GCConcPhaseTimer(_cm, "Concurrent Root Region Scanning"); - _cm->scanRootRegions(); + if (_cm->root_regions()->scan_in_progress()) { + assert(!cm()->has_aborted(), "Aborting before root region scanning is finished not supported."); + GCConcPhaseTimer(_cm, "Concurrent Root Region Scanning"); + _cm->scanRootRegions(); + } // It would be nice to use the GCTraceConcTime class here but // the "end" logging is inside the loop and not at the end of --- old/src/share/vm/gc/g1/g1ConcurrentMark.cpp 2016-02-08 15:06:01.544847834 +0100 +++ new/src/share/vm/gc/g1/g1ConcurrentMark.cpp 2016-02-08 15:06:01.432847830 +0100 @@ -372,12 +372,16 @@ return res; } -void G1CMRootRegions::cancel_scan() { +void G1CMRootRegions::notify_scan_done() { MutexLockerEx x(RootRegionScan_lock, Mutex::_no_safepoint_check_flag); _scan_in_progress = false; RootRegionScan_lock->notify_all(); } +void G1CMRootRegions::cancel_scan() { + notify_scan_done(); +} + void G1CMRootRegions::scan_finished() { assert(scan_in_progress(), "pre-condition"); @@ -387,11 +391,7 @@ } _next_survivor = NULL; - { - MutexLockerEx x(RootRegionScan_lock, Mutex::_no_safepoint_check_flag); - _scan_in_progress = false; - RootRegionScan_lock->notify_all(); - } + notify_scan_done(); } bool G1CMRootRegions::wait_until_scan_finished() { --- old/src/share/vm/gc/g1/g1ConcurrentMark.hpp 2016-02-08 15:06:01.784847844 +0100 +++ new/src/share/vm/gc/g1/g1ConcurrentMark.hpp 2016-02-08 15:06:01.676847840 +0100 @@ -229,6 +229,8 @@ volatile bool _should_abort; HeapRegion* volatile _next_survivor; + void notify_scan_done(); + public: G1CMRootRegions(); // We actually do most of the initialization in this method.