Skip to content

Commit 6c4c96f

Browse files
author
Kim Barrett
committed
8258742: Move PtrQueue reset to PtrQueueSet subclasses
Reviewed-by: tschatzl, iwalulya
1 parent b53d5ca commit 6c4c96f

9 files changed

+44
-72
lines changed

src/hotspot/share/gc/g1/g1BarrierSet.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -142,17 +142,18 @@ void G1BarrierSet::on_thread_destroy(Thread* thread) {
142142
}
143143

144144
void G1BarrierSet::on_thread_attach(Thread* thread) {
145-
assert(!G1ThreadLocalData::satb_mark_queue(thread).is_active(), "SATB queue should not be active");
146-
assert(G1ThreadLocalData::satb_mark_queue(thread).is_empty(), "SATB queue should be empty");
145+
SATBMarkQueue& queue = G1ThreadLocalData::satb_mark_queue(thread);
146+
assert(!queue.is_active(), "SATB queue should not be active");
147+
assert(queue.buffer() == nullptr, "SATB queue should not have a buffer");
148+
assert(queue.index() == 0, "SATB queue index should be zero");
147149
// Can't assert that the DCQ is empty. There is early execution on
148150
// the main thread, before it gets added to the threads list, which
149151
// is where this is called. That execution may enqueue dirty cards.
150152

151153
// If we are creating the thread during a marking cycle, we should
152154
// set the active field of the SATB queue to true. That involves
153155
// copying the global is_active value to this thread's queue.
154-
bool is_satb_active = _satb_mark_queue_set.is_active();
155-
G1ThreadLocalData::satb_mark_queue(thread).set_active(is_satb_active);
156+
queue.set_active(_satb_mark_queue_set.is_active());
156157
}
157158

158159
void G1BarrierSet::on_thread_detach(Thread* thread) {

src/hotspot/share/gc/g1/g1ConcurrentMark.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -1737,22 +1737,22 @@ class G1CMSATBBufferClosure : public SATBBufferClosure {
17371737
};
17381738

17391739
class G1RemarkThreadsClosure : public ThreadClosure {
1740-
G1CMSATBBufferClosure _cm_satb_cl;
1740+
G1SATBMarkQueueSet& _qset;
17411741
G1CMOopClosure _cm_cl;
17421742
MarkingCodeBlobClosure _code_cl;
17431743
uintx _claim_token;
17441744

17451745
public:
17461746
G1RemarkThreadsClosure(G1CollectedHeap* g1h, G1CMTask* task) :
1747-
_cm_satb_cl(task, g1h),
1747+
_qset(G1BarrierSet::satb_mark_queue_set()),
17481748
_cm_cl(g1h, task),
17491749
_code_cl(&_cm_cl, !CodeBlobToOopClosure::FixRelocations),
17501750
_claim_token(Threads::thread_claim_token()) {}
17511751

17521752
void do_thread(Thread* thread) {
17531753
if (thread->claim_threads_do(true, _claim_token)) {
1754-
SATBMarkQueue& queue = G1ThreadLocalData::satb_mark_queue(thread);
1755-
queue.apply_closure_and_empty(&_cm_satb_cl);
1754+
// Transfer any partial buffer to the qset for completed buffer processing.
1755+
_qset.flush_queue(G1ThreadLocalData::satb_mark_queue(thread));
17561756
if (thread->is_Java_thread()) {
17571757
// In theory it should not be neccessary to explicitly walk the nmethods to find roots for concurrent marking
17581758
// however the liveness of oops reachable from nmethods have very complex lifecycles:

src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -622,12 +622,14 @@ void G1DirtyCardQueueSet::abandon_logs() {
622622
// Since abandon is done only at safepoints, we can safely manipulate
623623
// these queues.
624624
struct AbandonThreadLogClosure : public ThreadClosure {
625+
G1DirtyCardQueueSet& _qset;
626+
AbandonThreadLogClosure(G1DirtyCardQueueSet& qset) : _qset(qset) {}
625627
virtual void do_thread(Thread* t) {
626-
G1DirtyCardQueue& dcq = G1ThreadLocalData::dirty_card_queue(t);
627-
dcq.reset();
628-
dcq.refinement_stats()->reset();
628+
G1DirtyCardQueue& queue = G1ThreadLocalData::dirty_card_queue(t);
629+
_qset.reset_queue(queue);
630+
queue.refinement_stats()->reset();
629631
}
630-
} closure;
632+
} closure(*this);
631633
Threads::threads_do(&closure);
632634

633635
G1BarrierSet::shared_dirty_card_queue().reset();

src/hotspot/share/gc/shared/ptrQueue.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,12 @@ PtrQueueSet::PtrQueueSet(BufferNode::Allocator* allocator) :
199199

200200
PtrQueueSet::~PtrQueueSet() {}
201201

202+
void PtrQueueSet::reset_queue(PtrQueue& queue) {
203+
if (queue.buffer() != nullptr) {
204+
queue.set_index(buffer_size());
205+
}
206+
}
207+
202208
void PtrQueueSet::flush_queue(PtrQueue& queue) {
203209
void** buffer = queue.buffer();
204210
if (buffer != nullptr) {

src/hotspot/share/gc/shared/ptrQueue.hpp

+7-34
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class PtrQueue {
4848
PtrQueueSet* const _qset;
4949

5050
// The (byte) index at which an object was last enqueued. Starts at
51-
// capacity_in_bytes (indicating an empty buffer) and goes towards zero.
51+
// capacity (in bytes) (indicating an empty buffer) and goes towards zero.
5252
// Value is always pointer-size aligned.
5353
size_t _index;
5454

@@ -91,49 +91,19 @@ class PtrQueue {
9191
void** buffer() const { return _buf; }
9292
void set_buffer(void** buffer) { _buf = buffer; }
9393

94-
size_t index_in_bytes() const {
95-
return _index;
96-
}
97-
98-
void set_index_in_bytes(size_t new_index) {
99-
assert(is_aligned(new_index, _element_size), "precondition");
100-
assert(new_index <= capacity_in_bytes(), "precondition");
101-
_index = new_index;
102-
}
103-
10494
size_t index() const {
105-
return byte_index_to_index(index_in_bytes());
95+
return byte_index_to_index(_index);
10696
}
10797

10898
void set_index(size_t new_index) {
109-
set_index_in_bytes(index_to_byte_index(new_index));
99+
assert(new_index <= capacity(), "precondition");
100+
_index = index_to_byte_index(new_index);
110101
}
111102

112103
size_t capacity() const {
113104
return byte_index_to_index(capacity_in_bytes());
114105
}
115106

116-
// Forcibly set empty.
117-
void reset() {
118-
if (_buf != NULL) {
119-
_index = capacity_in_bytes();
120-
}
121-
}
122-
123-
// Return the size of the in-use region.
124-
size_t size() const {
125-
size_t result = 0;
126-
if (_buf != NULL) {
127-
assert(_index <= capacity_in_bytes(), "Invariant");
128-
result = byte_index_to_index(capacity_in_bytes() - _index);
129-
}
130-
return result;
131-
}
132-
133-
bool is_empty() const {
134-
return _buf == NULL || capacity_in_bytes() == _index;
135-
}
136-
137107
// To support compiler.
138108

139109
protected:
@@ -260,6 +230,9 @@ class PtrQueueSet {
260230
PtrQueueSet(BufferNode::Allocator* allocator);
261231
~PtrQueueSet();
262232

233+
// Discard any buffered enqueued data.
234+
void reset_queue(PtrQueue& queue);
235+
263236
// If queue has any buffered enqueued data, transfer it to this qset.
264237
// Otherwise, deallocate queue's buffer.
265238
void flush_queue(PtrQueue& queue);

src/hotspot/share/gc/shared/satbMarkQueue.cpp

+4-13
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,6 @@ SATBMarkQueue::SATBMarkQueue(SATBMarkQueueSet* qset) :
4747
_active(false)
4848
{ }
4949

50-
void SATBMarkQueue::apply_closure_and_empty(SATBBufferClosure* cl) {
51-
assert(SafepointSynchronize::is_at_safepoint(),
52-
"SATB queues must only be processed at safepoints");
53-
if (_buf != NULL) {
54-
cl->do_buffer(&_buf[index()], size());
55-
reset();
56-
}
57-
}
58-
5950
#ifndef PRODUCT
6051
// Helpful for debugging
6152

@@ -359,12 +350,12 @@ void SATBMarkQueueSet::abandon_partial_marking() {
359350
abandon_completed_buffers();
360351

361352
class AbandonThreadQueueClosure : public ThreadClosure {
362-
SATBMarkQueueSet* _qset;
353+
SATBMarkQueueSet& _qset;
363354
public:
364-
AbandonThreadQueueClosure(SATBMarkQueueSet* qset) : _qset(qset) {}
355+
AbandonThreadQueueClosure(SATBMarkQueueSet& qset) : _qset(qset) {}
365356
virtual void do_thread(Thread* t) {
366-
_qset->satb_queue_for_thread(t).reset();
357+
_qset.reset_queue(_qset.satb_queue_for_thread(t));
367358
}
368-
} closure(this);
359+
} closure(*this);
369360
Threads::threads_do(&closure);
370361
}

src/hotspot/share/gc/shared/satbMarkQueue.hpp

-4
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,6 @@ class SATBMarkQueue: public PtrQueue {
6565

6666
inline SATBMarkQueueSet* satb_qset() const;
6767

68-
// Apply cl to the active part of the buffer.
69-
// Prerequisite: Must be at a safepoint.
70-
void apply_closure_and_empty(SATBBufferClosure* cl);
71-
7268
#ifndef PRODUCT
7369
// Helpful for debugging
7470
void print(const char* name);

src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ void ShenandoahBarrierSet::on_thread_attach(Thread *thread) {
105105
"We should not be at a safepoint");
106106
SATBMarkQueue& queue = ShenandoahThreadLocalData::satb_mark_queue(thread);
107107
assert(!queue.is_active(), "SATB queue should not be active");
108-
assert( queue.is_empty(), "SATB queue should be empty");
108+
assert(queue.buffer() == nullptr, "SATB queue should not have a buffer");
109+
assert(queue.index() == 0, "SATB queue index should be zero");
109110
queue.set_active(_satb_mark_queue_set.is_active());
110111
if (thread->is_Java_thread()) {
111112
ShenandoahThreadLocalData::set_gc_state(thread, _heap->gc_state());

src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp

+9-7
Original file line numberDiff line numberDiff line change
@@ -105,19 +105,21 @@ class ShenandoahConcurrentMarkingTask : public AbstractGangTask {
105105

106106
class ShenandoahSATBAndRemarkCodeRootsThreadsClosure : public ThreadClosure {
107107
private:
108-
ShenandoahSATBBufferClosure* _satb_cl;
109-
OopClosure* const _cl;
110-
MarkingCodeBlobClosure* _code_cl;
108+
SATBMarkQueueSet& _satb_qset;
109+
OopClosure* const _cl;
110+
MarkingCodeBlobClosure* _code_cl;
111111
uintx _claim_token;
112112

113113
public:
114-
ShenandoahSATBAndRemarkCodeRootsThreadsClosure(ShenandoahSATBBufferClosure* satb_cl, OopClosure* cl, MarkingCodeBlobClosure* code_cl) :
115-
_satb_cl(satb_cl), _cl(cl), _code_cl(code_cl),
114+
ShenandoahSATBAndRemarkCodeRootsThreadsClosure(SATBMarkQueueSet& satb_qset, OopClosure* cl, MarkingCodeBlobClosure* code_cl) :
115+
_satb_qset(satb_qset),
116+
_cl(cl), _code_cl(code_cl),
116117
_claim_token(Threads::thread_claim_token()) {}
117118

118119
void do_thread(Thread* thread) {
119120
if (thread->claim_threads_do(true, _claim_token)) {
120-
ShenandoahThreadLocalData::satb_mark_queue(thread).apply_closure_and_empty(_satb_cl);
121+
// Transfer any partial buffer to the qset for completed buffer processing.
122+
_satb_qset.flush_queue(ShenandoahThreadLocalData::satb_mark_queue(thread));
121123
if (thread->is_Java_thread()) {
122124
if (_cl != NULL) {
123125
ResourceMark rm;
@@ -165,7 +167,7 @@ class ShenandoahFinalMarkingTask : public AbstractGangTask {
165167
bool do_nmethods = heap->unload_classes() && !ShenandoahConcurrentRoots::can_do_concurrent_class_unloading();
166168
ShenandoahMarkRefsClosure mark_cl(q, rp);
167169
MarkingCodeBlobClosure blobsCl(&mark_cl, !CodeBlobToOopClosure::FixRelocations);
168-
ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(&cl,
170+
ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(satb_mq_set,
169171
ShenandoahIUBarrier ? &mark_cl : NULL,
170172
do_nmethods ? &blobsCl : NULL);
171173
Threads::threads_do(&tc);

0 commit comments

Comments
 (0)