--- a/src/hotspot/share/gc/g1/g1RemSet.cpp Fri Sep 06 15:13:38 2019 +0200
+++ b/src/hotspot/share/gc/g1/g1RemSet.cpp Fri Sep 06 13:38:55 2019 -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);