8224210: Shenandoah: Refactor ShenandoahRootScanner to support scanning CSet codecache roots
Reviewed-by: shade
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp Thu May 16 12:14:37 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp Mon May 20 09:42:37 2019 -0400
@@ -81,10 +81,10 @@
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 @@
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);
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Thu May 16 12:14:37 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Mon May 20 09:42:37 2019 -0400
@@ -1326,7 +1326,7 @@
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);
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp Thu May 16 12:14:37 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp Mon May 20 09:42:37 2019 -0400
@@ -135,23 +135,6 @@
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 @@
_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),
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp Thu May 16 12:14:37 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp Mon May 20 09:42:37 2019 -0400
@@ -122,12 +122,13 @@
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 @@
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:
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp Thu May 16 12:14:37 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp Mon May 20 09:42:37 2019 -0400
@@ -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 @@
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);
--- a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp Thu May 16 12:14:37 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp Mon May 20 09:42:37 2019 -0400
@@ -161,17 +161,16 @@
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 @@
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 @@
{
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 @@
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());