8258142: Simplify G1RedirtyCardsQueue
Separate local redirty qset from redirty queue. Reviewed-by: tschatzl, iwalulya
This commit is contained in:
parent
e8c40bafa5
commit
1ff0f1673d
@ -199,6 +199,7 @@ class RemoveSelfForwardPtrHRClosure: public HeapRegionClosure {
|
||||
G1CollectedHeap* _g1h;
|
||||
uint _worker_id;
|
||||
|
||||
G1RedirtyCardsLocalQueueSet _rdc_local_qset;
|
||||
G1RedirtyCardsQueue _rdcq;
|
||||
UpdateLogBuffersDeferred _log_buffer_cl;
|
||||
|
||||
@ -206,10 +207,16 @@ public:
|
||||
RemoveSelfForwardPtrHRClosure(G1RedirtyCardsQueueSet* rdcqs, uint worker_id) :
|
||||
_g1h(G1CollectedHeap::heap()),
|
||||
_worker_id(worker_id),
|
||||
_rdcq(rdcqs),
|
||||
_rdc_local_qset(rdcqs),
|
||||
_rdcq(&_rdc_local_qset),
|
||||
_log_buffer_cl(&_rdcq) {
|
||||
}
|
||||
|
||||
~RemoveSelfForwardPtrHRClosure() {
|
||||
_rdcq.flush();
|
||||
_rdc_local_qset.flush();
|
||||
}
|
||||
|
||||
size_t remove_self_forward_ptr_by_walking_hr(HeapRegion* hr,
|
||||
bool during_concurrent_start) {
|
||||
RemoveSelfForwardPtrObjClosure rspc(hr,
|
||||
|
@ -58,7 +58,8 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h,
|
||||
size_t optional_cset_length)
|
||||
: _g1h(g1h),
|
||||
_task_queue(g1h->task_queue(worker_id)),
|
||||
_rdcq(rdcqs),
|
||||
_rdc_local_qset(rdcqs),
|
||||
_rdcq(&_rdc_local_qset),
|
||||
_ct(g1h->card_table()),
|
||||
_closures(NULL),
|
||||
_plab_allocator(NULL),
|
||||
@ -114,6 +115,7 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h,
|
||||
|
||||
size_t G1ParScanThreadState::flush(size_t* surviving_young_words) {
|
||||
_rdcq.flush();
|
||||
_rdc_local_qset.flush();
|
||||
flush_numa_stats();
|
||||
// Update allocation statistics.
|
||||
_plab_allocator->flush_and_retire_stats();
|
||||
|
@ -48,6 +48,7 @@ class outputStream;
|
||||
class G1ParScanThreadState : public CHeapObj<mtGC> {
|
||||
G1CollectedHeap* _g1h;
|
||||
G1ScannerTasksQueue* _task_queue;
|
||||
G1RedirtyCardsLocalQueueSet _rdc_local_qset;
|
||||
G1RedirtyCardsQueue _rdcq;
|
||||
G1CardTable* _ct;
|
||||
G1EvacuationRootClosures* _closures;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -30,19 +30,21 @@
|
||||
|
||||
// G1RedirtyCardsQueueBase::LocalQSet
|
||||
|
||||
G1RedirtyCardsQueueBase::LocalQSet::LocalQSet(G1RedirtyCardsQueueSet* shared_qset) :
|
||||
G1RedirtyCardsLocalQueueSet::G1RedirtyCardsLocalQueueSet(G1RedirtyCardsQueueSet* shared_qset) :
|
||||
PtrQueueSet(shared_qset->allocator()),
|
||||
_shared_qset(shared_qset),
|
||||
_buffers()
|
||||
{}
|
||||
|
||||
G1RedirtyCardsQueueBase::LocalQSet::~LocalQSet() {
|
||||
#ifdef ASSERT
|
||||
G1RedirtyCardsLocalQueueSet::~G1RedirtyCardsLocalQueueSet() {
|
||||
assert(_buffers._head == NULL, "unflushed qset");
|
||||
assert(_buffers._tail == NULL, "invariant");
|
||||
assert(_buffers._entry_count == 0, "invariant");
|
||||
}
|
||||
#endif // ASSERT
|
||||
|
||||
void G1RedirtyCardsQueueBase::LocalQSet::enqueue_completed_buffer(BufferNode* node) {
|
||||
void G1RedirtyCardsLocalQueueSet::enqueue_completed_buffer(BufferNode* node) {
|
||||
_buffers._entry_count += buffer_size() - node->index();
|
||||
node->set_next(_buffers._head);
|
||||
_buffers._head = node;
|
||||
@ -51,26 +53,22 @@ void G1RedirtyCardsQueueBase::LocalQSet::enqueue_completed_buffer(BufferNode* no
|
||||
}
|
||||
}
|
||||
|
||||
G1BufferNodeList G1RedirtyCardsQueueBase::LocalQSet::take_all_completed_buffers() {
|
||||
G1BufferNodeList result = _buffers;
|
||||
void G1RedirtyCardsLocalQueueSet::flush() {
|
||||
_shared_qset->add_bufferlist(_buffers);
|
||||
_buffers = G1BufferNodeList();
|
||||
return result;
|
||||
}
|
||||
|
||||
void G1RedirtyCardsQueueBase::LocalQSet::flush() {
|
||||
_shared_qset->merge_bufferlist(this);
|
||||
}
|
||||
|
||||
// G1RedirtyCardsQueue
|
||||
|
||||
G1RedirtyCardsQueue::G1RedirtyCardsQueue(G1RedirtyCardsQueueSet* qset) :
|
||||
G1RedirtyCardsQueueBase(qset), // Init _local_qset before passing to PtrQueue.
|
||||
PtrQueue(&_local_qset, true /* active (always) */)
|
||||
G1RedirtyCardsQueue::G1RedirtyCardsQueue(G1RedirtyCardsLocalQueueSet* qset) :
|
||||
PtrQueue(qset, true /* always active */)
|
||||
{}
|
||||
|
||||
#ifdef ASSERT
|
||||
G1RedirtyCardsQueue::~G1RedirtyCardsQueue() {
|
||||
flush();
|
||||
assert(is_empty(), "unflushed queue");
|
||||
}
|
||||
#endif // ASSERT
|
||||
|
||||
void G1RedirtyCardsQueue::handle_completed_buffer() {
|
||||
enqueue_completed_buffer();
|
||||
@ -78,7 +76,6 @@ void G1RedirtyCardsQueue::handle_completed_buffer() {
|
||||
|
||||
void G1RedirtyCardsQueue::flush() {
|
||||
flush_impl();
|
||||
_local_qset.flush();
|
||||
}
|
||||
|
||||
// G1RedirtyCardsQueueSet
|
||||
@ -134,13 +131,12 @@ void G1RedirtyCardsQueueSet::enqueue_completed_buffer(BufferNode* node) {
|
||||
update_tail(node);
|
||||
}
|
||||
|
||||
void G1RedirtyCardsQueueSet::merge_bufferlist(LocalQSet* src) {
|
||||
void G1RedirtyCardsQueueSet::add_bufferlist(const G1BufferNodeList& buffers) {
|
||||
assert(_collecting, "precondition");
|
||||
const G1BufferNodeList from = src->take_all_completed_buffers();
|
||||
if (from._head != NULL) {
|
||||
assert(from._tail != NULL, "invariant");
|
||||
Atomic::add(&_entry_count, from._entry_count);
|
||||
_list.prepend(*from._head, *from._tail);
|
||||
update_tail(from._tail);
|
||||
if (buffers._head != NULL) {
|
||||
assert(buffers._tail != NULL, "invariant");
|
||||
Atomic::add(&_entry_count, buffers._entry_count);
|
||||
_list.prepend(*buffers._head, *buffers._tail);
|
||||
update_tail(buffers._tail);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -27,56 +27,36 @@
|
||||
|
||||
#include "gc/g1/g1BufferNodeList.hpp"
|
||||
#include "gc/shared/ptrQueue.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/padded.hpp"
|
||||
|
||||
class G1CardTableEntryClosure;
|
||||
class G1RedirtyCardsQueue;
|
||||
class G1RedirtyCardsQueueSet;
|
||||
|
||||
// Provide G1RedirtyCardsQueue with a thread-local qset. It provides an
|
||||
// uncontended staging area for completed buffers, to be flushed to the
|
||||
// shared qset en masse. Using the "base from member" idiom so the local
|
||||
// qset is constructed before being passed to the PtrQueue constructor.
|
||||
class G1RedirtyCardsQueueBase {
|
||||
friend class G1RedirtyCardsQueue;
|
||||
friend class G1RedirtyCardsQueueSet;
|
||||
|
||||
class LocalQSet : public PtrQueueSet {
|
||||
// shared qset en masse.
|
||||
class G1RedirtyCardsLocalQueueSet : public PtrQueueSet {
|
||||
G1RedirtyCardsQueueSet* _shared_qset;
|
||||
G1BufferNodeList _buffers;
|
||||
|
||||
public:
|
||||
LocalQSet(G1RedirtyCardsQueueSet* shared_qset);
|
||||
~LocalQSet();
|
||||
G1RedirtyCardsLocalQueueSet(G1RedirtyCardsQueueSet* shared_qset);
|
||||
~G1RedirtyCardsLocalQueueSet() NOT_DEBUG(= default);
|
||||
|
||||
// Add the buffer to the local list.
|
||||
virtual void enqueue_completed_buffer(BufferNode* node);
|
||||
|
||||
// Transfer all completed buffers to the shared qset.
|
||||
void flush();
|
||||
|
||||
G1BufferNodeList take_all_completed_buffers();
|
||||
};
|
||||
|
||||
G1RedirtyCardsQueueBase(G1RedirtyCardsQueueSet* shared_qset) :
|
||||
_local_qset(shared_qset) {}
|
||||
|
||||
~G1RedirtyCardsQueueBase() {}
|
||||
|
||||
LocalQSet _local_qset;
|
||||
};
|
||||
|
||||
// Worker-local queues of card table entries.
|
||||
class G1RedirtyCardsQueue : private G1RedirtyCardsQueueBase, public PtrQueue {
|
||||
class G1RedirtyCardsQueue : public PtrQueue {
|
||||
protected:
|
||||
virtual void handle_completed_buffer();
|
||||
|
||||
public:
|
||||
G1RedirtyCardsQueue(G1RedirtyCardsQueueSet* qset);
|
||||
|
||||
// Flushes the queue.
|
||||
~G1RedirtyCardsQueue();
|
||||
G1RedirtyCardsQueue(G1RedirtyCardsLocalQueueSet* qset);
|
||||
~G1RedirtyCardsQueue() NOT_DEBUG(= default);
|
||||
|
||||
// Flushes all enqueued cards to qset.
|
||||
void flush();
|
||||
@ -97,8 +77,6 @@ class G1RedirtyCardsQueueSet : public PtrQueueSet {
|
||||
BufferNode* _tail;
|
||||
DEBUG_ONLY(mutable bool _collecting;)
|
||||
|
||||
typedef G1RedirtyCardsQueueBase::LocalQSet LocalQSet;
|
||||
|
||||
void update_tail(BufferNode* node);
|
||||
|
||||
public:
|
||||
@ -110,7 +88,7 @@ public:
|
||||
// Collect buffers. These functions are thread-safe.
|
||||
// precondition: Must not be concurrent with buffer processing.
|
||||
virtual void enqueue_completed_buffer(BufferNode* node);
|
||||
void merge_bufferlist(LocalQSet* src);
|
||||
void add_bufferlist(const G1BufferNodeList& buffers);
|
||||
|
||||
// Processing phase operations.
|
||||
// precondition: Must not be concurrent with buffer collection.
|
||||
|
Loading…
x
Reference in New Issue
Block a user