--- old/src/share/vm/gc/g1/g1ConcurrentMark.cpp 2017-03-01 15:41:29.779389990 -0500 +++ new/src/share/vm/gc/g1/g1ConcurrentMark.cpp 2017-03-01 15:41:28.507316651 -0500 @@ -414,7 +414,6 @@ _task_queues(new G1CMTaskQueueSet((int) _max_worker_id)), _terminator(ParallelTaskTerminator((int) _max_worker_id, _task_queues)), - _has_overflown(false), _concurrent(false), _has_aborted(false), _restart_for_overflow(false), @@ -592,14 +591,9 @@ } -void G1ConcurrentMark::reset_marking_state(bool clear_overflow) { +void G1ConcurrentMark::reset_marking_state() { _global_mark_stack.set_should_expand(has_overflown()); _global_mark_stack.set_empty(); // Also clears the overflow stack's overflow flag - if (clear_overflow) { - clear_has_overflown(); - } else { - assert(has_overflown(), "pre-condition"); - } _finger = _heap_start; for (uint i = 0; i < _max_worker_id; ++i) { @@ -883,7 +877,7 @@ // not clear the overflow flag since we rely on it being true when // we exit this method to abort the pause and restart concurrent // marking. - reset_marking_state(true /* clear_overflow */); + reset_marking_state(); log_info(gc, marking)("Concurrent Mark reset for overflow"); } @@ -1752,12 +1746,6 @@ assert(_global_mark_stack.is_out_of_memory() || _global_mark_stack.is_empty(), "Mark stack should be empty (unless it is out of memory)"); - if (_global_mark_stack.is_out_of_memory()) { - // This should have been done already when we tried to push an - // entry on to the global mark stack. But let's do it again. - set_has_overflown(); - } - assert(rp->num_q() == active_workers, "why not"); rp->enqueue_discovered_references(executor); @@ -2931,7 +2919,6 @@ 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(!_cm->mark_stack_overflow(), "only way to reach here"); } 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. --- old/src/share/vm/gc/g1/g1ConcurrentMark.hpp 2017-03-01 15:41:33.431600552 -0500 +++ new/src/share/vm/gc/g1/g1ConcurrentMark.hpp 2017-03-01 15:41:32.239531825 -0500 @@ -192,6 +192,8 @@ // NULL if out of memory. OopChunk* allocate_new_chunk(); + // This is set by any task, when an overflow on the global data + // structures is detected volatile bool _out_of_memory; // Atomically add the given chunk to the list. @@ -386,9 +388,6 @@ WorkGangBarrierSync _first_overflow_barrier_sync; WorkGangBarrierSync _second_overflow_barrier_sync; - // This is set by any task, when an overflow on the global data - // structures is detected - volatile bool _has_overflown; // True: marking is concurrent, false: we're in remark volatile bool _concurrent; // Set at the end of a Full GC so that marking aborts @@ -432,7 +431,7 @@ // Resets all the marking data structures. Called when we have to restart // marking or when marking completes (via set_non_marking_state below). - void reset_marking_state(bool clear_overflow = true); + void reset_marking_state(); // We do this after we're done with marking so that the marking data // structures are initialized to a sensible and predictable state. @@ -505,9 +504,8 @@ // Access / manipulation of the overflow flag which is set to // indicate that the global stack has overflown - bool has_overflown() { return _has_overflown; } - void set_has_overflown() { _has_overflown = true; } - void clear_has_overflown() { _has_overflown = false; } + bool has_overflown() { return _global_mark_stack.is_out_of_memory(); } + void clear_has_overflown() { _global_mark_stack.clear_out_of_memory(); } bool restart_for_overflow() { return _restart_for_overflow; } // Methods to enter the two overflow sync barriers @@ -532,18 +530,13 @@ // The push and pop operations are used by tasks for transfers // between task-local queues and the global mark stack. bool mark_stack_push(oop* arr) { - if (!_global_mark_stack.par_push_chunk(arr)) { - set_has_overflown(); - return false; - } - return true; + return _global_mark_stack.par_push_chunk(arr); } bool mark_stack_pop(oop* arr) { return _global_mark_stack.par_pop_chunk(arr); } size_t mark_stack_size() { return _global_mark_stack.size(); } size_t partial_mark_stack_size_target() { return _global_mark_stack.capacity()/3; } - bool mark_stack_overflow() { return _global_mark_stack.is_out_of_memory(); } bool mark_stack_empty() { return _global_mark_stack.is_empty(); } G1CMRootRegions* root_regions() { return &_root_regions; }