mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8226310: Shenandoah: Concurrent evacuation of CLDG
Reviewed-by: rkennke
This commit is contained in:
parent
cfb99c9382
commit
13d3c63405
4 changed files with 42 additions and 17 deletions
|
@ -1524,6 +1524,7 @@ void ShenandoahHeap::op_final_mark() {
|
||||||
if (ShenandoahVerify) {
|
if (ShenandoahVerify) {
|
||||||
if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) {
|
if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) {
|
||||||
ShenandoahRootVerifier::RootTypes types = ShenandoahRootVerifier::combine(ShenandoahRootVerifier::JNIHandleRoots, ShenandoahRootVerifier::WeakRoots);
|
ShenandoahRootVerifier::RootTypes types = ShenandoahRootVerifier::combine(ShenandoahRootVerifier::JNIHandleRoots, ShenandoahRootVerifier::WeakRoots);
|
||||||
|
types = ShenandoahRootVerifier::combine(types, ShenandoahRootVerifier::CLDGRoots);
|
||||||
verifier()->verify_roots_no_forwarded_except(types);
|
verifier()->verify_roots_no_forwarded_except(types);
|
||||||
} else {
|
} else {
|
||||||
verifier()->verify_roots_no_forwarded();
|
verifier()->verify_roots_no_forwarded();
|
||||||
|
@ -1592,6 +1593,7 @@ class ShenandoahConcurrentRootsEvacUpdateTask : public AbstractGangTask {
|
||||||
private:
|
private:
|
||||||
ShenandoahJNIHandleRoots<true /*concurrent*/> _jni_roots;
|
ShenandoahJNIHandleRoots<true /*concurrent*/> _jni_roots;
|
||||||
ShenandoahWeakRoots<true /*concurrent*/> _weak_roots;
|
ShenandoahWeakRoots<true /*concurrent*/> _weak_roots;
|
||||||
|
ShenandoahClassLoaderDataRoots<true /*concurrent*/, false /*single threaded*/> _cld_roots;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ShenandoahConcurrentRootsEvacUpdateTask() :
|
ShenandoahConcurrentRootsEvacUpdateTask() :
|
||||||
|
@ -1601,8 +1603,10 @@ public:
|
||||||
void work(uint worker_id) {
|
void work(uint worker_id) {
|
||||||
ShenandoahEvacOOMScope oom;
|
ShenandoahEvacOOMScope oom;
|
||||||
ShenandoahEvacuateUpdateRootsClosure cl;
|
ShenandoahEvacuateUpdateRootsClosure cl;
|
||||||
|
CLDToOopClosure clds(&cl, ClassLoaderData::_claim_strong);
|
||||||
|
|
||||||
_jni_roots.oops_do<ShenandoahEvacuateUpdateRootsClosure>(&cl);
|
_jni_roots.oops_do<ShenandoahEvacuateUpdateRootsClosure>(&cl);
|
||||||
|
_cld_roots.cld_do(&clds);
|
||||||
_weak_roots.oops_do<ShenandoahEvacuateUpdateRootsClosure>(&cl);
|
_weak_roots.oops_do<ShenandoahEvacuateUpdateRootsClosure>(&cl);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -162,18 +162,18 @@ ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers, ShenandoahPhase
|
||||||
|
|
||||||
void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) {
|
void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) {
|
||||||
MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations);
|
MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations);
|
||||||
CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
|
|
||||||
AlwaysTrueClosure always_true;
|
AlwaysTrueClosure always_true;
|
||||||
|
|
||||||
_serial_roots.oops_do(oops, worker_id);
|
_serial_roots.oops_do(oops, worker_id);
|
||||||
_serial_weak_roots.weak_oops_do(oops, worker_id);
|
_serial_weak_roots.weak_oops_do(oops, worker_id);
|
||||||
if (_include_concurrent_roots) {
|
if (_include_concurrent_roots) {
|
||||||
|
CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
|
||||||
_jni_roots.oops_do<OopClosure>(oops, worker_id);
|
_jni_roots.oops_do<OopClosure>(oops, worker_id);
|
||||||
|
_cld_roots.cld_do(&clds, worker_id);
|
||||||
_weak_roots.oops_do<OopClosure>(oops, worker_id);
|
_weak_roots.oops_do<OopClosure>(oops, worker_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
_thread_roots.oops_do(oops, NULL, worker_id);
|
_thread_roots.oops_do(oops, NULL, worker_id);
|
||||||
_cld_roots.cld_do(&clds, worker_id);
|
|
||||||
_code_roots.code_blobs_do(&blobsCl, worker_id);
|
_code_roots.code_blobs_do(&blobsCl, worker_id);
|
||||||
|
|
||||||
_dedup_roots.oops_do(&always_true, oops, worker_id);
|
_dedup_roots.oops_do(&always_true, oops, worker_id);
|
||||||
|
|
|
@ -190,13 +190,14 @@ public:
|
||||||
void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id);
|
void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <bool SINGLE_THREADED>
|
template <bool CONCURRENT, bool SINGLE_THREADED>
|
||||||
class ShenandoahClassLoaderDataRoots {
|
class ShenandoahClassLoaderDataRoots {
|
||||||
public:
|
public:
|
||||||
ShenandoahClassLoaderDataRoots();
|
ShenandoahClassLoaderDataRoots();
|
||||||
|
~ShenandoahClassLoaderDataRoots();
|
||||||
|
|
||||||
void always_strong_cld_do(CLDClosure* clds, uint worker_id);
|
void always_strong_cld_do(CLDClosure* clds, uint worker_id = 0);
|
||||||
void cld_do(CLDClosure* clds, uint worker_id);
|
void cld_do(CLDClosure* clds, uint worker_id = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ShenandoahRootProcessor : public StackObj {
|
class ShenandoahRootProcessor : public StackObj {
|
||||||
|
@ -217,7 +218,8 @@ private:
|
||||||
ShenandoahThreadRoots _thread_roots;
|
ShenandoahThreadRoots _thread_roots;
|
||||||
ShenandoahCodeCacheRoots<ITR> _code_roots;
|
ShenandoahCodeCacheRoots<ITR> _code_roots;
|
||||||
ShenandoahJNIHandleRoots<false /*concurrent*/ > _jni_roots;
|
ShenandoahJNIHandleRoots<false /*concurrent*/ > _jni_roots;
|
||||||
ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots;
|
ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
|
||||||
|
_cld_roots;
|
||||||
public:
|
public:
|
||||||
ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase);
|
ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase);
|
||||||
|
|
||||||
|
@ -242,7 +244,8 @@ private:
|
||||||
ShenandoahSerialRoots _serial_roots;
|
ShenandoahSerialRoots _serial_roots;
|
||||||
ShenandoahThreadRoots _thread_roots;
|
ShenandoahThreadRoots _thread_roots;
|
||||||
ShenandoahJNIHandleRoots<false /*concurrent*/> _jni_roots;
|
ShenandoahJNIHandleRoots<false /*concurrent*/> _jni_roots;
|
||||||
ShenandoahClassLoaderDataRoots<true /*single threaded*/> _cld_roots;
|
ShenandoahClassLoaderDataRoots<false /*concurrent*/, true /*single threaded*/>
|
||||||
|
_cld_roots;
|
||||||
ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots;
|
ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -257,7 +260,8 @@ class ShenandoahRootEvacuator : public ShenandoahRootProcessor {
|
||||||
private:
|
private:
|
||||||
ShenandoahSerialRoots _serial_roots;
|
ShenandoahSerialRoots _serial_roots;
|
||||||
ShenandoahJNIHandleRoots<false /*concurrent*/> _jni_roots;
|
ShenandoahJNIHandleRoots<false /*concurrent*/> _jni_roots;
|
||||||
ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots;
|
ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
|
||||||
|
_cld_roots;
|
||||||
ShenandoahThreadRoots _thread_roots;
|
ShenandoahThreadRoots _thread_roots;
|
||||||
ShenandoahSerialWeakRoots _serial_weak_roots;
|
ShenandoahSerialWeakRoots _serial_weak_roots;
|
||||||
ShenandoahWeakRoots<false /*concurrent*/> _weak_roots;
|
ShenandoahWeakRoots<false /*concurrent*/> _weak_roots;
|
||||||
|
@ -276,7 +280,8 @@ class ShenandoahRootUpdater : public ShenandoahRootProcessor {
|
||||||
private:
|
private:
|
||||||
ShenandoahSerialRoots _serial_roots;
|
ShenandoahSerialRoots _serial_roots;
|
||||||
ShenandoahJNIHandleRoots<false /*concurrent*/> _jni_roots;
|
ShenandoahJNIHandleRoots<false /*concurrent*/> _jni_roots;
|
||||||
ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots;
|
ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
|
||||||
|
_cld_roots;
|
||||||
ShenandoahThreadRoots _thread_roots;
|
ShenandoahThreadRoots _thread_roots;
|
||||||
ShenandoahSerialWeakRoots _serial_weak_roots;
|
ShenandoahSerialWeakRoots _serial_weak_roots;
|
||||||
ShenandoahWeakRoots<false /*concurrent*/> _weak_roots;
|
ShenandoahWeakRoots<false /*concurrent*/> _weak_roots;
|
||||||
|
@ -296,7 +301,8 @@ class ShenandoahRootAdjuster : public ShenandoahRootProcessor {
|
||||||
private:
|
private:
|
||||||
ShenandoahSerialRoots _serial_roots;
|
ShenandoahSerialRoots _serial_roots;
|
||||||
ShenandoahJNIHandleRoots<false /*concurrent*/> _jni_roots;
|
ShenandoahJNIHandleRoots<false /*concurrent*/> _jni_roots;
|
||||||
ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots;
|
ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
|
||||||
|
_cld_roots;
|
||||||
ShenandoahThreadRoots _thread_roots;
|
ShenandoahThreadRoots _thread_roots;
|
||||||
ShenandoahSerialWeakRoots _serial_weak_roots;
|
ShenandoahSerialWeakRoots _serial_weak_roots;
|
||||||
ShenandoahWeakRoots<false /*concurrent*/> _weak_roots;
|
ShenandoahWeakRoots<false /*concurrent*/> _weak_roots;
|
||||||
|
|
|
@ -119,19 +119,32 @@ void ShenandoahJNIHandleRoots<CONCURRENT>::oops_do(T* cl, uint worker_id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool SINGLE_THREADED>
|
template <bool CONCURRENT, bool SINGLE_THREADED>
|
||||||
ShenandoahClassLoaderDataRoots<SINGLE_THREADED>::ShenandoahClassLoaderDataRoots() {
|
ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::ShenandoahClassLoaderDataRoots() {
|
||||||
if (!SINGLE_THREADED) {
|
if (!SINGLE_THREADED) {
|
||||||
ClassLoaderDataGraph::clear_claimed_marks();
|
ClassLoaderDataGraph::clear_claimed_marks();
|
||||||
}
|
}
|
||||||
|
if (CONCURRENT) {
|
||||||
|
ClassLoaderDataGraph_lock->lock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool SINGLE_THREADED>
|
template <bool CONCURRENT, bool SINGLE_THREADED>
|
||||||
void ShenandoahClassLoaderDataRoots<SINGLE_THREADED>::always_strong_cld_do(CLDClosure* clds, uint worker_id) {
|
ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::~ShenandoahClassLoaderDataRoots() {
|
||||||
|
if (CONCURRENT) {
|
||||||
|
ClassLoaderDataGraph_lock->unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <bool CONCURRENT, bool SINGLE_THREADED>
|
||||||
|
void ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::always_strong_cld_do(CLDClosure* clds, uint worker_id) {
|
||||||
if (SINGLE_THREADED) {
|
if (SINGLE_THREADED) {
|
||||||
assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
|
assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
|
||||||
assert(Thread::current()->is_VM_thread(), "Single threaded CLDG iteration can only be done by VM thread");
|
assert(Thread::current()->is_VM_thread(), "Single threaded CLDG iteration can only be done by VM thread");
|
||||||
ClassLoaderDataGraph::always_strong_cld_do(clds);
|
ClassLoaderDataGraph::always_strong_cld_do(clds);
|
||||||
|
} else if (CONCURRENT) {
|
||||||
|
ClassLoaderDataGraph::always_strong_cld_do(clds);
|
||||||
} else {
|
} else {
|
||||||
ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
|
ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
|
||||||
ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id);
|
ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id);
|
||||||
|
@ -139,12 +152,14 @@ void ShenandoahClassLoaderDataRoots<SINGLE_THREADED>::always_strong_cld_do(CLDCl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool SINGLE_THREADED>
|
template <bool CONCURRENT, bool SINGLE_THREADED>
|
||||||
void ShenandoahClassLoaderDataRoots<SINGLE_THREADED>::cld_do(CLDClosure* clds, uint worker_id) {
|
void ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::cld_do(CLDClosure* clds, uint worker_id) {
|
||||||
if (SINGLE_THREADED) {
|
if (SINGLE_THREADED) {
|
||||||
assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
|
assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
|
||||||
assert(Thread::current()->is_VM_thread(), "Single threaded CLDG iteration can only be done by VM thread");
|
assert(Thread::current()->is_VM_thread(), "Single threaded CLDG iteration can only be done by VM thread");
|
||||||
ClassLoaderDataGraph::cld_do(clds);
|
ClassLoaderDataGraph::cld_do(clds);
|
||||||
|
} else if (CONCURRENT) {
|
||||||
|
ClassLoaderDataGraph::cld_do(clds);
|
||||||
} else {
|
} else {
|
||||||
ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
|
ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
|
||||||
ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id);
|
ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue