8224210: Shenandoah: Refactor ShenandoahRootScanner to support scanning CSet codecache roots
Reviewed-by: shade
This commit is contained in:
parent
a0a09f03e4
commit
18a59944ef
@ -81,10 +81,10 @@ ShenandoahMarkRefsSuperClosure::ShenandoahMarkRefsSuperClosure(ShenandoahObjToSc
|
||||
template<UpdateRefsMode UPDATE_REFS>
|
||||
class ShenandoahInitMarkRootsTask : public AbstractGangTask {
|
||||
private:
|
||||
ShenandoahRootScanner* _rp;
|
||||
ShenandoahAllRootScanner* _rp;
|
||||
bool _process_refs;
|
||||
public:
|
||||
ShenandoahInitMarkRootsTask(ShenandoahRootScanner* rp, bool process_refs) :
|
||||
ShenandoahInitMarkRootsTask(ShenandoahAllRootScanner* rp, bool process_refs) :
|
||||
AbstractGangTask("Shenandoah init mark roots task"),
|
||||
_rp(rp),
|
||||
_process_refs(process_refs) {
|
||||
@ -251,7 +251,7 @@ void ShenandoahConcurrentMark::mark_roots(ShenandoahPhaseTimings::Phase root_pha
|
||||
|
||||
assert(nworkers <= task_queues()->size(), "Just check");
|
||||
|
||||
ShenandoahRootScanner root_proc(nworkers, root_phase);
|
||||
ShenandoahAllRootScanner root_proc(nworkers, root_phase);
|
||||
TASKQUEUE_STATS_ONLY(task_queues()->reset_taskqueue_stats());
|
||||
task_queues()->reserve(nworkers);
|
||||
|
||||
|
@ -1326,7 +1326,7 @@ void ShenandoahHeap::object_iterate(ObjectClosure* cl) {
|
||||
Stack<oop,mtGC> oop_stack;
|
||||
|
||||
// First, we process all GC roots. This populates the work stack with initial objects.
|
||||
ShenandoahRootScanner rp(1, ShenandoahPhaseTimings::_num_phases);
|
||||
ShenandoahAllRootScanner rp(1, ShenandoahPhaseTimings::_num_phases);
|
||||
ObjectIterateScanRootClosure oops(&_aux_bit_map, &oop_stack);
|
||||
rp.roots_do(0, &oops);
|
||||
|
||||
|
@ -135,23 +135,6 @@ void ShenandoahClassLoaderDataRoots::clds_do(CLDClosure* strong_clds, CLDClosure
|
||||
ClassLoaderDataGraph::roots_cld_do(strong_clds, weak_clds);
|
||||
}
|
||||
|
||||
class ShenandoahParallelOopsDoThreadClosure : public ThreadClosure {
|
||||
private:
|
||||
OopClosure* _f;
|
||||
CodeBlobClosure* _cf;
|
||||
ThreadClosure* _thread_cl;
|
||||
public:
|
||||
ShenandoahParallelOopsDoThreadClosure(OopClosure* f, CodeBlobClosure* cf, ThreadClosure* thread_cl) :
|
||||
_f(f), _cf(cf), _thread_cl(thread_cl) {}
|
||||
|
||||
void do_thread(Thread* t) {
|
||||
if (_thread_cl != NULL) {
|
||||
_thread_cl->do_thread(t);
|
||||
}
|
||||
t->oops_do(_f, _cf);
|
||||
}
|
||||
};
|
||||
|
||||
ShenandoahRootProcessor::ShenandoahRootProcessor(ShenandoahPhaseTimings::Phase phase) :
|
||||
_heap(ShenandoahHeap::heap()),
|
||||
_phase(phase) {
|
||||
@ -164,50 +147,6 @@ ShenandoahRootProcessor::~ShenandoahRootProcessor() {
|
||||
_heap->phase_timings()->record_workers_end(_phase);
|
||||
}
|
||||
|
||||
ShenandoahRootScanner::ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
|
||||
ShenandoahRootProcessor(phase),
|
||||
_thread_roots(n_workers > 1) {
|
||||
}
|
||||
|
||||
void ShenandoahRootScanner::roots_do(uint worker_id, OopClosure* oops) {
|
||||
CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
|
||||
MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations);
|
||||
roots_do(worker_id, oops, &clds_cl, &blobs_cl);
|
||||
}
|
||||
|
||||
void ShenandoahRootScanner::strong_roots_do(uint worker_id, OopClosure* oops) {
|
||||
CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
|
||||
MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations);
|
||||
strong_roots_do(worker_id, oops, &clds_cl, &blobs_cl);
|
||||
}
|
||||
|
||||
void ShenandoahRootScanner::roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure *tc) {
|
||||
assert(!ShenandoahHeap::heap()->unload_classes(), "Should be used during class unloading");
|
||||
ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
|
||||
ResourceMark rm;
|
||||
|
||||
_serial_roots.oops_do(oops, worker_id);
|
||||
_cld_roots.clds_do(clds, clds, worker_id);
|
||||
_thread_roots.threads_do(&tc_cl, worker_id);
|
||||
|
||||
// With ShenandoahConcurrentScanCodeRoots, we avoid scanning the entire code cache here,
|
||||
// and instead do that in concurrent phase under the relevant lock. This saves init mark
|
||||
// pause time.
|
||||
if (code != NULL && !ShenandoahConcurrentScanCodeRoots) {
|
||||
_code_roots.code_blobs_do(code, worker_id);
|
||||
}
|
||||
}
|
||||
|
||||
void ShenandoahRootScanner::strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc) {
|
||||
assert(ShenandoahHeap::heap()->unload_classes(), "Should be used during class unloading");
|
||||
ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
|
||||
ResourceMark rm;
|
||||
|
||||
_serial_roots.oops_do(oops, worker_id);
|
||||
_cld_roots.clds_do(clds, NULL, worker_id);
|
||||
_thread_roots.threads_do(&tc_cl, worker_id);
|
||||
}
|
||||
|
||||
ShenandoahRootEvacuator::ShenandoahRootEvacuator(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
|
||||
ShenandoahRootProcessor(phase),
|
||||
_thread_roots(n_workers > 1),
|
||||
|
@ -122,12 +122,13 @@ public:
|
||||
ShenandoahHeap* heap() const { return _heap; }
|
||||
};
|
||||
|
||||
template <typename ITR>
|
||||
class ShenandoahRootScanner : public ShenandoahRootProcessor {
|
||||
private:
|
||||
ShenandoahSerialRoots _serial_roots;
|
||||
ShenandoahClassLoaderDataRoots _cld_roots;
|
||||
ShenandoahThreadRoots _thread_roots;
|
||||
ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots;
|
||||
ShenandoahCodeCacheRoots<ITR> _code_roots;
|
||||
public:
|
||||
ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase);
|
||||
|
||||
@ -142,6 +143,9 @@ public:
|
||||
void roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc = NULL);
|
||||
};
|
||||
|
||||
typedef ShenandoahRootScanner<ShenandoahAllCodeRootsIterator> ShenandoahAllRootScanner;
|
||||
typedef ShenandoahRootScanner<ShenandoahCsetCodeRootsIterator> ShenandoahCSetRootScanner;
|
||||
|
||||
// Evacuate all roots at a safepoint
|
||||
class ShenandoahRootEvacuator : public ShenandoahRootProcessor {
|
||||
private:
|
||||
|
@ -24,6 +24,7 @@
|
||||
#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
|
||||
#define SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
|
||||
|
||||
#include "gc/shenandoah/shenandoahHeuristics.hpp"
|
||||
#include "gc/shenandoah/shenandoahRootProcessor.hpp"
|
||||
#include "gc/shenandoah/shenandoahTimingTracker.hpp"
|
||||
|
||||
@ -49,6 +50,74 @@ ShenandoahCodeCacheRoots<ITR>::~ShenandoahCodeCacheRoots() {
|
||||
nmethod::oops_do_marking_epilogue();
|
||||
}
|
||||
|
||||
class ShenandoahParallelOopsDoThreadClosure : public ThreadClosure {
|
||||
private:
|
||||
OopClosure* _f;
|
||||
CodeBlobClosure* _cf;
|
||||
ThreadClosure* _thread_cl;
|
||||
public:
|
||||
ShenandoahParallelOopsDoThreadClosure(OopClosure* f, CodeBlobClosure* cf, ThreadClosure* thread_cl) :
|
||||
_f(f), _cf(cf), _thread_cl(thread_cl) {}
|
||||
|
||||
void do_thread(Thread* t) {
|
||||
if (_thread_cl != NULL) {
|
||||
_thread_cl->do_thread(t);
|
||||
}
|
||||
t->oops_do(_f, _cf);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ITR>
|
||||
ShenandoahRootScanner<ITR>::ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase) :
|
||||
ShenandoahRootProcessor(phase),
|
||||
_thread_roots(n_workers > 1) {
|
||||
}
|
||||
|
||||
template <typename ITR>
|
||||
void ShenandoahRootScanner<ITR>::roots_do(uint worker_id, OopClosure* oops) {
|
||||
CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
|
||||
MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations);
|
||||
roots_do(worker_id, oops, &clds_cl, &blobs_cl);
|
||||
}
|
||||
|
||||
template <typename ITR>
|
||||
void ShenandoahRootScanner<ITR>::strong_roots_do(uint worker_id, OopClosure* oops) {
|
||||
CLDToOopClosure clds_cl(oops, ClassLoaderData::_claim_strong);
|
||||
MarkingCodeBlobClosure blobs_cl(oops, !CodeBlobToOopClosure::FixRelocations);
|
||||
strong_roots_do(worker_id, oops, &clds_cl, &blobs_cl);
|
||||
}
|
||||
|
||||
template <typename ITR>
|
||||
void ShenandoahRootScanner<ITR>::roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure *tc) {
|
||||
assert(!ShenandoahHeap::heap()->unload_classes() ||
|
||||
ShenandoahHeap::heap()->heuristics()->can_do_traversal_gc(),
|
||||
"No class unloading or traversal GC");
|
||||
ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
|
||||
ResourceMark rm;
|
||||
|
||||
_serial_roots.oops_do(oops, worker_id);
|
||||
_cld_roots.clds_do(clds, clds, worker_id);
|
||||
_thread_roots.threads_do(&tc_cl, worker_id);
|
||||
|
||||
// With ShenandoahConcurrentScanCodeRoots, we avoid scanning the entire code cache here,
|
||||
// and instead do that in concurrent phase under the relevant lock. This saves init mark
|
||||
// pause time.
|
||||
if (code != NULL && !ShenandoahConcurrentScanCodeRoots) {
|
||||
_code_roots.code_blobs_do(code, worker_id);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ITR>
|
||||
void ShenandoahRootScanner<ITR>::strong_roots_do(uint worker_id, OopClosure* oops, CLDClosure* clds, CodeBlobClosure* code, ThreadClosure* tc) {
|
||||
assert(ShenandoahHeap::heap()->unload_classes(), "Should be used during class unloading");
|
||||
ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
|
||||
ResourceMark rm;
|
||||
|
||||
_serial_roots.oops_do(oops, worker_id);
|
||||
_cld_roots.clds_do(clds, NULL, worker_id);
|
||||
_thread_roots.threads_do(&tc_cl, worker_id);
|
||||
}
|
||||
|
||||
template <typename IsAlive, typename KeepAlive>
|
||||
void ShenandoahRootUpdater::roots_do(uint worker_id, IsAlive* is_alive, KeepAlive* keep_alive) {
|
||||
CodeBlobToOopClosure update_blobs(keep_alive, CodeBlobToOopClosure::FixRelocations);
|
||||
|
@ -161,17 +161,16 @@ public:
|
||||
|
||||
class ShenandoahInitTraversalCollectionTask : public AbstractGangTask {
|
||||
private:
|
||||
ShenandoahRootScanner* _rp;
|
||||
ShenandoahCSetRootScanner* _rp;
|
||||
ShenandoahHeap* _heap;
|
||||
ShenandoahCsetCodeRootsIterator* _cset_coderoots;
|
||||
ShenandoahStringDedupRoots _dedup_roots;
|
||||
|
||||
public:
|
||||
ShenandoahInitTraversalCollectionTask(ShenandoahRootScanner* rp, ShenandoahCsetCodeRootsIterator* cset_coderoots) :
|
||||
ShenandoahInitTraversalCollectionTask(ShenandoahCSetRootScanner* rp) :
|
||||
AbstractGangTask("Shenandoah Init Traversal Collection"),
|
||||
_rp(rp),
|
||||
_heap(ShenandoahHeap::heap()),
|
||||
_cset_coderoots(cset_coderoots) {}
|
||||
_heap(ShenandoahHeap::heap()) {}
|
||||
|
||||
void work(uint worker_id) {
|
||||
ShenandoahParallelWorkerSession worker_session(worker_id);
|
||||
@ -231,11 +230,11 @@ public:
|
||||
|
||||
class ShenandoahFinalTraversalCollectionTask : public AbstractGangTask {
|
||||
private:
|
||||
ShenandoahRootScanner* _rp;
|
||||
ShenandoahAllRootScanner* _rp;
|
||||
ShenandoahTaskTerminator* _terminator;
|
||||
ShenandoahHeap* _heap;
|
||||
public:
|
||||
ShenandoahFinalTraversalCollectionTask(ShenandoahRootScanner* rp, ShenandoahTaskTerminator* terminator) :
|
||||
ShenandoahFinalTraversalCollectionTask(ShenandoahAllRootScanner* rp, ShenandoahTaskTerminator* terminator) :
|
||||
AbstractGangTask("Shenandoah Final Traversal Collection"),
|
||||
_rp(rp),
|
||||
_terminator(terminator),
|
||||
@ -415,11 +414,8 @@ void ShenandoahTraversalGC::init_traversal_collection() {
|
||||
{
|
||||
uint nworkers = _heap->workers()->active_workers();
|
||||
task_queues()->reserve(nworkers);
|
||||
ShenandoahRootScanner rp(nworkers, ShenandoahPhaseTimings::init_traversal_gc_work);
|
||||
|
||||
ShenandoahCsetCodeRootsIterator cset_coderoots = ShenandoahCodeRoots::cset_iterator();
|
||||
|
||||
ShenandoahInitTraversalCollectionTask traversal_task(&rp, &cset_coderoots);
|
||||
ShenandoahCSetRootScanner rp(nworkers, ShenandoahPhaseTimings::init_traversal_gc_work);
|
||||
ShenandoahInitTraversalCollectionTask traversal_task(&rp);
|
||||
_heap->workers()->run_task(&traversal_task);
|
||||
}
|
||||
|
||||
@ -588,7 +584,7 @@ void ShenandoahTraversalGC::final_traversal_collection() {
|
||||
task_queues()->reserve(nworkers);
|
||||
|
||||
// Finish traversal
|
||||
ShenandoahRootScanner rp(nworkers, ShenandoahPhaseTimings::final_traversal_gc_work);
|
||||
ShenandoahAllRootScanner rp(nworkers, ShenandoahPhaseTimings::final_traversal_gc_work);
|
||||
ShenandoahTerminationTracker term(ShenandoahPhaseTimings::final_traversal_gc_termination);
|
||||
|
||||
ShenandoahTaskTerminator terminator(nworkers, task_queues());
|
||||
|
Loading…
x
Reference in New Issue
Block a user