< prev index next >

src/share/vm/gc_implementation/shenandoah/shenandoahCodeRoots.hpp

Print this page
rev 10509 : [backport] Refactor and improve ShenandoahCodeRoots strategies
rev 10619 : [backport] Move ParallelCodeIterator to ShenandoahCodeRoots
rev 10630 : [backport] Unreachable assert in ShenandoahCodeRoots::acquire_lock

@@ -32,15 +32,53 @@
 
 class ShenandoahHeap;
 class ShenandoahHeapRegion;
 class ShenandoahCodeRootsLock;
 
+class ShenandoahParallelCodeCacheIterator VALUE_OBJ_CLASS_SPEC {
+  friend class CodeCache;
+private:
+  volatile int  _claimed_idx;
+  volatile bool _finished;
+public:
+  ShenandoahParallelCodeCacheIterator();
+  void parallel_blobs_do(CodeBlobClosure* f);
+};
+
+// ShenandoahNMethod tuple records the internal locations of oop slots within the nmethod.
+// This allows us to quickly scan the oops without doing the nmethod-internal scans, that
+// sometimes involves parsing the machine code. Note it does not record the oops themselves,
+// because it would then require handling these tuples as the new class of roots.
+class ShenandoahNMethod : public CHeapObj<mtGC> {
+private:
+  nmethod* _nm;
+  oop**    _oops;
+  int      _oops_count;
+
+public:
+  ShenandoahNMethod(nmethod *nm, GrowableArray<oop*>* oops);
+  ~ShenandoahNMethod();
+
+  nmethod* nm() {
+    return _nm;
+  }
+
+  bool has_cset_oops(ShenandoahHeap* heap);
+
+  void assert_alive_and_correct() PRODUCT_RETURN;
+  void assert_same_oops(GrowableArray<oop*>* oops) PRODUCT_RETURN;
+
+  static bool find_with_nmethod(void* nm, ShenandoahNMethod* other) {
+    return other->_nm == nm;
+  }
+};
+
 class ShenandoahCodeRootsIterator VALUE_OBJ_CLASS_SPEC {
   friend class ShenandoahCodeRoots;
 protected:
   ShenandoahHeap* _heap;
-  ParallelCodeCacheIterator _par_iterator;
+  ShenandoahParallelCodeCacheIterator _par_iterator;
   ShenandoahSharedFlag _seq_claimed;
   volatile jlong _claimed;
 protected:
   ShenandoahCodeRootsIterator();
   ~ShenandoahCodeRootsIterator();

@@ -85,18 +123,15 @@
    * @return
    */
   static ShenandoahCsetCodeRootsIterator cset_iterator();
 
 private:
-  static volatile jint _recorded_nmethods_lock;
-  static GrowableArray<nmethod*>* _recorded_nmethods;
-
-  static void fast_add_nmethod(nmethod* nm);
-  static void fast_remove_nmethod(nmethod* nm);
+  static volatile jint _recorded_nms_lock;
+  static GrowableArray<ShenandoahNMethod*>* _recorded_nms;
 
   static void acquire_lock(bool write) {
-    volatile jint* loc = &_recorded_nmethods_lock;
+    volatile jint* loc = &_recorded_nms_lock;
     if (write) {
       while ((OrderAccess::load_acquire(loc) != 0) ||
              Atomic::cmpxchg(-1, loc, 0) != 0) {
         SpinPause();
       }

@@ -105,21 +140,21 @@
       while (true) {
         jint cur = OrderAccess::load_acquire(loc);
         if (cur >= 0) {
           if (Atomic::cmpxchg(cur + 1, loc, cur) == cur) {
             // Success!
+            assert (*loc > 0, "acquired for read");
             return;
           }
         }
         SpinPause();
       }
-      assert (*loc > 1, "acquired for read");
     }
   }
 
   static void release_lock(bool write) {
-    volatile jint* loc = &ShenandoahCodeRoots::_recorded_nmethods_lock;
+    volatile jint* loc = &ShenandoahCodeRoots::_recorded_nms_lock;
     if (write) {
       OrderAccess::release_store_fence(loc, 0);
     } else {
       Atomic::dec(loc);
     }
< prev index next >