< prev index next >

src/share/vm/gc/shenandoah/shenandoahConcurrentMark.cpp

Print this page
rev 13055 : Implement barriers for maintaining connection matrix.

@@ -48,11 +48,11 @@
   SCMObjToScanQueue* _queue;
   ShenandoahHeap* _heap;
 
   template <class T>
   inline void do_oop_nv(T* p) {
-    ShenandoahConcurrentMark::mark_through_ref<T, RESOLVE>(p, _heap, _queue);
+    ShenandoahConcurrentMark::mark_through_ref<T, RESOLVE, false>(p, _heap, _queue, NULL);
   }
 
 public:
   ShenandoahInitMarkRootsClosure(SCMObjToScanQueue* q) :
     _queue(q), _heap(ShenandoahHeap::heap()) {};

@@ -62,11 +62,12 @@
 };
 
 ShenandoahMarkRefsSuperClosure::ShenandoahMarkRefsSuperClosure(SCMObjToScanQueue* q, ReferenceProcessor* rp) :
   MetadataAwareOopClosure(rp),
   _queue(q),
-  _heap((ShenandoahHeap*) Universe::heap())
+  _heap(ShenandoahHeap::heap()),
+  _conn_matrix(ShenandoahHeap::heap()->connection_matrix())
 {
 }
 
 class ShenandoahInitMarkRootsTask : public AbstractGangTask {
 private:

@@ -187,11 +188,12 @@
     _cm->mark_loop(worker_id, _terminator, rp,
                    true, // cancellable
                    true, // drain SATBs as we go
                    true, // count liveness
                    _cm->unload_classes(),
-                   _update_refs);
+                   _update_refs,
+                   UseShenandoahMatrix);
   }
 };
 
 class SCMFinalMarkingTask : public AbstractGangTask {
 private:

@@ -224,11 +226,12 @@
     _cm->mark_loop(worker_id, _terminator, rp,
                    false, // not cancellable
                    false, // do not drain SATBs, already drained
                    _count_live,
                    _unload_classes,
-                   _update_refs);
+                   _update_refs,
+                   UseShenandoahMatrix);
 
     assert(_cm->task_queues()->is_empty(), "Should be empty");
   }
 };
 

@@ -612,11 +615,12 @@
     scm->mark_loop(_worker_id, _terminator, rp,
                    false, // not cancellable
                    false, // do not drain SATBs
                    true,  // count liveness
                    scm->unload_classes(),
-                   sh->need_update_refs());
+                   sh->need_update_refs(),
+                   UseShenandoahMatrix);
   }
 };
 
 
 class ShenandoahCMKeepAliveClosure : public OopClosure {

@@ -624,16 +628,16 @@
   SCMObjToScanQueue* _queue;
   ShenandoahHeap* _heap;
 
   template <class T>
   inline void do_oop_nv(T* p) {
-    ShenandoahConcurrentMark::mark_through_ref<T, NONE>(p, _heap, _queue);
+    ShenandoahConcurrentMark::mark_through_ref<T, NONE, false>(p, _heap, _queue, NULL);
   }
 
 public:
   ShenandoahCMKeepAliveClosure(SCMObjToScanQueue* q) :
-    _queue(q), _heap(ShenandoahHeap::heap()) {};
+    _queue(q), _heap(ShenandoahHeap::heap()) {}
 
   void do_oop(narrowOop* p) { do_oop_nv(p); }
   void do_oop(oop* p)       { do_oop_nv(p); }
 };
 

@@ -642,16 +646,56 @@
   SCMObjToScanQueue* _queue;
   ShenandoahHeap* _heap;
 
   template <class T>
   inline void do_oop_nv(T* p) {
-    ShenandoahConcurrentMark::mark_through_ref<T, SIMPLE>(p, _heap, _queue);
+    ShenandoahConcurrentMark::mark_through_ref<T, SIMPLE, false>(p, _heap, _queue, NULL);
   }
 
 public:
   ShenandoahCMKeepAliveUpdateClosure(SCMObjToScanQueue* q) :
-    _queue(q), _heap(ShenandoahHeap::heap()) {};
+    _queue(q), _heap(ShenandoahHeap::heap()) {}
+
+  void do_oop(narrowOop* p) { do_oop_nv(p); }
+  void do_oop(oop* p)       { do_oop_nv(p); }
+};
+
+class ShenandoahCMKeepAliveMatrixClosure : public OopClosure {
+private:
+  SCMObjToScanQueue* _queue;
+  ShenandoahHeap* _heap;
+  ShenandoahConnectionMatrix* _conn_matrix;
+
+  template <class T>
+  inline void do_oop_nv(T* p) {
+    ShenandoahConcurrentMark::mark_through_ref<T, NONE, true>(p, _heap, _queue, _conn_matrix);
+  }
+
+public:
+  ShenandoahCMKeepAliveMatrixClosure(SCMObjToScanQueue* q) :
+    _queue(q), _heap(ShenandoahHeap::heap()),
+    _conn_matrix(ShenandoahHeap::heap()->connection_matrix()) {};
+
+  void do_oop(narrowOop* p) { do_oop_nv(p); }
+  void do_oop(oop* p)       { do_oop_nv(p); }
+};
+
+class ShenandoahCMKeepAliveUpdateMatrixClosure : public OopClosure {
+private:
+  SCMObjToScanQueue* _queue;
+  ShenandoahHeap* _heap;
+  ShenandoahConnectionMatrix* _conn_matrix;
+
+  template <class T>
+  inline void do_oop_nv(T* p) {
+    ShenandoahConcurrentMark::mark_through_ref<T, SIMPLE, true>(p, _heap, _queue, _conn_matrix);
+  }
+
+public:
+  ShenandoahCMKeepAliveUpdateMatrixClosure(SCMObjToScanQueue* q) :
+    _queue(q), _heap(ShenandoahHeap::heap()),
+    _conn_matrix(ShenandoahHeap::heap()->connection_matrix()) {};
 
   void do_oop(narrowOop* p) { do_oop_nv(p); }
   void do_oop(oop* p)       { do_oop_nv(p); }
 };
 

@@ -672,18 +716,28 @@
   void work(uint worker_id) {
     assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
     ShenandoahHeap* heap = ShenandoahHeap::heap();
     ShenandoahForwardedIsAliveClosure is_alive;
     ShenandoahCMDrainMarkingStackClosure complete_gc(worker_id, _terminator);
+    if (UseShenandoahMatrix) {
+      if (heap->need_update_refs()) {
+        ShenandoahCMKeepAliveUpdateMatrixClosure keep_alive(heap->concurrentMark()->get_queue(worker_id));
+        _proc_task.work(worker_id, is_alive, keep_alive, complete_gc);
+      } else {
+        ShenandoahCMKeepAliveMatrixClosure keep_alive(heap->concurrentMark()->get_queue(worker_id));
+        _proc_task.work(worker_id, is_alive, keep_alive, complete_gc);
+      }
+    } else {
     if (heap->need_update_refs()) {
       ShenandoahCMKeepAliveUpdateClosure keep_alive(heap->concurrentMark()->get_queue(worker_id));
       _proc_task.work(worker_id, is_alive, keep_alive, complete_gc);
     } else {
       ShenandoahCMKeepAliveClosure keep_alive(heap->concurrentMark()->get_queue(worker_id));
       _proc_task.work(worker_id, is_alive, keep_alive, complete_gc);
     }
   }
+  }
 };
 
 class ShenandoahRefEnqueueTaskProxy : public AbstractGangTask {
 
 private:

@@ -814,11 +868,11 @@
   q->set_empty();
   q->overflow_stack()->clear();
   q->clear_buffer();
 }
 
-template <bool CANCELLABLE, bool DRAIN_SATB, bool COUNT_LIVENESS, bool CLASS_UNLOAD, bool UPDATE_REFS>
+template <bool CANCELLABLE, bool DRAIN_SATB, bool COUNT_LIVENESS, bool CLASS_UNLOAD, bool UPDATE_REFS, bool UPDATE_MATRIX>
 void ShenandoahConcurrentMark::mark_loop_prework(uint w, ParallelTaskTerminator *t, ReferenceProcessor *rp) {
   SCMObjToScanQueue* q = get_queue(w);
 
   jushort* ld;
   if (COUNT_LIVENESS) {

@@ -828,10 +882,29 @@
     ld = NULL;
   }
 
   // TODO: We can clean up this if we figure out how to do templated oop closures that
   // play nice with specialized_oop_iterators.
+  if (UPDATE_MATRIX) {
+    if (CLASS_UNLOAD) {
+      if (UPDATE_REFS) {
+        ShenandoahMarkUpdateRefsMetadataMatrixClosure cl(q, rp);
+        mark_loop_work<ShenandoahMarkUpdateRefsMetadataMatrixClosure, CANCELLABLE, DRAIN_SATB, COUNT_LIVENESS>(&cl, ld, w, t);
+      } else {
+        ShenandoahMarkRefsMetadataMatrixClosure cl(q, rp);
+        mark_loop_work<ShenandoahMarkRefsMetadataMatrixClosure, CANCELLABLE, DRAIN_SATB, COUNT_LIVENESS>(&cl, ld, w, t);
+      }
+    } else {
+      if (UPDATE_REFS) {
+        ShenandoahMarkUpdateRefsMatrixClosure cl(q, rp);
+        mark_loop_work<ShenandoahMarkUpdateRefsMatrixClosure, CANCELLABLE, DRAIN_SATB, COUNT_LIVENESS>(&cl, ld, w, t);
+      } else {
+        ShenandoahMarkRefsMatrixClosure cl(q, rp);
+        mark_loop_work<ShenandoahMarkRefsMatrixClosure, CANCELLABLE, DRAIN_SATB, COUNT_LIVENESS>(&cl, ld, w, t);
+      }
+    }
+  } else {
   if (CLASS_UNLOAD) {
     if (UPDATE_REFS) {
       ShenandoahMarkUpdateRefsMetadataClosure cl(q, rp);
       mark_loop_work<ShenandoahMarkUpdateRefsMetadataClosure, CANCELLABLE, DRAIN_SATB, COUNT_LIVENESS>(&cl, ld, w, t);
     } else {

@@ -845,11 +918,11 @@
     } else {
       ShenandoahMarkRefsClosure cl(q, rp);
       mark_loop_work<ShenandoahMarkRefsClosure, CANCELLABLE, DRAIN_SATB, COUNT_LIVENESS>(&cl, ld, w, t);
     }
   }
-
+  }
   if (COUNT_LIVENESS) {
     for (uint i = 0; i < _heap->max_regions(); i++) {
       ShenandoahHeapRegion *r = _heap->regions()->get(i);
       if (r != NULL) {
         jushort live = ld[i];
< prev index next >