--- old/src/hotspot/share/gc/g1/g1RemSet.cpp 2019-09-03 21:16:17.061775497 -0400 +++ new/src/hotspot/share/gc/g1/g1RemSet.cpp 2019-09-03 21:16:16.841763642 -0400 @@ -42,6 +42,7 @@ #include "gc/g1/heapRegionRemSet.inline.hpp" #include "gc/g1/sparsePRT.hpp" #include "gc/shared/gcTraceTime.inline.hpp" +#include "gc/shared/ptrQueue.hpp" #include "gc/shared/suspendibleThreadSet.hpp" #include "jfr/jfrEvents.hpp" #include "memory/iterator.hpp" @@ -1060,7 +1061,7 @@ _scan_state(scan_state), _ct(g1h->card_table()), _cards_dirty(0), _cards_skipped(0) {} - bool do_card_ptr(CardValue* card_ptr, uint worker_i) { + void do_card_ptr(CardValue* card_ptr, uint worker_i) { // The only time we care about recording cards that // contain references that point into the collection set // is during RSet updating within an evacuation pause. @@ -1084,7 +1085,6 @@ // regions to clear the card table at the end during the prepare() phase. _cards_skipped++; } - return true; } size_t cards_dirty() const { return _cards_dirty; } @@ -1093,17 +1093,37 @@ HeapRegionClaimer _hr_claimer; G1RemSetScanState* _scan_state; + BufferNode::Stack _dirty_card_buffers; bool _initial_evacuation; volatile bool _fast_reclaim_handled; + void apply_closure_to_dirty_card_buffers(G1MergeLogBufferCardsClosure* cl, uint worker_id) { + G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set(); + size_t buffer_size = dcqs.buffer_size(); + while (BufferNode* node = _dirty_card_buffers.pop()) { + cl->apply_to_buffer(node, buffer_size, worker_id); + dcqs.deallocate_buffer(node); + } + } + public: G1MergeHeapRootsTask(G1RemSetScanState* scan_state, uint num_workers, bool initial_evacuation) : AbstractGangTask("G1 Merge Heap Roots"), _hr_claimer(num_workers), _scan_state(scan_state), + _dirty_card_buffers(), _initial_evacuation(initial_evacuation), - _fast_reclaim_handled(false) { } + _fast_reclaim_handled(false) + { + if (initial_evacuation) { + G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set(); + G1BufferNodeList buffers = dcqs.take_all_completed_buffers(); + if (buffers._entry_count != 0) { + _dirty_card_buffers.prepend(*buffers._head, *buffers._tail); + } + } + } virtual void work(uint worker_id) { G1CollectedHeap* g1h = G1CollectedHeap::heap(); @@ -1158,7 +1178,7 @@ G1GCParPhaseTimesTracker x(p, G1GCPhaseTimes::MergeLB, worker_id); G1MergeLogBufferCardsClosure cl(g1h, _scan_state); - g1h->iterate_dirty_card_closure(&cl, worker_id); + apply_closure_to_dirty_card_buffers(&cl, worker_id); p->record_thread_work_item(G1GCPhaseTimes::MergeLB, worker_id, cl.cards_dirty(), G1GCPhaseTimes::MergeLBDirtyCards); p->record_thread_work_item(G1GCPhaseTimes::MergeLB, worker_id, cl.cards_skipped(), G1GCPhaseTimes::MergeLBSkippedCards);