8229044: G1RedirtyCardsQueueSet should be local to a collection
Summary: Stack allocate redirty qsets in do_collection_pause_at_safepoint.
Reviewed-by: tschatzl, sangheki
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Fri Aug 16 11:35:17 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Fri Aug 16 14:46:52 2019 -0400
@@ -1082,7 +1082,6 @@
G1BarrierSet::dirty_card_queue_set().abandon_logs();
assert(G1BarrierSet::dirty_card_queue_set().num_completed_buffers() == 0,
"DCQS should be empty");
- redirty_cards_queue_set().verify_empty();
}
void G1CollectedHeap::verify_after_full_collection() {
@@ -1521,7 +1520,6 @@
_collection_set(this, _policy),
_hot_card_cache(NULL),
_rem_set(NULL),
- _redirty_cards_queue_set(),
_cm(NULL),
_cm_thread(NULL),
_cr(NULL),
@@ -1691,9 +1689,6 @@
&bs->dirty_card_queue_buffer_allocator(),
true); // init_free_ids
- // Use same buffer allocator as dirty card qset, to allow merging.
- _redirty_cards_queue_set.initialize(&bs->dirty_card_queue_buffer_allocator());
-
// Create the hot card cache.
_hot_card_cache = new G1HotCardCache(this);
@@ -3028,7 +3023,9 @@
calculate_collection_set(evacuation_info, target_pause_time_ms);
+ G1RedirtyCardsQueueSet rdcqs(G1BarrierSet::dirty_card_queue_set().allocator());
G1ParScanThreadStateSet per_thread_states(this,
+ &rdcqs,
workers()->active_workers(),
collection_set()->young_region_length(),
collection_set()->optional_region_length());
@@ -3040,7 +3037,7 @@
if (_collection_set.optional_region_length() != 0) {
evacuate_optional_collection_set(&per_thread_states);
}
- post_evacuate_collection_set(evacuation_info, &per_thread_states);
+ post_evacuate_collection_set(evacuation_info, &rdcqs, &per_thread_states);
start_new_collection_set();
@@ -3122,15 +3119,15 @@
return true;
}
-void G1CollectedHeap::remove_self_forwarding_pointers() {
- G1ParRemoveSelfForwardPtrsTask rsfp_task;
+void G1CollectedHeap::remove_self_forwarding_pointers(G1RedirtyCardsQueueSet* rdcqs) {
+ G1ParRemoveSelfForwardPtrsTask rsfp_task(rdcqs);
workers()->run_task(&rsfp_task);
}
-void G1CollectedHeap::restore_after_evac_failure() {
+void G1CollectedHeap::restore_after_evac_failure(G1RedirtyCardsQueueSet* rdcqs) {
double remove_self_forwards_start = os::elapsedTime();
- remove_self_forwarding_pointers();
+ remove_self_forwarding_pointers(rdcqs);
SharedRestorePreservedMarksTaskExecutor task_executor(workers());
_preserved_marks_set.restore(&task_executor);
@@ -3264,15 +3261,14 @@
}
};
-void G1CollectedHeap::redirty_logged_cards() {
+void G1CollectedHeap::redirty_logged_cards(G1RedirtyCardsQueueSet* rdcqs) {
double redirty_logged_cards_start = os::elapsedTime();
- G1RedirtyLoggedCardsTask redirty_task(&redirty_cards_queue_set(), this);
+ G1RedirtyLoggedCardsTask redirty_task(rdcqs, this);
workers()->run_task(&redirty_task);
G1DirtyCardQueueSet& dcq = G1BarrierSet::dirty_card_queue_set();
- dcq.merge_bufferlists(&redirty_cards_queue_set());
- redirty_cards_queue_set().verify_empty();
+ dcq.merge_bufferlists(rdcqs);
phase_times()->record_redirty_logged_cards_time_ms((os::elapsedTime() - redirty_logged_cards_start) * 1000.0);
}
@@ -3603,8 +3599,6 @@
// Should G1EvacuationFailureALot be in effect for this GC?
NOT_PRODUCT(set_evacuation_failure_alot_for_current_gc();)
-
- redirty_cards_queue_set().verify_empty();
}
class G1EvacuateRegionsBaseTask : public AbstractGangTask {
@@ -3806,7 +3800,9 @@
_collection_set.abandon_optional_collection_set(per_thread_states);
}
-void G1CollectedHeap::post_evacuate_collection_set(G1EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* per_thread_states) {
+void G1CollectedHeap::post_evacuate_collection_set(G1EvacuationInfo& evacuation_info,
+ G1RedirtyCardsQueueSet* rdcqs,
+ G1ParScanThreadStateSet* per_thread_states) {
rem_set()->cleanup_after_scan_heap_roots();
// Process any discovered reference objects - we have
@@ -3834,7 +3830,7 @@
_allocator->release_gc_alloc_regions(evacuation_info);
if (evacuation_failed()) {
- restore_after_evac_failure();
+ restore_after_evac_failure(rdcqs);
// Reset the G1EvacuationFailureALot counters and flags
NOT_PRODUCT(reset_evacuation_should_fail();)
@@ -3869,7 +3865,7 @@
purge_code_root_memory();
- redirty_logged_cards();
+ redirty_logged_cards(rdcqs);
free_collection_set(&_collection_set, evacuation_info, per_thread_states->surviving_young_words());
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Fri Aug 16 11:35:17 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Fri Aug 16 14:46:52 2019 -0400
@@ -762,7 +762,9 @@
public:
void pre_evacuate_collection_set(G1EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* pss);
- void post_evacuate_collection_set(G1EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* pss);
+ void post_evacuate_collection_set(G1EvacuationInfo& evacuation_info,
+ G1RedirtyCardsQueueSet* rdcqs,
+ G1ParScanThreadStateSet* pss);
void expand_heap_after_young_collection();
// Update object copying statistics.
@@ -774,10 +776,6 @@
// The g1 remembered set of the heap.
G1RemSet* _rem_set;
- // A set of cards that cover the objects for which the Rsets should be updated
- // concurrently after the collection.
- G1RedirtyCardsQueueSet _redirty_cards_queue_set;
-
// After a collection pause, convert the regions in the collection set into free
// regions.
void free_collection_set(G1CollectionSet* collection_set, G1EvacuationInfo& evacuation_info, const size_t* surviving_young_words);
@@ -803,11 +801,11 @@
// Failed evacuations cause some logical from-space objects to have
// forwarding pointers to themselves. Reset them.
- void remove_self_forwarding_pointers();
+ void remove_self_forwarding_pointers(G1RedirtyCardsQueueSet* rdcqs);
// Restore the objects in the regions in the collection set after an
// evacuation failure.
- void restore_after_evac_failure();
+ void restore_after_evac_failure(G1RedirtyCardsQueueSet* rdcqs);
PreservedMarksSet _preserved_marks_set;
@@ -935,11 +933,6 @@
uint num_task_queues() const;
- // A set of cards where updates happened during the GC
- G1RedirtyCardsQueueSet& redirty_cards_queue_set() {
- return _redirty_cards_queue_set;
- }
-
// Create a G1CollectedHeap.
// Must call the initialize method afterwards.
// May not return if something goes wrong.
@@ -1366,7 +1359,8 @@
void complete_cleaning(BoolObjectClosure* is_alive, bool class_unloading_occurred);
// Redirty logged cards in the refinement queue.
- void redirty_logged_cards();
+ void redirty_logged_cards(G1RedirtyCardsQueueSet* rdcqs);
+
// Verification
// Deduplicate the string
--- a/src/hotspot/share/gc/g1/g1EvacFailure.cpp Fri Aug 16 11:35:17 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1EvacFailure.cpp Fri Aug 16 14:46:52 2019 -0400
@@ -203,10 +203,10 @@
UpdateLogBuffersDeferred _log_buffer_cl;
public:
- RemoveSelfForwardPtrHRClosure(uint worker_id) :
+ RemoveSelfForwardPtrHRClosure(G1RedirtyCardsQueueSet* rdcqs, uint worker_id) :
_g1h(G1CollectedHeap::heap()),
_worker_id(worker_id),
- _rdcq(&_g1h->redirty_cards_queue_set()),
+ _rdcq(rdcqs),
_log_buffer_cl(&_rdcq) {
}
@@ -250,13 +250,14 @@
}
};
-G1ParRemoveSelfForwardPtrsTask::G1ParRemoveSelfForwardPtrsTask() :
+G1ParRemoveSelfForwardPtrsTask::G1ParRemoveSelfForwardPtrsTask(G1RedirtyCardsQueueSet* rdcqs) :
AbstractGangTask("G1 Remove Self-forwarding Pointers"),
_g1h(G1CollectedHeap::heap()),
+ _rdcqs(rdcqs),
_hrclaimer(_g1h->workers()->active_workers()) { }
void G1ParRemoveSelfForwardPtrsTask::work(uint worker_id) {
- RemoveSelfForwardPtrHRClosure rsfp_cl(worker_id);
+ RemoveSelfForwardPtrHRClosure rsfp_cl(_rdcqs, worker_id);
_g1h->collection_set_iterate_increment_from(&rsfp_cl, &_hrclaimer, worker_id);
}
--- a/src/hotspot/share/gc/g1/g1EvacFailure.hpp Fri Aug 16 11:35:17 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1EvacFailure.hpp Fri Aug 16 14:46:52 2019 -0400
@@ -31,16 +31,18 @@
#include "utilities/globalDefinitions.hpp"
class G1CollectedHeap;
+class G1RedirtyCardsQueueSet;
// Task to fixup self-forwarding pointers
// installed as a result of an evacuation failure.
class G1ParRemoveSelfForwardPtrsTask: public AbstractGangTask {
protected:
G1CollectedHeap* _g1h;
+ G1RedirtyCardsQueueSet* _rdcqs;
HeapRegionClaimer _hrclaimer;
public:
- G1ParRemoveSelfForwardPtrsTask();
+ G1ParRemoveSelfForwardPtrsTask(G1RedirtyCardsQueueSet* rdcqs);
void work(uint worker_id);
};
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp Fri Aug 16 11:35:17 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp Fri Aug 16 14:46:52 2019 -0400
@@ -38,12 +38,13 @@
#include "runtime/prefetch.inline.hpp"
G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h,
+ G1RedirtyCardsQueueSet* rdcqs,
uint worker_id,
size_t young_cset_length,
size_t optional_cset_length)
: _g1h(g1h),
_refs(g1h->task_queue(worker_id)),
- _rdcq(&g1h->redirty_cards_queue_set()),
+ _rdcq(rdcqs),
_ct(g1h->card_table()),
_closures(NULL),
_plab_allocator(NULL),
@@ -336,7 +337,7 @@
assert(worker_id < _n_workers, "out of bounds access");
if (_states[worker_id] == NULL) {
_states[worker_id] =
- new G1ParScanThreadState(_g1h, worker_id, _young_cset_length, _optional_cset_length);
+ new G1ParScanThreadState(_g1h, _rdcqs, worker_id, _young_cset_length, _optional_cset_length);
}
return _states[worker_id];
}
@@ -407,10 +408,12 @@
}
}
G1ParScanThreadStateSet::G1ParScanThreadStateSet(G1CollectedHeap* g1h,
+ G1RedirtyCardsQueueSet* rdcqs,
uint n_workers,
size_t young_cset_length,
size_t optional_cset_length) :
_g1h(g1h),
+ _rdcqs(rdcqs),
_states(NEW_C_HEAP_ARRAY(G1ParScanThreadState*, n_workers, mtGC)),
_surviving_young_words_total(NEW_C_HEAP_ARRAY(size_t, young_cset_length, mtGC)),
_young_cset_length(young_cset_length),
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp Fri Aug 16 11:35:17 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp Fri Aug 16 14:46:52 2019 -0400
@@ -97,6 +97,7 @@
public:
G1ParScanThreadState(G1CollectedHeap* g1h,
+ G1RedirtyCardsQueueSet* rdcqs,
uint worker_id,
size_t young_cset_length,
size_t optional_cset_length);
@@ -237,6 +238,7 @@
class G1ParScanThreadStateSet : public StackObj {
G1CollectedHeap* _g1h;
+ G1RedirtyCardsQueueSet* _rdcqs;
G1ParScanThreadState** _states;
size_t* _surviving_young_words_total;
size_t _young_cset_length;
@@ -246,6 +248,7 @@
public:
G1ParScanThreadStateSet(G1CollectedHeap* g1h,
+ G1RedirtyCardsQueueSet* rdcqs,
uint n_workers,
size_t young_cset_length,
size_t optional_cset_length);
--- a/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.cpp Fri Aug 16 11:35:17 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.cpp Fri Aug 16 14:46:52 2019 -0400
@@ -99,13 +99,15 @@
// G1RedirtyCardsQueueSet
-G1RedirtyCardsQueueSet::G1RedirtyCardsQueueSet() :
+G1RedirtyCardsQueueSet::G1RedirtyCardsQueueSet(BufferNode::Allocator* allocator) :
PtrQueueSet(),
_list(),
_entry_count(0),
_tail(NULL)
DEBUG_ONLY(COMMA _collecting(true))
-{}
+{
+ initialize(allocator);
+}
G1RedirtyCardsQueueSet::~G1RedirtyCardsQueueSet() {
verify_empty();
--- a/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp Fri Aug 16 11:35:17 2019 -0700
+++ b/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp Fri Aug 16 14:46:52 2019 -0400
@@ -110,11 +110,9 @@
void update_tail(BufferNode* node);
public:
- G1RedirtyCardsQueueSet();
+ G1RedirtyCardsQueueSet(BufferNode::Allocator* allocator);
~G1RedirtyCardsQueueSet();
- using PtrQueueSet::initialize;
-
void verify_empty() const NOT_DEBUG_RETURN;
// Collect buffers. These functions are thread-safe.