--- old/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp 2018-04-26 11:17:55.264837768 +0200 +++ new/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp 2018-04-26 11:17:54.646819532 +0200 @@ -1706,6 +1706,44 @@ } } +class G1PrecleanYieldClosure : public YieldClosure { + G1ConcurrentMark* _cm; + +public: + G1PrecleanYieldClosure(G1ConcurrentMark* cm) : _cm(cm) { } + + virtual bool should_return() { + return _cm->has_aborted(); + } + + virtual bool should_return_fine_grain() { + _cm->do_yield_check(); + return _cm->has_aborted(); + } +}; + +void G1ConcurrentMark::preclean() { + assert(G1UseReferencePrecleaning, "Precleaning must be enabled."); + + SuspendibleThreadSetJoiner joiner; + + G1CMKeepAliveAndDrainClosure keep_alive(this, task(0), true /* is_serial */); + G1CMDrainMarkingStackClosure drain_mark_stack(this, task(0), true /* is_serial */); + + set_concurrency_and_phase(1, true); + + G1PrecleanYieldClosure yield_cl(this); + + ReferenceProcessor* rp = _g1h->ref_processor_cm(); + // Precleaning is single threaded. Temporarily disable MT discovery. + ReferenceProcessorMTDiscoveryMutator rp_mut_discovery(rp, false); + rp->preclean_discovered_references(rp->is_alive_non_header(), + &keep_alive, + &drain_mark_stack, + &yield_cl, + _gc_timer_cm); +} + // When sampling object counts, we already swapped the mark bitmaps, so we need to use // the prev bitmap determining liveness. class G1ObjectCountIsAliveClosure: public BoolObjectClosure {