Skip to content
Permalink
Browse files
8255070: Shenandoah: Use single thread for concurrent CLD liveness test
Reviewed-by: rkennke
  • Loading branch information
zhengyu123 committed Oct 21, 2020
1 parent 6020991 commit 615b759edd99e0a063eeb6f748f22345dc4e376c
Showing 3 changed files with 34 additions and 21 deletions.
@@ -1941,7 +1941,7 @@ class ShenandoahConcurrentWeakRootsEvacUpdateTask : public AbstractGangTask {
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 @@ class ShenandoahClassLoaderDataRoots {
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 @@ class ShenandoahClassLoaderDataRoots {

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 {

1 comment on commit 615b759

@bridgekeeper
Copy link

@bridgekeeper bridgekeeper bot commented on 615b759 Oct 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.