< prev index next >

src/hotspot/share/gc/g1/satbMarkQueue.cpp

Print this page

        

@@ -33,10 +33,14 @@
 #include "runtime/mutexLocker.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/thread.hpp"
 #include "runtime/threadSMR.hpp"
 #include "runtime/vmThread.hpp"
+#include "utilities/macros.hpp"
+#if INCLUDE_SHENANDOAHGC
+#include "gc/shenandoah/shenandoahHeap.inline.hpp"
+#endif
 
 SATBMarkQueue::SATBMarkQueue(SATBMarkQueueSet* qset, bool permanent) :
   // SATB queues are only active during marking cycles. We create
   // them with their active field set to false. If a thread is
   // created during a cycle and its SATB queue needs to be activated

@@ -84,38 +88,35 @@
 // The stale reference cases are implicitly handled by the NTAMS
 // comparison. Because of the possibility of stale references, buffer
 // processing must be somewhat circumspect and not assume entries
 // in an unfiltered buffer refer to valid objects.
 
-inline bool requires_marking(const void* entry, G1CollectedHeap* heap) {
-  // Includes rejection of NULL pointers.
-  assert(heap->is_in_reserved(entry),
-         "Non-heap pointer in SATB buffer: " PTR_FORMAT, p2i(entry));
-
-  HeapRegion* region = heap->heap_region_containing(entry);
-  assert(region != NULL, "No region for " PTR_FORMAT, p2i(entry));
-  if (entry >= region->next_top_at_mark_start()) {
-    return false;
-  }
-
-  assert(oopDesc::is_oop(oop(entry), true /* ignore mark word */),
-         "Invalid oop in SATB buffer: " PTR_FORMAT, p2i(entry));
-
-  return true;
+template <class HeapType>
+inline bool retain_entry(const void* entry, HeapType* heap) {
+  return heap->requires_marking(entry);
 }
 
-inline bool retain_entry(const void* entry, G1CollectedHeap* heap) {
-  return requires_marking(entry, heap) && !heap->is_marked_next((oop)entry);
+void SATBMarkQueue::filter() {
+  if (UseG1GC) {
+    filter_impl<G1CollectedHeap>();
+#if INCLUDE_SHENANDOAHGC
+  } else if (UseShenandoahGC) {
+    filter_impl<ShenandoahHeap>();
+#endif
+  } else {
+    ShouldNotReachHere();
+  }
 }
 
 // This method removes entries from a SATB buffer that will not be
 // useful to the concurrent marking threads.  Entries are retained if
 // they require marking and are not already marked. Retained entries
 // are compacted toward the top of the buffer.
 
-void SATBMarkQueue::filter() {
-  G1CollectedHeap* g1h = G1CollectedHeap::heap();
+template <class HeapType>
+void SATBMarkQueue::filter_impl() {
+  HeapType* heap = (HeapType*) Universe::heap();
   void** buf = _buf;
 
   if (buf == NULL) {
     // nothing to do
     return;

@@ -126,14 +127,14 @@
   void** dst = &buf[capacity()];
   assert(src <= dst, "invariant");
   for ( ; src < dst; ++src) {
     // Search low to high for an entry to keep.
     void* entry = *src;
-    if (retain_entry(entry, g1h)) {
+    if (retain_entry(entry, heap)) {
       // Found keeper.  Search high to low for an entry to discard.
       while (src < --dst) {
-        if (!retain_entry(*dst, g1h)) {
+        if (!retain_entry(*dst, heap)) {
           *dst = entry;         // Replace discard with keeper.
           break;
         }
       }
       // If discard search failed (src == dst), the outer loop will also end.

@@ -163,12 +164,11 @@
 
   filter();
 
   size_t cap = capacity();
   size_t percent_used = ((cap - index()) * 100) / cap;
-  bool should_enqueue = percent_used > G1SATBBufferEnqueueingThresholdPercent;
-  return should_enqueue;
+  return percent_used > G1SATBBufferEnqueueingThresholdPercent;
 }
 
 void SATBMarkQueue::apply_closure_and_empty(SATBBufferClosure* cl) {
   assert(SafepointSynchronize::is_at_safepoint(),
          "SATB queues must only be processed at safepoints");

@@ -205,21 +205,17 @@
                                   Mutex* lock) {
   PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold, -1);
   _shared_satb_queue.set_lock(lock);
 }
 
-void SATBMarkQueueSet::handle_zero_index_for_thread(JavaThread* t) {
-  G1ThreadLocalData::satb_mark_queue(t).handle_zero_index();
-}
-
 #ifdef ASSERT
 void SATBMarkQueueSet::dump_active_states(bool expected_active) {
   log_error(gc, verify)("Expected SATB active state: %s", expected_active ? "ACTIVE" : "INACTIVE");
   log_error(gc, verify)("Actual SATB active states:");
   log_error(gc, verify)("  Queue set: %s", is_active() ? "ACTIVE" : "INACTIVE");
   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
-    log_error(gc, verify)("  Thread \"%s\" queue: %s", t->name(), G1ThreadLocalData::satb_mark_queue(t).is_active() ? "ACTIVE" : "INACTIVE");
+    log_error(gc, verify)("  Thread \"%s\" queue: %s", t->name(), satb_queue_for_thread(t).is_active() ? "ACTIVE" : "INACTIVE");
   }
   log_error(gc, verify)("  Shared queue: %s", shared_satb_queue()->is_active() ? "ACTIVE" : "INACTIVE");
 }
 
 void SATBMarkQueueSet::verify_active_states(bool expected_active) {

@@ -229,11 +225,11 @@
     guarantee(false, "SATB queue set has an unexpected active state");
   }
 
   // Verify thread queue states
   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
-    if (G1ThreadLocalData::satb_mark_queue(t).is_active() != expected_active) {
+    if (satb_queue_for_thread(t).is_active() != expected_active) {
       dump_active_states(expected_active);
       guarantee(false, "Thread SATB queue has an unexpected active state");
     }
   }
 

@@ -250,18 +246,18 @@
 #ifdef ASSERT
   verify_active_states(expected_active);
 #endif // ASSERT
   _all_active = active;
   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
-    G1ThreadLocalData::satb_mark_queue(t).set_active(active);
+    satb_queue_for_thread(t).set_active(active);
   }
   shared_satb_queue()->set_active(active);
 }
 
 void SATBMarkQueueSet::filter_thread_buffers() {
   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
-    G1ThreadLocalData::satb_mark_queue(t).filter();
+    satb_queue_for_thread(t).filter();
   }
   shared_satb_queue()->filter();
 }
 
 bool SATBMarkQueueSet::apply_closure_to_completed_buffer(SATBBufferClosure* cl) {

@@ -311,11 +307,11 @@
     i += 1;
   }
 
   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
     jio_snprintf(buffer, SATB_PRINTER_BUFFER_SIZE, "Thread: %s", t->name());
-    G1ThreadLocalData::satb_mark_queue(t).print(buffer);
+    satb_queue_for_thread(t).print(buffer);
   }
 
   shared_satb_queue()->print("Shared");
 
   tty->cr();

@@ -342,9 +338,18 @@
     deallocate_buffer(nd);
   }
   assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
   // So we can safely manipulate these queues.
   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
-    G1ThreadLocalData::satb_mark_queue(t).reset();
+    satb_queue_for_thread(t).reset();
   }
   shared_satb_queue()->reset();
 }
+
+void G1SATBMarkQueueSet::handle_zero_index_for_thread(JavaThread* t) {
+  G1ThreadLocalData::satb_mark_queue(t).handle_zero_index();
+}
+
+SATBMarkQueue& G1SATBMarkQueueSet::satb_queue_for_thread(Thread* t) {
+  return G1ThreadLocalData::satb_mark_queue(t);
+}
+
< prev index next >