8224210: Shenandoah: Refactor ShenandoahRootScanner to support scanning CSet codecache roots
authorzgu
Mon, 20 May 2019 09:42:37 -0400
changeset 54940 2d90a0988c95
parent 54939 bafd6c944db4
child 54941 af28daff6b98
8224210: Shenandoah: Refactor ShenandoahRootScanner to support scanning CSet codecache roots Reviewed-by: shade
src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp
src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp
src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp
src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp
src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp
--- 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());