--- old/src/share/vm/gc_implementation/g1/concurrentMark.cpp 2014-04-29 14:52:10.941193812 +0200 +++ new/src/share/vm/gc_implementation/g1/concurrentMark.cpp 2014-04-29 14:52:10.811216015 +0200 @@ -978,7 +978,9 @@ if (concurrent()) { SuspendibleThreadSet::leave(); } - _first_overflow_barrier_sync.enter(); + + bool barrier_aborted = !_first_overflow_barrier_sync.enter(); + if (concurrent()) { SuspendibleThreadSet::join(); } @@ -986,7 +988,11 @@ // more work if (verbose_low()) { - gclog_or_tty->print_cr("[%u] leaving first barrier", worker_id); + 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 we're executing the concurrent phase of marking, reset the marking @@ -995,7 +1001,10 @@ // If we reset here as a result of an overflow during the remark we will // see assertion failures from any subsequent set_concurrency_and_phase() // calls. - if (concurrent()) { + // If the barrier aborted we don't need to reset the marking state here + // since ConcurrentMark::abort() did that for us and we will now ignore + // the overflow condition and just abort the whole marking phase. + if (!barrier_aborted && concurrent()) { // let the task associated with with worker 0 do this if (worker_id == 0) { // task 0 is responsible for clearing the global data structures @@ -1026,14 +1035,20 @@ if (concurrent()) { SuspendibleThreadSet::leave(); } - _second_overflow_barrier_sync.enter(); + + 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()) { - gclog_or_tty->print_cr("[%u] leaving second barrier", worker_id); + 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); + } } } @@ -3240,6 +3255,8 @@ 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();