8258490: Shenandoah: Full GC does not need to remark threads and drain SATB buffers

Reviewed-by: shade
This commit is contained in:
Zhengyu Gu 2021-01-04 18:10:36 +00:00
parent 7f04d23be4
commit f80c63b380

@ -225,6 +225,18 @@ void ShenandoahProcessConcurrentRootsTask<T>::work(uint worker_id) {
_rs.oops_do(&cl, worker_id);
}
class ShenandoahClaimThreadClosure : public ThreadClosure {
private:
const uintx _claim_token;
public:
ShenandoahClaimThreadClosure() :
_claim_token(Threads::thread_claim_token()) {}
virtual void do_thread(Thread* thread) {
thread->claim_threads_do(false /*is_par*/, _claim_token);
}
};
class ShenandoahFinalMarkingTask : public AbstractGangTask {
private:
ShenandoahConcurrentMark* _cm;
@ -234,6 +246,13 @@ private:
public:
ShenandoahFinalMarkingTask(ShenandoahConcurrentMark* cm, TaskTerminator* terminator, bool dedup_string) :
AbstractGangTask("Shenandoah Final Mark"), _cm(cm), _terminator(terminator), _dedup_string(dedup_string) {
// Full GC does not need to remark threads and drain SATB buffers, but we need to claim the
// threads - it requires a StrongRootsScope around the task.
if (ShenandoahHeap::heap()->is_full_gc_in_progress()) {
ShenandoahClaimThreadClosure tc;
Threads::threads_do(&tc);
}
}
void work(uint worker_id) {
@ -242,33 +261,20 @@ public:
ShenandoahParallelWorkerSession worker_session(worker_id);
ShenandoahReferenceProcessor* rp = heap->ref_processor();
// First drain remaining SATB buffers.
// Notice that this is not strictly necessary for mark-compact. But since
// it requires a StrongRootsScope around the task, we need to claim the
// threads, and performance-wise it doesn't really matter. Adds about 1ms to
// full-gc.
{
if (!heap->is_full_gc_in_progress()) {
ShenandoahObjToScanQueue* q = _cm->get_queue(worker_id);
ShenandoahSATBBufferClosure cl(q);
SATBMarkQueueSet& satb_mq_set = ShenandoahBarrierSet::satb_mark_queue_set();
while (satb_mq_set.apply_closure_to_completed_buffer(&cl));
while (satb_mq_set.apply_closure_to_completed_buffer(&cl)) {}
assert(!heap->has_forwarded_objects(), "Not expected");
bool do_nmethods = heap->unload_classes() && !ShenandoahConcurrentRoots::can_do_concurrent_class_unloading();
if (heap->has_forwarded_objects()) {
ShenandoahMarkResolveRefsClosure resolve_mark_cl(q, rp);
MarkingCodeBlobClosure blobsCl(&resolve_mark_cl, !CodeBlobToOopClosure::FixRelocations);
ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(&cl,
ShenandoahStoreValEnqueueBarrier ? &resolve_mark_cl : NULL,
do_nmethods ? &blobsCl : NULL);
Threads::threads_do(&tc);
} else {
ShenandoahMarkRefsClosure mark_cl(q, rp);
MarkingCodeBlobClosure blobsCl(&mark_cl, !CodeBlobToOopClosure::FixRelocations);
ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(&cl,
ShenandoahStoreValEnqueueBarrier ? &mark_cl : NULL,
do_nmethods ? &blobsCl : NULL);
Threads::threads_do(&tc);
}
ShenandoahMarkRefsClosure mark_cl(q, rp);
MarkingCodeBlobClosure blobsCl(&mark_cl, !CodeBlobToOopClosure::FixRelocations);
ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(&cl,
ShenandoahStoreValEnqueueBarrier ? &mark_cl : NULL,
do_nmethods ? &blobsCl : NULL);
Threads::threads_do(&tc);
}
_cm->mark_loop(worker_id, _terminator, rp,