mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-19 18:44:38 +02:00
8255019: Shenandoah: Split STW and concurrent mark into separate classes
Reviewed-by: rkennke, shade
This commit is contained in:
parent
aba3431c4e
commit
da6bcf966a
20 changed files with 943 additions and 631 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 2020, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2019, 2021, Red Hat, Inc. 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
|
||||
|
@ -116,7 +116,6 @@ void ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::cld_do_impl(Cl
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
template <bool CONCURRENT, bool SINGLE_THREADED>
|
||||
void ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::always_strong_cld_do(CLDClosure* clds, uint worker_id) {
|
||||
cld_do_impl(&ClassLoaderDataGraph::always_strong_cld_do, clds, worker_id);
|
||||
|
@ -144,48 +143,33 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
template <bool CONCURRENT>
|
||||
ShenandoahConcurrentRootScanner<CONCURRENT>::ShenandoahConcurrentRootScanner(uint n_workers,
|
||||
ShenandoahPhaseTimings::Phase phase) :
|
||||
_vm_roots(phase),
|
||||
_cld_roots(phase, n_workers),
|
||||
_codecache_snapshot(NULL),
|
||||
_phase(phase) {
|
||||
if (!ShenandoahHeap::heap()->unload_classes()) {
|
||||
if (CONCURRENT) {
|
||||
CodeCache_lock->lock_without_safepoint_check();
|
||||
} else {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
|
||||
}
|
||||
_codecache_snapshot = ShenandoahCodeRoots::table()->snapshot_for_iteration();
|
||||
}
|
||||
assert(!CONCURRENT || !ShenandoahHeap::heap()->has_forwarded_objects(), "Not expecting forwarded pointers during concurrent marking");
|
||||
}
|
||||
// The rationale for selecting the roots to scan is as follows:
|
||||
// a. With unload_classes = true, we only want to scan the actual strong roots from the
|
||||
// code cache. This will allow us to identify the dead classes, unload them, *and*
|
||||
// invalidate the relevant code cache blobs. This could be only done together with
|
||||
// class unloading.
|
||||
// b. With unload_classes = false, we have to nominally retain all the references from code
|
||||
// cache, because there could be the case of embedded class/oop in the generated code,
|
||||
// which we will never visit during mark. Without code cache invalidation, as in (a),
|
||||
// we risk executing that code cache blob, and crashing.
|
||||
template <typename T>
|
||||
void ShenandoahSTWRootScanner::roots_do(T* oops, uint worker_id) {
|
||||
MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations);
|
||||
CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
|
||||
ResourceMark rm;
|
||||
|
||||
template <bool CONCURRENT>
|
||||
ShenandoahConcurrentRootScanner<CONCURRENT>::~ShenandoahConcurrentRootScanner() {
|
||||
if (!ShenandoahHeap::heap()->unload_classes()) {
|
||||
ShenandoahCodeRoots::table()->finish_iteration(_codecache_snapshot);
|
||||
if (CONCURRENT) {
|
||||
CodeCache_lock->unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <bool CONCURRENT>
|
||||
void ShenandoahConcurrentRootScanner<CONCURRENT>::oops_do(OopClosure* oops, uint worker_id) {
|
||||
ShenandoahHeap* const heap = ShenandoahHeap::heap();
|
||||
CLDToOopClosure clds_cl(oops, CONCURRENT ? ClassLoaderData::_claim_strong : ClassLoaderData::_claim_none);
|
||||
_vm_roots.oops_do(oops, worker_id);
|
||||
|
||||
if (!heap->unload_classes()) {
|
||||
_cld_roots.cld_do(&clds_cl, worker_id);
|
||||
ShenandoahWorkerTimingsTracker timer(_phase, ShenandoahPhaseTimings::CodeCacheRoots, worker_id);
|
||||
CodeBlobToOopClosure blobs(oops, !CodeBlobToOopClosure::FixRelocations);
|
||||
_codecache_snapshot->parallel_blobs_do(&blobs);
|
||||
if (_unload_classes) {
|
||||
_thread_roots.oops_do(oops, &blobs_cl, worker_id);
|
||||
_cld_roots.always_strong_cld_do(&clds, worker_id);
|
||||
} else {
|
||||
_cld_roots.always_strong_cld_do(&clds_cl, worker_id);
|
||||
AlwaysTrueClosure always_true;
|
||||
_thread_roots.oops_do(oops, NULL, worker_id);
|
||||
_code_roots.code_blobs_do(&blobs_cl, worker_id);
|
||||
_cld_roots.cld_do(&clds, worker_id);
|
||||
_dedup_roots.oops_do(&always_true, oops, worker_id);
|
||||
}
|
||||
|
||||
_vm_roots.oops_do<T>(oops, worker_id);
|
||||
}
|
||||
|
||||
template <typename IsAlive, typename KeepAlive>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue