--- old/src/share/vm/gc_implementation/g1/concurrentMark.cpp 2014-05-27 13:04:21.511191592 +0200 +++ new/src/share/vm/gc_implementation/g1/concurrentMark.cpp 2014-05-27 13:04:21.370103177 +0200 @@ -900,7 +900,7 @@ G1CollectedHeap* g1h = G1CollectedHeap::heap(); G1CollectorPolicy* g1p = g1h->g1_policy(); - _has_aborted = false; + clear_has_aborted(); #ifndef PRODUCT if (G1PrintReachableAtInitialMark) { @@ -3260,7 +3260,7 @@ } _first_overflow_barrier_sync.abort(); _second_overflow_barrier_sync.abort(); - _has_aborted = true; + set_has_aborted(); SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); satb_mq_set.abandon_partial_marking(); --- old/src/share/vm/gc_implementation/g1/concurrentMark.hpp 2014-05-27 13:04:22.321179695 +0200 +++ new/src/share/vm/gc_implementation/g1/concurrentMark.hpp 2014-05-27 13:04:22.180249330 +0200 @@ -822,7 +822,9 @@ // Called to abort the marking cycle after a Full GC takes place. void abort(); - bool has_aborted() { return _has_aborted; } + bool has_aborted() { return _has_aborted; } + void set_has_aborted() { _has_aborted = true; } + void clear_has_aborted() { _has_aborted = false; } // This prints the global/local fingers. It is used for debugging. NOT_PRODUCT(void print_finger();) --- old/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 2014-05-27 13:04:23.081184002 +0200 +++ new/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 2014-05-27 13:04:22.941219548 +0200 @@ -2173,20 +2173,14 @@ } void G1CollectedHeap::stop() { -#if 0 - // Stopping concurrent worker threads is currently disabled until - // some bugs in concurrent mark has been resolve. Without fixing - // those bugs first we risk haning during VM exit when trying to - // stop these threads. - - // Abort any ongoing concurrent root region scanning and stop all - // concurrent threads. We do this to make sure these threads do - // not continue to execute and access resources (e.g. gclog_or_tty) - // that are destroyed during shutdown. + // Abort any ongoing concurrent mark and stop all concurrent threads. + // We do this to make sure these threads do not continue to execute + // and access resources (e.g. gclog_or_tty) that are destroyed during + // shutdown. + _cm->set_has_aborted(); _cm->root_regions()->abort(); _cm->root_regions()->wait_until_scan_finished(); stop_conc_gc_threads(); -#endif } size_t G1CollectedHeap::conservative_max_heap_alignment() { --- old/src/share/vm/runtime/java.cpp 2014-05-27 13:04:23.931187878 +0200 +++ new/src/share/vm/runtime/java.cpp 2014-05-27 13:04:23.791223818 +0200 @@ -500,9 +500,6 @@ os::infinite_sleep(); } - // Stop any ongoing concurrent GC work - Universe::heap()->stop(); - // Terminate watcher thread - must before disenrolling any periodic task if (PeriodicTask::num_tasks() > 0) WatcherThread::stop(); @@ -517,10 +514,8 @@ StatSampler::disengage(); StatSampler::destroy(); - // We do not need to explicitly stop concurrent GC threads because the - // JVM will be taken down at a safepoint when such threads are inactive -- - // except for some concurrent G1 threads, see (comment in) - // Threads::destroy_vm(). + // Stop concurrent GC threads + Universe::heap()->stop(); // Print GC/heap related information. if (PrintGCDetails) { --- old/src/share/vm/runtime/thread.cpp 2014-05-27 13:04:24.671187432 +0200 +++ new/src/share/vm/runtime/thread.cpp 2014-05-27 13:04:24.530016584 +0200 @@ -3966,14 +3966,8 @@ // GC vm_operations can get caught at the safepoint, and the // heap is unparseable if they are caught. Grab the Heap_lock // to prevent this. The GC vm_operations will not be able to - // queue until after the vm thread is dead. - // After this point, we'll never emerge out of the safepoint before - // the VM exits, so concurrent GC threads do not need to be explicitly - // stopped; they remain inactive until the process exits. - // Note: some concurrent G1 threads may be running during a safepoint, - // but these will not be accessing the heap, just some G1-specific side - // data structures that are not accessed by any other threads but them - // after this point in a terminal safepoint. + // queue until after the vm thread is dead. After this point, + // we'll never emerge out of the safepoint before the VM exits. MutexLocker ml(Heap_lock);