8226310: Shenandoah: Concurrent evacuation of CLDG
authorzgu
Mon, 24 Jun 2019 14:13:49 -0400
changeset 55477 c396e381cfa4
parent 55476 aee0d296c0ef
child 55478 ae2e53e379cb
8226310: Shenandoah: Concurrent evacuation of CLDG Reviewed-by: rkennke
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
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Mon Jun 24 11:46:46 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Mon Jun 24 14:13:49 2019 -0400
@@ -1524,6 +1524,7 @@
       if (ShenandoahVerify) {
         if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) {
           ShenandoahRootVerifier::RootTypes types = ShenandoahRootVerifier::combine(ShenandoahRootVerifier::JNIHandleRoots, ShenandoahRootVerifier::WeakRoots);
+          types = ShenandoahRootVerifier::combine(types, ShenandoahRootVerifier::CLDGRoots);
           verifier()->verify_roots_no_forwarded_except(types);
         } else {
           verifier()->verify_roots_no_forwarded();
@@ -1592,6 +1593,7 @@
 private:
   ShenandoahJNIHandleRoots<true /*concurrent*/> _jni_roots;
   ShenandoahWeakRoots<true /*concurrent*/>      _weak_roots;
+  ShenandoahClassLoaderDataRoots<true /*concurrent*/, false /*single threaded*/> _cld_roots;
 
 public:
   ShenandoahConcurrentRootsEvacUpdateTask() :
@@ -1601,8 +1603,10 @@
   void work(uint worker_id) {
     ShenandoahEvacOOMScope oom;
     ShenandoahEvacuateUpdateRootsClosure cl;
+    CLDToOopClosure clds(&cl, ClassLoaderData::_claim_strong);
 
     _jni_roots.oops_do<ShenandoahEvacuateUpdateRootsClosure>(&cl);
+    _cld_roots.cld_do(&clds);
     _weak_roots.oops_do<ShenandoahEvacuateUpdateRootsClosure>(&cl);
   }
 };
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp	Mon Jun 24 11:46:46 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp	Mon Jun 24 14:13:49 2019 -0400
@@ -162,18 +162,18 @@
 
 void ShenandoahRootEvacuator::roots_do(uint worker_id, OopClosure* oops) {
   MarkingCodeBlobClosure blobsCl(oops, CodeBlobToOopClosure::FixRelocations);
-  CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
   AlwaysTrueClosure always_true;
 
   _serial_roots.oops_do(oops, worker_id);
   _serial_weak_roots.weak_oops_do(oops, worker_id);
   if (_include_concurrent_roots) {
+    CLDToOopClosure clds(oops, ClassLoaderData::_claim_strong);
     _jni_roots.oops_do<OopClosure>(oops, worker_id);
+    _cld_roots.cld_do(&clds, worker_id);
     _weak_roots.oops_do<OopClosure>(oops, worker_id);
   }
 
   _thread_roots.oops_do(oops, NULL, worker_id);
-  _cld_roots.cld_do(&clds, worker_id);
   _code_roots.code_blobs_do(&blobsCl, worker_id);
 
   _dedup_roots.oops_do(&always_true, oops, worker_id);
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp	Mon Jun 24 11:46:46 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp	Mon Jun 24 14:13:49 2019 -0400
@@ -190,13 +190,14 @@
   void code_blobs_do(CodeBlobClosure* blob_cl, uint worker_id);
 };
 
-template <bool SINGLE_THREADED>
+template <bool CONCURRENT, bool SINGLE_THREADED>
 class ShenandoahClassLoaderDataRoots {
 public:
   ShenandoahClassLoaderDataRoots();
+  ~ShenandoahClassLoaderDataRoots();
 
-  void always_strong_cld_do(CLDClosure* clds, uint worker_id);
-  void cld_do(CLDClosure* clds, uint worker_id);
+  void always_strong_cld_do(CLDClosure* clds, uint worker_id = 0);
+  void cld_do(CLDClosure* clds, uint worker_id = 0);
 };
 
 class ShenandoahRootProcessor : public StackObj {
@@ -217,7 +218,8 @@
   ShenandoahThreadRoots                                     _thread_roots;
   ShenandoahCodeCacheRoots<ITR>                             _code_roots;
   ShenandoahJNIHandleRoots<false /*concurrent*/ >           _jni_roots;
-  ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots;
+  ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
+                                                            _cld_roots;
 public:
   ShenandoahRootScanner(uint n_workers, ShenandoahPhaseTimings::Phase phase);
 
@@ -242,7 +244,8 @@
   ShenandoahSerialRoots                                    _serial_roots;
   ShenandoahThreadRoots                                    _thread_roots;
   ShenandoahJNIHandleRoots<false /*concurrent*/>           _jni_roots;
-  ShenandoahClassLoaderDataRoots<true /*single threaded*/> _cld_roots;
+  ShenandoahClassLoaderDataRoots<false /*concurrent*/, true /*single threaded*/>
+                                                           _cld_roots;
   ShenandoahCodeCacheRoots<ShenandoahAllCodeRootsIterator> _code_roots;
 
 public:
@@ -257,7 +260,8 @@
 private:
   ShenandoahSerialRoots                                     _serial_roots;
   ShenandoahJNIHandleRoots<false /*concurrent*/>            _jni_roots;
-  ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots;
+  ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
+                                                            _cld_roots;
   ShenandoahThreadRoots                                     _thread_roots;
   ShenandoahSerialWeakRoots                                 _serial_weak_roots;
   ShenandoahWeakRoots<false /*concurrent*/>                 _weak_roots;
@@ -276,7 +280,8 @@
 private:
   ShenandoahSerialRoots                                     _serial_roots;
   ShenandoahJNIHandleRoots<false /*concurrent*/>            _jni_roots;
-  ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots;
+  ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
+                                                            _cld_roots;
   ShenandoahThreadRoots                                     _thread_roots;
   ShenandoahSerialWeakRoots                                 _serial_weak_roots;
   ShenandoahWeakRoots<false /*concurrent*/>                 _weak_roots;
@@ -296,7 +301,8 @@
 private:
   ShenandoahSerialRoots                                     _serial_roots;
   ShenandoahJNIHandleRoots<false /*concurrent*/>            _jni_roots;
-  ShenandoahClassLoaderDataRoots<false /*single threaded*/> _cld_roots;
+  ShenandoahClassLoaderDataRoots<false /*concurrent*/, false /*single threaded*/>
+                                                            _cld_roots;
   ShenandoahThreadRoots                                     _thread_roots;
   ShenandoahSerialWeakRoots                                 _serial_weak_roots;
   ShenandoahWeakRoots<false /*concurrent*/>                 _weak_roots;
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp	Mon Jun 24 11:46:46 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp	Mon Jun 24 14:13:49 2019 -0400
@@ -119,19 +119,32 @@
   }
 }
 
-template <bool SINGLE_THREADED>
-ShenandoahClassLoaderDataRoots<SINGLE_THREADED>::ShenandoahClassLoaderDataRoots() {
+template <bool CONCURRENT, bool SINGLE_THREADED>
+ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::ShenandoahClassLoaderDataRoots() {
   if (!SINGLE_THREADED) {
     ClassLoaderDataGraph::clear_claimed_marks();
   }
+  if (CONCURRENT) {
+    ClassLoaderDataGraph_lock->lock();
+  }
 }
 
-template <bool SINGLE_THREADED>
-void ShenandoahClassLoaderDataRoots<SINGLE_THREADED>::always_strong_cld_do(CLDClosure* clds, uint worker_id) {
+template <bool CONCURRENT, bool SINGLE_THREADED>
+ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::~ShenandoahClassLoaderDataRoots() {
+  if (CONCURRENT) {
+    ClassLoaderDataGraph_lock->unlock();
+  }
+}
+
+
+template <bool CONCURRENT, bool SINGLE_THREADED>
+void ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::always_strong_cld_do(CLDClosure* clds, uint worker_id) {
   if (SINGLE_THREADED) {
     assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
     assert(Thread::current()->is_VM_thread(), "Single threaded CLDG iteration can only be done by VM thread");
     ClassLoaderDataGraph::always_strong_cld_do(clds);
+  } else if (CONCURRENT) {
+     ClassLoaderDataGraph::always_strong_cld_do(clds);
   } else {
    ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id);
@@ -139,13 +152,15 @@
   }
 }
 
-template <bool SINGLE_THREADED>
-void ShenandoahClassLoaderDataRoots<SINGLE_THREADED>::cld_do(CLDClosure* clds, uint worker_id) {
+template <bool CONCURRENT, bool SINGLE_THREADED>
+void ShenandoahClassLoaderDataRoots<CONCURRENT, SINGLE_THREADED>::cld_do(CLDClosure* clds, uint worker_id) {
   if (SINGLE_THREADED) {
     assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
     assert(Thread::current()->is_VM_thread(), "Single threaded CLDG iteration can only be done by VM thread");
     ClassLoaderDataGraph::cld_do(clds);
-  } else {
+  } else if (CONCURRENT) {
+    ClassLoaderDataGraph::cld_do(clds);
+  }  else {
     ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CLDGRoots, worker_id);
     ClassLoaderDataGraph::cld_do(clds);