mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-05 11:15:13 +00:00
8229044: G1RedirtyCardsQueueSet should be local to a collection
Stack allocate redirty qsets in do_collection_pause_at_safepoint. Reviewed-by: tschatzl, sangheki
This commit is contained in:
parent
c0b8844dce
commit
0b9a90e0d1
@ -1082,7 +1082,6 @@ void G1CollectedHeap::abort_refinement() {
|
||||
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 @@ G1CollectedHeap::G1CollectedHeap() :
|
||||
_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 @@ jint G1CollectedHeap::initialize() {
|
||||
&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 @@ bool G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_
|
||||
|
||||
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 @@ bool G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_
|
||||
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 @@ bool G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_
|
||||
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 @@ class G1RedirtyLoggedCardsTask : public AbstractGangTask {
|
||||
}
|
||||
};
|
||||
|
||||
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 @@ void G1CollectedHeap::pre_evacuate_collection_set(G1EvacuationInfo& evacuation_i
|
||||
|
||||
// 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 @@ void G1CollectedHeap::evacuate_optional_collection_set(G1ParScanThreadStateSet*
|
||||
_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 @@ void G1CollectedHeap::post_evacuate_collection_set(G1EvacuationInfo& evacuation_
|
||||
_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 @@ void G1CollectedHeap::post_evacuate_collection_set(G1EvacuationInfo& evacuation_
|
||||
|
||||
purge_code_root_memory();
|
||||
|
||||
redirty_logged_cards();
|
||||
redirty_logged_cards(rdcqs);
|
||||
|
||||
free_collection_set(&_collection_set, evacuation_info, per_thread_states->surviving_young_words());
|
||||
|
||||
|
||||
@ -762,7 +762,9 @@ private:
|
||||
|
||||
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 @@ public:
|
||||
// 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 @@ public:
|
||||
|
||||
// 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 @@ public:
|
||||
|
||||
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 @@ public:
|
||||
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
|
||||
|
||||
@ -203,10 +203,10 @@ class RemoveSelfForwardPtrHRClosure: public HeapRegionClosure {
|
||||
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 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
@ -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 @@ G1ParScanThreadState* G1ParScanThreadStateSet::state_for_worker(uint worker_id)
|
||||
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 @@ oop G1ParScanThreadState::handle_evacuation_failure_par(oop old, markWord m) {
|
||||
}
|
||||
}
|
||||
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),
|
||||
|
||||
@ -97,6 +97,7 @@ class G1ParScanThreadState : public CHeapObj<mtGC> {
|
||||
|
||||
public:
|
||||
G1ParScanThreadState(G1CollectedHeap* g1h,
|
||||
G1RedirtyCardsQueueSet* rdcqs,
|
||||
uint worker_id,
|
||||
size_t young_cset_length,
|
||||
size_t optional_cset_length);
|
||||
@ -237,6 +238,7 @@ public:
|
||||
|
||||
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 @@ class G1ParScanThreadStateSet : public StackObj {
|
||||
|
||||
public:
|
||||
G1ParScanThreadStateSet(G1CollectedHeap* g1h,
|
||||
G1RedirtyCardsQueueSet* rdcqs,
|
||||
uint n_workers,
|
||||
size_t young_cset_length,
|
||||
size_t optional_cset_length);
|
||||
|
||||
@ -99,13 +99,15 @@ void G1RedirtyCardsQueue::flush() {
|
||||
|
||||
// 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();
|
||||
|
||||
@ -110,11 +110,9 @@ class G1RedirtyCardsQueueSet : public PtrQueueSet {
|
||||
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.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user