--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu May 29 14:31:28 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Wed Jun 04 14:16:20 2014 +0200
@@ -901,7 +901,7 @@
G1CollectedHeap* g1h = G1CollectedHeap::heap();
G1CollectorPolicy* g1p = g1h->g1_policy();
- clear_has_aborted();
+ _has_aborted = false;
#ifndef PRODUCT
if (G1PrintReachableAtInitialMark) {
@@ -3261,7 +3261,7 @@
}
_first_overflow_barrier_sync.abort();
_second_overflow_barrier_sync.abort();
- set_has_aborted();
+ _has_aborted = true;
SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
satb_mq_set.abandon_partial_marking();
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp Thu May 29 14:31:28 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp Wed Jun 04 14:16:20 2014 +0200
@@ -822,9 +822,7 @@
// Called to abort the marking cycle after a Full GC takes place.
void abort();
- bool has_aborted() { return _has_aborted; }
- void set_has_aborted() { _has_aborted = true; }
- void clear_has_aborted() { _has_aborted = false; }
+ bool has_aborted() { return _has_aborted; }
// This prints the global/local fingers. It is used for debugging.
NOT_PRODUCT(void print_finger();)
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu May 29 14:31:28 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Jun 04 14:16:20 2014 +0200
@@ -2174,14 +2174,20 @@
}
void G1CollectedHeap::stop() {
- // 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();
+#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.
_cm->root_regions()->abort();
_cm->root_regions()->wait_until_scan_finished();
stop_conc_gc_threads();
+#endif
}
size_t G1CollectedHeap::conservative_max_heap_alignment() {
--- a/hotspot/src/share/vm/runtime/java.cpp Thu May 29 14:31:28 2014 +0200
+++ b/hotspot/src/share/vm/runtime/java.cpp Wed Jun 04 14:16:20 2014 +0200
@@ -501,6 +501,9 @@
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();
@@ -515,8 +518,10 @@
StatSampler::disengage();
StatSampler::destroy();
- // Stop concurrent GC threads
- Universe::heap()->stop();
+ // 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().
// Print GC/heap related information.
if (PrintGCDetails) {
--- a/hotspot/src/share/vm/runtime/thread.cpp Thu May 29 14:31:28 2014 +0200
+++ b/hotspot/src/share/vm/runtime/thread.cpp Wed Jun 04 14:16:20 2014 +0200
@@ -3968,8 +3968,14 @@
// 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.
+ // 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.
MutexLocker ml(Heap_lock);