comparison 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
comparison
equal deleted inserted replaced
5962:8a729074feae 5963:64bf7c8270cb
991 // first attempt (without holding the Heap_lock) here and the 991 // first attempt (without holding the Heap_lock) here and the
992 // follow-on attempt will be at the start of the next loop 992 // follow-on attempt will be at the start of the next loop
993 // iteration (after taking the Heap_lock). 993 // iteration (after taking the Heap_lock).
994 result = _mutator_alloc_region.attempt_allocation(word_size, 994 result = _mutator_alloc_region.attempt_allocation(word_size,
995 false /* bot_updates */); 995 false /* bot_updates */);
996 if (result != NULL ){ 996 if (result != NULL) {
997 return result; 997 return result;
998 } 998 }
999 999
1000 // Give a warning if we seem to be looping forever. 1000 // Give a warning if we seem to be looping forever.
1001 if ((QueuedAllocationWarningCount > 0) && 1001 if ((QueuedAllocationWarningCount > 0) &&
2435 VM_G1IncCollectionPause op(gc_count_before, 2435 VM_G1IncCollectionPause op(gc_count_before,
2436 0, /* word_size */ 2436 0, /* word_size */
2437 true, /* should_initiate_conc_mark */ 2437 true, /* should_initiate_conc_mark */
2438 g1_policy()->max_pause_time_ms(), 2438 g1_policy()->max_pause_time_ms(),
2439 cause); 2439 cause);
2440
2440 VMThread::execute(&op); 2441 VMThread::execute(&op);
2441 if (!op.pause_succeeded()) { 2442 if (!op.pause_succeeded()) {
2442 // Another GC got scheduled and prevented us from scheduling
2443 // the initial-mark GC. It's unlikely that the GC that
2444 // pre-empted us was also an initial-mark GC. So, we'll retry
2445 // the initial-mark GC.
2446
2447 if (full_gc_count_before == total_full_collections()) { 2443 if (full_gc_count_before == total_full_collections()) {
2448 retry_gc = true; 2444 retry_gc = op.should_retry_gc();
2449 } else { 2445 } else {
2450 // A Full GC happened while we were trying to schedule the 2446 // A Full GC happened while we were trying to schedule the
2451 // initial-mark GC. No point in starting a new cycle given 2447 // initial-mark GC. No point in starting a new cycle given
2452 // that the whole heap was collected anyway. 2448 // that the whole heap was collected anyway.
2449 }
2450
2451 if (retry_gc) {
2452 if (GC_locker::is_active_and_needs_gc()) {
2453 GC_locker::stall_until_clear();
2454 }
2453 } 2455 }
2454 } 2456 }
2455 } else { 2457 } else {
2456 if (cause == GCCause::_gc_locker 2458 if (cause == GCCause::_gc_locker
2457 DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) { 2459 DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) {