Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8273559: Shenandoah: Shenandoah should support multi-threaded heap dump #5473

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,7 @@ class ShenandoahConcurrentWeakRootsEvacUpdateTask : public AbstractGangTask {
ShenandoahVMWeakRoots<true /*concurrent*/> _vm_roots;

// Roots related to concurrent class unloading
ShenandoahClassLoaderDataRoots<true /* concurrent */, true /* single thread*/>
ShenandoahClassLoaderDataRoots<true /* concurrent */>
_cld_roots;
ShenandoahConcurrentNMethodIterator _nmethod_itr;
ShenandoahPhaseTimings::Phase _phase;
Expand All @@ -734,7 +734,7 @@ class ShenandoahConcurrentWeakRootsEvacUpdateTask : public AbstractGangTask {
ShenandoahConcurrentWeakRootsEvacUpdateTask(ShenandoahPhaseTimings::Phase phase) :
AbstractGangTask("Shenandoah Evacuate/Update Concurrent Weak Roots"),
_vm_roots(phase),
_cld_roots(phase, ShenandoahHeap::heap()->workers()->active_workers()),
_cld_roots(phase, ShenandoahHeap::heap()->workers()->active_workers(), false /*heap iteration*/),
_nmethod_itr(ShenandoahCodeRoots::table()),
_phase(phase) {
if (ShenandoahHeap::heap()->unload_classes()) {
Expand Down Expand Up @@ -838,15 +838,16 @@ class ShenandoahConcurrentRootsEvacUpdateTask : public AbstractGangTask {
private:
ShenandoahPhaseTimings::Phase _phase;
ShenandoahVMRoots<true /*concurrent*/> _vm_roots;
ShenandoahClassLoaderDataRoots<true /*concurrent*/, false /*single threaded*/> _cld_roots;
ShenandoahClassLoaderDataRoots<true /*concurrent*/>
_cld_roots;
ShenandoahConcurrentNMethodIterator _nmethod_itr;

public:
ShenandoahConcurrentRootsEvacUpdateTask(ShenandoahPhaseTimings::Phase phase) :
AbstractGangTask("Shenandoah Evacuate/Update Concurrent Strong Roots"),
_phase(phase),
_vm_roots(phase),
_cld_roots(phase, ShenandoahHeap::heap()->workers()->active_workers()),
_cld_roots(phase, ShenandoahHeap::heap()->workers()->active_workers(), false /*heap iteration*/),
_nmethod_itr(ShenandoahCodeRoots::table()) {
if (!ShenandoahHeap::heap()->unload_classes()) {
MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1319,7 +1319,8 @@ void ShenandoahHeap::scan_roots_for_iteration(ShenandoahScanObjectStack* oop_sta
// This populates the work stack with initial objects
// It is important to relinquish the associated locks before diving
// into heap dumper
ShenandoahHeapIterationRootScanner rp;
uint n_workers = safepoint_workers() != NULL ? safepoint_workers()->active_workers() : 1;
ShenandoahHeapIterationRootScanner rp(n_workers);
rp.roots_do(oops);
}

Expand Down
16 changes: 8 additions & 8 deletions src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ ShenandoahSTWRootScanner::ShenandoahSTWRootScanner(ShenandoahPhaseTimings::Phase
ShenandoahRootProcessor(phase),
_thread_roots(phase, ShenandoahHeap::heap()->workers()->active_workers() > 1),
_code_roots(phase),
_cld_roots(phase, ShenandoahHeap::heap()->workers()->active_workers()),
_cld_roots(phase, ShenandoahHeap::heap()->workers()->active_workers(), false /*heap iteration*/),
_vm_roots(phase),
_unload_classes(ShenandoahHeap::heap()->unload_classes()) {
}
Expand Down Expand Up @@ -154,7 +154,7 @@ ShenandoahConcurrentRootScanner::ShenandoahConcurrentRootScanner(uint n_workers,
ShenandoahRootProcessor(phase),
_java_threads(phase, n_workers),
_vm_roots(phase),
_cld_roots(phase, n_workers),
_cld_roots(phase, n_workers, false /*heap iteration*/),
_codecache_snapshot(NULL),
_phase(phase) {
if (!ShenandoahHeap::heap()->unload_classes()) {
Expand Down Expand Up @@ -213,7 +213,7 @@ void ShenandoahConcurrentRootScanner::update_tlab_stats() {
ShenandoahRootUpdater::ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
ShenandoahRootProcessor(phase),
_vm_roots(phase),
_cld_roots(phase, n_workers),
_cld_roots(phase, n_workers, false /*heap iteration*/),
_thread_roots(phase, n_workers > 1),
_weak_roots(phase),
_code_roots(phase) {
Expand All @@ -222,7 +222,7 @@ ShenandoahRootUpdater::ShenandoahRootUpdater(uint n_workers, ShenandoahPhaseTimi
ShenandoahRootAdjuster::ShenandoahRootAdjuster(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
ShenandoahRootProcessor(phase),
_vm_roots(phase),
_cld_roots(phase, n_workers),
_cld_roots(phase, n_workers, false /*heap iteration*/),
_thread_roots(phase, n_workers > 1),
_weak_roots(phase),
_code_roots(phase) {
Expand All @@ -248,18 +248,18 @@ void ShenandoahRootAdjuster::roots_do(uint worker_id, OopClosure* oops) {
_thread_roots.oops_do(oops, NULL, worker_id);
}

ShenandoahHeapIterationRootScanner::ShenandoahHeapIterationRootScanner() :
ShenandoahHeapIterationRootScanner::ShenandoahHeapIterationRootScanner(uint n_workers) :
ShenandoahRootProcessor(ShenandoahPhaseTimings::heap_iteration_roots),
_thread_roots(ShenandoahPhaseTimings::heap_iteration_roots, false /*is par*/),
_vm_roots(ShenandoahPhaseTimings::heap_iteration_roots),
_cld_roots(ShenandoahPhaseTimings::heap_iteration_roots, 1),
_cld_roots(ShenandoahPhaseTimings::heap_iteration_roots, n_workers, true /*heap iteration*/),
_weak_roots(ShenandoahPhaseTimings::heap_iteration_roots),
_code_roots(ShenandoahPhaseTimings::heap_iteration_roots) {
}

void ShenandoahHeapIterationRootScanner::roots_do(OopClosure* oops) {
// Must use _claim_none to avoid interfering with concurrent CLDG iteration
CLDToOopClosure clds(oops, ClassLoaderData::_claim_none);
// Must use _claim_other to avoid interfering with concurrent CLDG iteration
CLDToOopClosure clds(oops, ClassLoaderData::_claim_other);
MarkingCodeBlobClosure code(oops, !CodeBlobToOopClosure::FixRelocations);
ShenandoahParallelOopsDoThreadClosure tc_cl(oops, &code, NULL);
AlwaysTrueClosure always_true;
Expand Down
21 changes: 8 additions & 13 deletions src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,23 +107,21 @@ class ShenandoahCodeCacheRoots {
void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id);
};

template <bool CONCURRENT, bool SINGLE_THREADED>
template <bool CONCURRENT>
class ShenandoahClassLoaderDataRoots {
private:
ShenandoahSharedSemaphore _semaphore;
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.
return MAX2(1u, MIN2(ShenandoahSharedSemaphore::max_tokens(), n_workers / 2));
}

public:
ShenandoahClassLoaderDataRoots(ShenandoahPhaseTimings::Phase phase, uint n_workers);
ShenandoahClassLoaderDataRoots(ShenandoahPhaseTimings::Phase phase, uint n_workers, bool heap_iteration);
~ShenandoahClassLoaderDataRoots();

void always_strong_cld_do(CLDClosure* clds, uint worker_id);
Expand Down Expand Up @@ -164,7 +162,7 @@ class ShenandoahSTWRootScanner : public ShenandoahRootProcessor {
private:
ShenandoahThreadRoots _thread_roots;
ShenandoahCodeCacheRoots _code_roots;
ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /* single_thread*/>
ShenandoahClassLoaderDataRoots<false /*concurrent*/>
_cld_roots;
ShenandoahVMRoots<false /*concurrent*/>
_vm_roots;
Expand All @@ -180,7 +178,7 @@ class ShenandoahConcurrentRootScanner : public ShenandoahRootProcessor {
private:
ShenandoahJavaThreadsIterator _java_threads;
ShenandoahVMRoots<true /*concurrent*/> _vm_roots;
ShenandoahClassLoaderDataRoots<true /*concurrent*/, false /* single-threaded*/>
ShenandoahClassLoaderDataRoots<true /*concurrent*/>
_cld_roots;
ShenandoahNMethodTableSnapshot* _codecache_snapshot;
ShenandoahPhaseTimings::Phase _phase;
Expand All @@ -201,13 +199,12 @@ class ShenandoahHeapIterationRootScanner : public ShenandoahRootProcessor {
private:
ShenandoahThreadRoots _thread_roots;
ShenandoahVMRoots<false /*concurrent*/> _vm_roots;
ShenandoahClassLoaderDataRoots<false /*concurrent*/, true /*single threaded*/>
_cld_roots;
ShenandoahClassLoaderDataRoots<false /*concurrent*/> _cld_roots;
ShenandoahVMWeakRoots<false /*concurrent*/> _weak_roots;
ShenandoahCodeCacheRoots _code_roots;

public:
ShenandoahHeapIterationRootScanner();
ShenandoahHeapIterationRootScanner(uint n_workers);

void roots_do(OopClosure* cl);
};
Expand All @@ -216,8 +213,7 @@ class ShenandoahHeapIterationRootScanner : public ShenandoahRootProcessor {
class ShenandoahRootUpdater : public ShenandoahRootProcessor {
private:
ShenandoahVMRoots<false /*concurrent*/> _vm_roots;
ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
_cld_roots;
ShenandoahClassLoaderDataRoots<false /*concurrent*/> _cld_roots;
ShenandoahThreadRoots _thread_roots;
ShenandoahVMWeakRoots<false /*concurrent*/> _weak_roots;
ShenandoahCodeCacheRoots _code_roots;
Expand All @@ -233,8 +229,7 @@ class ShenandoahRootUpdater : public ShenandoahRootProcessor {
class ShenandoahRootAdjuster : public ShenandoahRootProcessor {
private:
ShenandoahVMRoots<false /*concurrent*/> _vm_roots;
ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
_cld_roots;
ShenandoahClassLoaderDataRoots<false /*concurrent*/> _cld_roots;
ShenandoahThreadRoots _thread_roots;
ShenandoahVMWeakRoots<false /*concurrent*/> _weak_roots;
ShenandoahCodeCacheRoots _code_roots;
Expand Down
36 changes: 17 additions & 19 deletions src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,39 +75,37 @@ void ShenandoahVMRoots<CONCURRENT>::oops_do(T* cl, uint worker_id) {
_strong_roots.oops_do(cl);
}

template <bool CONCURRENT, bool SINGLE_THREADED>
ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::ShenandoahClassLoaderDataRoots(ShenandoahPhaseTimings::Phase phase, uint n_workers) :
template <bool CONCURRENT>
ShenandoahClassLoaderDataRoots<CONCURRENT>::ShenandoahClassLoaderDataRoots(ShenandoahPhaseTimings::Phase phase, uint n_workers, bool heap_iteration) :
_semaphore(worker_count(n_workers)),
_phase(phase) {
if (!SINGLE_THREADED) {
if (heap_iteration) {
ClassLoaderDataGraph::clear_claimed_marks(ClassLoaderData::_claim_other);
} else {
ClassLoaderDataGraph::clear_claimed_marks();
}
if (CONCURRENT && !SINGLE_THREADED) {

if (CONCURRENT) {
ClassLoaderDataGraph_lock->lock();
}

// Non-concurrent mode only runs at safepoints
assert(CONCURRENT || SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
}

template <bool CONCURRENT, bool SINGLE_THREADED>
ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::~ShenandoahClassLoaderDataRoots() {
if (CONCURRENT && !SINGLE_THREADED) {
template <bool CONCURRENT>
ShenandoahClassLoaderDataRoots<CONCURRENT>::~ShenandoahClassLoaderDataRoots() {
if (CONCURRENT) {
ClassLoaderDataGraph_lock->unlock();
}
}

template <bool CONCURRENT, bool SINGLE_THREADED>
void ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::cld_do_impl(CldDo f, CLDClosure* clds, uint worker_id) {
template <bool CONCURRENT>
void ShenandoahClassLoaderDataRoots<CONCURRENT>::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);
}
f(clds);
_semaphore.claim_all();
}
} else {
Expand All @@ -116,13 +114,13 @@ 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) {
template <bool CONCURRENT>
void ShenandoahClassLoaderDataRoots<CONCURRENT>::always_strong_cld_do(CLDClosure* clds, uint worker_id) {
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) {
template <bool CONCURRENT>
void ShenandoahClassLoaderDataRoots<CONCURRENT>::cld_do(CLDClosure* clds, uint worker_id) {
cld_do_impl(&ClassLoaderDataGraph::cld_do, clds, worker_id);
}

Expand Down
Loading