@@ -113,15 +113,15 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h,
113113 initialize_numa_stats ();
114114}
115115
116- size_t G1ParScanThreadState::flush_stats (size_t * surviving_young_words, uint num_workers) {
117- _rdc_local_qset.flush ();
116+ size_t G1ParScanThreadState::flush_stats (size_t * surviving_young_words, uint num_workers, BufferNodeList* rdc_buffers ) {
117+ *rdc_buffers = _rdc_local_qset.flush ();
118118 flush_numa_stats ();
119119 // Update allocation statistics.
120120 _plab_allocator->flush_and_retire_stats (num_workers);
121121 _g1h->policy ()->record_age_table (&_age_table);
122122
123123 if (_evacuation_failed_info.has_failed ()) {
124- _g1h->gc_tracer_stw ()->report_evacuation_failed (_evacuation_failed_info);
124+ _g1h->gc_tracer_stw ()->report_evacuation_failed (_evacuation_failed_info);
125125 }
126126
127127 size_t sum = 0 ;
@@ -593,7 +593,6 @@ const size_t* G1ParScanThreadStateSet::surviving_young_words() const {
593593
594594void G1ParScanThreadStateSet::flush_stats () {
595595 assert (!_flushed, " thread local state from the per thread states should be flushed once" );
596-
597596 for (uint worker_id = 0 ; worker_id < _num_workers; ++worker_id) {
598597 G1ParScanThreadState* pss = _states[worker_id];
599598 assert (pss != nullptr , " must be initialized" );
@@ -604,7 +603,7 @@ void G1ParScanThreadStateSet::flush_stats() {
604603 // because it resets the PLAB allocator where we get this info from.
605604 size_t lab_waste_bytes = pss->lab_waste_words () * HeapWordSize;
606605 size_t lab_undo_waste_bytes = pss->lab_undo_waste_words () * HeapWordSize;
607- size_t copied_bytes = pss->flush_stats (_surviving_young_words_total, _num_workers) * HeapWordSize;
606+ size_t copied_bytes = pss->flush_stats (_surviving_young_words_total, _num_workers, &_rdc_buffers[worker_id] ) * HeapWordSize;
608607 size_t evac_fail_enqueued_cards = pss->evac_failure_enqueued_cards ();
609608
610609 p->record_or_add_thread_work_item (G1GCPhaseTimes::MergePSS, worker_id, copied_bytes, G1GCPhaseTimes::MergePSSCopiedBytes);
@@ -615,6 +614,11 @@ void G1ParScanThreadStateSet::flush_stats() {
615614 delete pss;
616615 _states[worker_id] = nullptr ;
617616 }
617+
618+ G1DirtyCardQueueSet& dcq = G1BarrierSet::dirty_card_queue_set ();
619+ dcq.merge_bufferlists (rdcqs ());
620+ rdcqs ()->verify_empty ();
621+
618622 _flushed = true ;
619623}
620624
@@ -706,13 +710,15 @@ G1ParScanThreadStateSet::G1ParScanThreadStateSet(G1CollectedHeap* g1h,
706710 _rdcqs(G1BarrierSet::dirty_card_queue_set().allocator()),
707711 _preserved_marks_set(true /* in_c_heap */ ),
708712 _states(NEW_C_HEAP_ARRAY(G1ParScanThreadState*, num_workers, mtGC)),
713+ _rdc_buffers(NEW_C_HEAP_ARRAY(BufferNodeList, num_workers, mtGC)),
709714 _surviving_young_words_total(NEW_C_HEAP_ARRAY(size_t , collection_set->young_region_length () + 1, mtGC)),
710715 _num_workers(num_workers),
711716 _flushed(false ),
712717 _evac_failure_regions(evac_failure_regions) {
713718 _preserved_marks_set.init (num_workers);
714719 for (uint i = 0 ; i < num_workers; ++i) {
715720 _states[i] = nullptr ;
721+ _rdc_buffers[i] = BufferNodeList ();
716722 }
717723 memset (_surviving_young_words_total, 0 , (collection_set->young_region_length () + 1 ) * sizeof (size_t ));
718724}
@@ -721,5 +727,6 @@ G1ParScanThreadStateSet::~G1ParScanThreadStateSet() {
721727 assert (_flushed, " thread local state from the per thread states should have been flushed" );
722728 FREE_C_HEAP_ARRAY (G1ParScanThreadState*, _states);
723729 FREE_C_HEAP_ARRAY (size_t , _surviving_young_words_total);
730+ FREE_C_HEAP_ARRAY (BufferNodeList, _rdc_buffers);
724731 _preserved_marks_set.reclaim ();
725732}
0 commit comments