--- old/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp 2018-06-19 21:02:30.283187305 +0200 +++ new/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp 2018-06-19 21:02:30.098189571 +0200 @@ -232,7 +232,12 @@ // it requires a StrongRootsScope around the task, we need to claim the // threads, and performance-wise it doesn't really matter. Adds about 1ms to // full-gc. - _cm->drain_satb_buffers(worker_id); + ShenandoahObjToScanQueue* q = get_queue(worker_id); + ShenandoahSATBBufferClosure cl(q); + SATBMarkQueueSet& satb_mq_set = ShenandoahBarrierSet::satb_mark_queue_set(); + while (satb_mq_set.apply_closure_to_completed_buffer(&cl)); + ShenandoahSATBThreadsClosure tc(&cl); + Threads::threads_do(&tc); ReferenceProcessor* rp; if (_cm->process_references()) { @@ -497,13 +502,6 @@ } }; -void ShenandoahConcurrentMark::drain_satb_buffers(uint worker_id) { - ShenandoahObjToScanQueue* q = get_queue(worker_id); - ShenandoahSATBBufferClosure cl(q); - ShenandoahSATBThreadsClosure tc(&cl); - Threads::threads_do(&tc); -} - #if TASKQUEUE_STATS void ShenandoahConcurrentMark::print_taskqueue_stats_hdr(outputStream* const st) { st->print_raw_cr("GC Task Stats"); --- old/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.hpp 2018-06-19 21:02:30.752181561 +0200 +++ new/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.hpp 2018-06-19 21:02:30.573183754 +0200 @@ -118,7 +118,6 @@ ShenandoahObjToScanQueue* get_queue(uint worker_id); void clear_queue(ShenandoahObjToScanQueue *q); - void drain_satb_buffers(uint worker_id); ShenandoahObjToScanQueueSet* task_queues() { return _task_queues;} jushort* get_liveness(uint worker_id); --- old/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp 2018-06-19 21:02:31.199176087 +0200 +++ new/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp 2018-06-19 21:02:31.015178340 +0200 @@ -243,8 +243,17 @@ rp = _heap->ref_processor(); } - // Step 1: Process ordinary GC roots. + // Step 0: Drain outstanding SATB queues. + // NOTE: we piggy-back draining of remaining thread SATB buffers on the final root scan below. ShenandoahTraversalSATBBufferClosure satb_cl(q); + { + // Process remaining finished SATB buffers. + SATBMarkQueueSet& satb_mq_set = ShenandoahBarrierSet::satb_mark_queue_set(); + while (satb_mq_set.apply_closure_to_completed_buffer(&satb_cl)); + // Process remaining threads SATB buffers below. + } + + // Step 1: Process ordinary GC roots. if (!_heap->is_degenerated_gc_in_progress()) { ShenandoahTraversalClosure roots_cl(q, rp); CLDToOopClosure cld_cl(&roots_cl);