Skip to content

Commit

Permalink
8273559: Shenandoah: Shenandoah should support multi-threaded heap dump
Browse files Browse the repository at this point in the history
Reviewed-by: shade, rkennke, sgehwolf
  • Loading branch information
zhengyu123 committed Sep 15, 2021
1 parent f531b5c commit 8132bfd
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 45 deletions.
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 @@ -1317,7 +1317,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

3 comments on commit 8132bfd

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

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

@earthling-amzn
Copy link
Contributor

Choose a reason for hiding this comment

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

/backport jdk17u-dev

@openjdk
Copy link

@openjdk openjdk bot commented on 8132bfd Jun 15, 2023

Choose a reason for hiding this comment

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

@earthling-amzn Could not automatically backport 8132bfd2 to openjdk/jdk17u-dev due to conflicts in the following files:

  • src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp

Please fetch the appropriate branch/commit and manually resolve these conflicts by using the following commands in your personal fork of openjdk/jdk17u-dev. Note: these commands are just some suggestions and you can use other equivalent commands you know.

# Fetch the up-to-date version of the target branch
$ git fetch --no-tags https://git.openjdk.org/jdk17u-dev.git master:master

# Check out the target branch and create your own branch to backport
$ git checkout master
$ git checkout -b earthling-amzn-backport-8132bfd2

# Fetch the commit you want to backport
$ git fetch --no-tags https://git.openjdk.org/jdk.git 8132bfd23f2f7fb52e502a3e6fe488fbdb537df0

# Backport the commit
$ git cherry-pick --no-commit 8132bfd23f2f7fb52e502a3e6fe488fbdb537df0
# Resolve conflicts now

# Commit the files you have modified
$ git add files/with/resolved/conflicts
$ git commit -m 'Backport 8132bfd23f2f7fb52e502a3e6fe488fbdb537df0'

Once you have resolved the conflicts as explained above continue with creating a pull request towards the openjdk/jdk17u-dev with the title Backport 8132bfd23f2f7fb52e502a3e6fe488fbdb537df0.

Please sign in to comment.