# HG changeset patch # User zgu # Date 1546440714 18000 # Wed Jan 02 09:51:54 2019 -0500 # Node ID 9f081ae6c51a8dafb1f147d00adb748271fc4d16 # Parent 315f53a48199aedca79bbccbf7690acabf0f8c7f imported patch G1_8215299.patch diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp @@ -588,7 +588,8 @@ _num_active_tasks = active_tasks; // Need to update the three data structures below according to the // number of active threads for this phase. - _terminator = TaskTerminator((int) active_tasks, _task_queues); +// _terminator = TaskTerminator((int) active_tasks, _task_queues); + _terminator.terminator()->reset_for_reuse(active_tasks); _first_overflow_barrier_sync.set_n_workers((int) active_tasks); _second_overflow_barrier_sync.set_n_workers((int) active_tasks); } @@ -2178,7 +2179,9 @@ } bool G1CMTask::should_exit_termination() { - regular_clock_call(); + if (!regular_clock_call()) { + return true; + } // This is called when we are in the termination protocol. We should // quit if, for some reason, this task wants to abort or the global // stack is not empty (this means that we can get work from it). @@ -2189,12 +2192,14 @@ assert(_words_scanned >= _words_scanned_limit || _refs_reached >= _refs_reached_limit , "shouldn't have been called otherwise"); - regular_clock_call(); + if (!regular_clock_call()) { + set_has_aborted(); + } } -void G1CMTask::regular_clock_call() { +bool G1CMTask::regular_clock_call() { if (has_aborted()) { - return; + return false; } // First, we need to recalculate the words scanned and refs reached @@ -2205,21 +2210,19 @@ // (1) If an overflow has been flagged, then we abort. if (_cm->has_overflown()) { - set_has_aborted(); - return; + return false; } // If we are not concurrent (i.e. we're doing remark) we don't need // to check anything else. The other steps are only needed during // the concurrent marking phase. if (!_cm->concurrent()) { - return; + return true; } // (2) If marking has been aborted for Full GC, then we also abort. if (_cm->has_aborted()) { - set_has_aborted(); - return; + return false; } double curr_time_ms = os::elapsedVTime() * 1000.0; @@ -2228,17 +2231,15 @@ if (SuspendibleThreadSet::should_yield()) { // We should yield. To do this we abort the task. The caller is // responsible for yielding. - set_has_aborted(); - return; + return false; } // (5) We check whether we've reached our time quota. If we have, // then we abort. double elapsed_time_ms = curr_time_ms - _start_time_ms; if (elapsed_time_ms > _time_target_ms) { - set_has_aborted(); _has_timed_out = true; - return; + return false; } // (6) Finally, we check whether there are enough completed STAB @@ -2247,9 +2248,9 @@ if (!_draining_satb_buffers && satb_mq_set.process_completed_buffers()) { // we do need to process SATB buffers, we'll abort and restart // the marking task to do so - set_has_aborted(); - return; + return false; } + return true; } void G1CMTask::recalculate_limits() { @@ -2404,7 +2405,9 @@ // until we run out of buffers or we need to abort. while (!has_aborted() && satb_mq_set.apply_closure_to_completed_buffer(&satb_cl)) { - regular_clock_call(); + if(!regular_clock_call()) { + set_has_aborted(); + } } _draining_satb_buffers = false; @@ -2647,7 +2650,9 @@ // If the iteration is successful, give up the region. if (mr.is_empty()) { giveup_current_region(); - regular_clock_call(); + if (!regular_clock_call()) { + set_has_aborted(); + } } else if (_curr_region->is_humongous() && mr.start() == _curr_region->bottom()) { if (_next_mark_bitmap->is_marked(mr.start())) { // The object is marked - apply the closure @@ -2656,10 +2661,14 @@ // Even if this task aborted while scanning the humongous object // we can (and should) give up the current region. giveup_current_region(); - regular_clock_call(); + if (!regular_clock_call()) { + set_has_aborted(); + } } else if (_next_mark_bitmap->iterate(&bitmap_closure, mr)) { giveup_current_region(); - regular_clock_call(); + if (!regular_clock_call()) { + set_has_aborted(); + } } else { assert(has_aborted(), "currently the only way to do so"); // The only way to abort the bitmap iteration is to return @@ -2714,7 +2723,9 @@ // block of empty regions. So we need to call the regular clock // method once round the loop to make sure it's called // frequently enough. - regular_clock_call(); + if (!regular_clock_call()) { + set_has_aborted(); + } } if (!has_aborted() && _curr_region == NULL) { @@ -2792,6 +2803,7 @@ guarantee(_cm->mark_stack_empty(), "only way to reach here"); guarantee(_task_queue->size() == 0, "only way to reach here"); guarantee(!_cm->has_overflown(), "only way to reach here"); + guarantee(!has_aborted(), "Should never happen in completed case"); } else { // Apparently there's more work to do. Let's abort this task. It // will restart it and we can hopefully find more things to do. diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp @@ -727,7 +727,8 @@ // Supposed to be called regularly during a marking step as // it checks a bunch of conditions that might cause the marking step // to abort - void regular_clock_call(); + // Return true if the marking step should continue. Otherwise, return false to abort + bool regular_clock_call(); // Test whether obj might have already been passed over by the // mark bitmap scan, and so needs to be pushed onto the mark stack.