src/share/vm/gc_implementation/g1/concurrentMark.cpp

Print this page
rev 6345 : 8040803: G1: Concurrent mark hangs when mark stack overflows
Reviewed-by: TDB

*** 976,995 **** } if (concurrent()) { SuspendibleThreadSet::leave(); } ! _first_overflow_barrier_sync.enter(); if (concurrent()) { SuspendibleThreadSet::join(); } // at this point everyone should have synced up and not be doing any // more work if (verbose_low()) { gclog_or_tty->print_cr("[%u] leaving first barrier", worker_id); } // If we're executing the concurrent phase of marking, reset the marking // state; otherwise the marking state is reset after reference processing, // during the remark pause. // If we reset here as a result of an overflow during the remark we will --- 976,1007 ---- } if (concurrent()) { SuspendibleThreadSet::leave(); } ! ! bool barrier_aborted = !_first_overflow_barrier_sync.enter(); ! if (concurrent()) { SuspendibleThreadSet::join(); } // at this point everyone should have synced up and not be doing any // more work if (verbose_low()) { + if (barrier_aborted) { + gclog_or_tty->print_cr("[%u] aborted first barrier", worker_id); + } else { gclog_or_tty->print_cr("[%u] leaving first barrier", worker_id); } + } + + if (barrier_aborted) { + // If the barrier aborted we ignore the overflow condition and + // just abort the whole marking phase as quickly as possible. + return; + } // If we're executing the concurrent phase of marking, reset the marking // state; otherwise the marking state is reset after reference processing, // during the remark pause. // If we reset here as a result of an overflow during the remark we will
*** 1024,1042 **** } if (concurrent()) { SuspendibleThreadSet::leave(); } ! _second_overflow_barrier_sync.enter(); if (concurrent()) { SuspendibleThreadSet::join(); } // at this point everything should be re-initialized and ready to go if (verbose_low()) { gclog_or_tty->print_cr("[%u] leaving second barrier", worker_id); } } #ifndef PRODUCT void ForceOverflowSettings::init() { _num_remaining = G1ConcMarkForceOverflow; --- 1036,1060 ---- } if (concurrent()) { SuspendibleThreadSet::leave(); } ! ! bool barrier_aborted = !_second_overflow_barrier_sync.enter(); ! if (concurrent()) { SuspendibleThreadSet::join(); } // at this point everything should be re-initialized and ready to go if (verbose_low()) { + if (barrier_aborted) { + gclog_or_tty->print_cr("[%u] aborted second barrier", worker_id); + } else { gclog_or_tty->print_cr("[%u] leaving second barrier", worker_id); } + } } #ifndef PRODUCT void ForceOverflowSettings::init() { _num_remaining = G1ConcMarkForceOverflow;
*** 3238,3247 **** --- 3256,3267 ---- // Empty mark stack reset_marking_state(); for (uint i = 0; i < _max_worker_id; ++i) { _tasks[i]->clear_region_fields(); } + _first_overflow_barrier_sync.abort(); + _second_overflow_barrier_sync.abort(); _has_aborted = true; SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); satb_mq_set.abandon_partial_marking(); // This can be called either during or outside marking, we'll read