Mercurial > hg > truffle
diff src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 5963:64bf7c8270cb
7147724: G1: hang in SurrogateLockerThread::manipulatePLL
Summary: Attempting to initiate a marking cycle when allocating a humongous object can, if a marking cycle is successfully initiated by another thread, result in the allocating thread spinning until the marking cycle is complete. Eliminate a deadlock between the main ConcurrentMarkThread, the SurrogateLocker thread, the VM thread, and a mutator thread waiting on the SecondaryFreeList_lock (while free regions are going to become available) by not manipulating the pending list lock during the prologue and epilogue of the cleanup pause.
Reviewed-by: brutisso, jcoomes, tonyp
author | johnc |
---|---|
date | Mon, 12 Mar 2012 14:59:00 -0700 |
parents | a9647476d1a4 |
children | 500023bd0818 |
line wrap: on
line diff
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Mar 16 16:14:04 2012 +0100 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Mon Mar 12 14:59:00 2012 -0700 @@ -993,7 +993,7 @@ // iteration (after taking the Heap_lock). result = _mutator_alloc_region.attempt_allocation(word_size, false /* bot_updates */); - if (result != NULL ){ + if (result != NULL) { return result; } @@ -2437,20 +2437,22 @@ true, /* should_initiate_conc_mark */ g1_policy()->max_pause_time_ms(), cause); + VMThread::execute(&op); if (!op.pause_succeeded()) { - // Another GC got scheduled and prevented us from scheduling - // the initial-mark GC. It's unlikely that the GC that - // pre-empted us was also an initial-mark GC. So, we'll retry - // the initial-mark GC. - if (full_gc_count_before == total_full_collections()) { - retry_gc = true; + retry_gc = op.should_retry_gc(); } else { // A Full GC happened while we were trying to schedule the // initial-mark GC. No point in starting a new cycle given // that the whole heap was collected anyway. } + + if (retry_gc) { + if (GC_locker::is_active_and_needs_gc()) { + GC_locker::stall_until_clear(); + } + } } } else { if (cause == GCCause::_gc_locker