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