When we abort a concurrent cycle due to a Full GC in G1 we call ConcurrentMark::abort(). That will set _has_aborted flag and then call register_concurrent_cycle_end().
The concurrent marking thread will see the _has_aborted flag in its ConcurrentMarkThread::run() method, abort the execution and then call register_concurrent_cycle_end().
Currently this works since the code inside register_concurrent_cycle_end() is guarded by _concurrent_cycle_started which it itself resets. So, the double calls will not necessarily result in too much extra work being done. But one of the things that register_concurrent_cycle_end() does is to call report_gc_end() on the concurrent GC tracer. That prevents further use of it for this GC. This means that inside the ConcurrentMarkThread::run() method we can not rely on the tracer.
Removing the call to register_concurrent_cycle_end() in ConcurrentMark::abort() and relying on the call in ConcurrentMarkThread::run() seems to be a reasonable approach.
The concurrent marking thread will see the _has_aborted flag in its ConcurrentMarkThread::run() method, abort the execution and then call register_concurrent_cycle_end().
Currently this works since the code inside register_concurrent_cycle_end() is guarded by _concurrent_cycle_started which it itself resets. So, the double calls will not necessarily result in too much extra work being done. But one of the things that register_concurrent_cycle_end() does is to call report_gc_end() on the concurrent GC tracer. That prevents further use of it for this GC. This means that inside the ConcurrentMarkThread::run() method we can not rely on the tracer.
Removing the call to register_concurrent_cycle_end() in ConcurrentMark::abort() and relying on the call in ConcurrentMarkThread::run() seems to be a reasonable approach.