8255070: Shenandoah: Use single thread for concurrent CLD liveness test

Reviewed-by: rkennke
This commit is contained in:
Zhengyu Gu 2020-10-21 19:44:24 +00:00
parent 6020991530
commit 615b759edd
3 changed files with 34 additions and 21 deletions

@ -1941,7 +1941,7 @@ private:
ShenandoahVMWeakRoots<true /*concurrent*/> _vm_roots;
// Roots related to concurrent class unloading
ShenandoahClassLoaderDataRoots<true /* concurrent */, false /* single thread*/>
ShenandoahClassLoaderDataRoots<true /* concurrent */, true /* single thread*/>
_cld_roots;
ShenandoahConcurrentNMethodIterator _nmethod_itr;
ShenandoahConcurrentStringDedupRoots _dedup_roots;

@ -149,6 +149,8 @@ private:
ShenandoahPhaseTimings::Phase _phase;
static uint worker_count(uint n_workers) {
if (SINGLE_THREADED) return 1u;
// Limit concurrency a bit, otherwise it wastes resources when workers are tripping
// over each other. This also leaves free workers to process other parts of the root
// set, while admitted workers are busy with doing the CLDG walk.
@ -161,6 +163,10 @@ public:
void always_strong_cld_do(CLDClosure* clds, uint worker_id);
void cld_do(CLDClosure* clds, uint worker_id);
private:
typedef void (*CldDo)(CLDClosure*);
void cld_do_impl(CldDo f, CLDClosure* clds, uint worker_id);
};
class ShenandoahRootProcessor : public StackObj {

@ -35,6 +35,7 @@
#include "gc/shenandoah/shenandoahUtils.hpp"
#include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/safepoint.hpp"
template <bool CONCURRENT>
@ -81,43 +82,49 @@ ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::ShenandoahClassLoad
if (!SINGLE_THREADED) {
ClassLoaderDataGraph::clear_claimed_marks();
}
if (CONCURRENT) {
if (CONCURRENT && !SINGLE_THREADED) {
ClassLoaderDataGraph_lock->lock();
}
// Non-concurrent mode only runs at safepoints by VM thread
assert(CONCURRENT || SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
assert(CONCURRENT || Thread::current()->is_VM_thread(), "Can only be done by VM thread");
}
template <bool CONCURRENT, bool SINGLE_THREADED>
ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::~ShenandoahClassLoaderDataRoots() {
if (CONCURRENT) {
if (CONCURRENT && !SINGLE_THREADED) {
ClassLoaderDataGraph_lock->unlock();
}
}
template <bool CONCURRENT, bool SINGLE_THREADED>
void ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::cld_do_impl(CldDo f, CLDClosure* clds, uint worker_id) {
if (CONCURRENT) {
if (_semaphore.try_acquire()) {
ShenandoahWorkerTimingsTracker timer(_phase, ShenandoahPhaseTimings::CLDGRoots, worker_id);
if (SINGLE_THREADED){
MutexLocker ml(ClassLoaderDataGraph_lock, Mutex::_no_safepoint_check_flag);
f(clds);
} else {
f(clds);
}
_semaphore.claim_all();
}
} else {
f(clds);
}
}
template <bool CONCURRENT, bool SINGLE_THREADED>
void ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::always_strong_cld_do(CLDClosure* clds, uint worker_id) {
if (SINGLE_THREADED) {
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");
ClassLoaderDataGraph::always_strong_cld_do(clds);
} else if (_semaphore.try_acquire()) {
ShenandoahWorkerTimingsTracker timer(_phase, ShenandoahPhaseTimings::CLDGRoots, worker_id);
ClassLoaderDataGraph::always_strong_cld_do(clds);
_semaphore.claim_all();
}
cld_do_impl(&ClassLoaderDataGraph::always_strong_cld_do, clds, worker_id);
}
template <bool CONCURRENT, bool SINGLE_THREADED>
void ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::cld_do(CLDClosure* clds, uint worker_id) {
if (SINGLE_THREADED) {
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");
ClassLoaderDataGraph::cld_do(clds);
} else if (_semaphore.try_acquire()) {
ShenandoahWorkerTimingsTracker timer(_phase, ShenandoahPhaseTimings::CLDGRoots, worker_id);
ClassLoaderDataGraph::cld_do(clds);
_semaphore.claim_all();
}
cld_do_impl(&ClassLoaderDataGraph::cld_do, clds, worker_id);
}
class ShenandoahParallelOopsDoThreadClosure : public ThreadClosure {