src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp

Print this page
rev 5363 : imported patch filtering.diff
rev 5365 : [mq]: invalidate-fix

@@ -68,10 +68,16 @@
   jbyte val = _byte_map[card_index];
   // It's already processed
   if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) {
     return false;
   }
+
+  if  (val == g1_young_gen) {
+    // the card is for a young gen region. We don't need to keep track of all pointers into young
+    return false;
+  }
+
   // Cached bit can be installed either on a clean card or on a claimed card.
   jbyte new_val = val;
   if (val == clean_card_val()) {
     new_val = (jbyte)deferred_card_val();
   } else {

@@ -83,10 +89,23 @@
     Atomic::cmpxchg(new_val, &_byte_map[card_index], val);
   }
   return true;
 }
 
+void G1SATBCardTableModRefBS::g1_mark_as_young(const MemRegion& mr) {
+  jbyte *const first = byte_for(mr.start());
+  jbyte *const last = byte_after(mr.last());
+
+  memset(first, g1_young_gen, last - first);
+}
+
+#ifndef PRODUCT
+void G1SATBCardTableModRefBS::verify_g1_young_region(MemRegion mr) {
+  verify_region(mr, g1_young_gen,  true);
+}
+#endif
+
 G1SATBCardTableLoggingModRefBS::
 G1SATBCardTableLoggingModRefBS(MemRegion whole_heap,
                                int max_covered_regions) :
   G1SATBCardTableModRefBS(whole_heap, max_covered_regions),
   _dcqs(JavaThread::dirty_card_queue_set())

@@ -95,11 +114,15 @@
 }
 
 void
 G1SATBCardTableLoggingModRefBS::write_ref_field_work(void* field,
                                                      oop new_val) {
-  jbyte* byte = byte_for(field);
+  volatile jbyte* byte = byte_for(field);
+  if (*byte == g1_young_gen) {
+    return;
+  }
+  OrderAccess::storeload();
   if (*byte != dirty_card) {
     *byte = dirty_card;
     Thread* thr = Thread::current();
     if (thr->is_Java_thread()) {
       JavaThread* jt = (JavaThread*)thr;

@@ -127,37 +150,47 @@
   g1_bs->write_ref_field_work(field, new_val);
 }
 
 void
 G1SATBCardTableLoggingModRefBS::invalidate(MemRegion mr, bool whole_heap) {
-  jbyte* byte = byte_for(mr.start());
+  volatile jbyte* byte = byte_for(mr.start());
   jbyte* last_byte = byte_for(mr.last());
   Thread* thr = Thread::current();
   if (whole_heap) {
     while (byte <= last_byte) {
       *byte = dirty_card;
       byte++;
     }
   } else {
+    // skip all consecutive young cards
+    for (; byte <= last_byte && *byte == g1_young_gen; byte++);
+
+    if (byte <= last_byte) {
+      OrderAccess::storeload();
     // Enqueue if necessary.
     if (thr->is_Java_thread()) {
       JavaThread* jt = (JavaThread*)thr;
-      while (byte <= last_byte) {
+        for (; byte <= last_byte; byte++) {
+          if (*byte == g1_young_gen) {
+            continue;
+          }
         if (*byte != dirty_card) {
           *byte = dirty_card;
           jt->dirty_card_queue().enqueue(byte);
         }
-        byte++;
       }
     } else {
       MutexLockerEx x(Shared_DirtyCardQ_lock,
                       Mutex::_no_safepoint_check_flag);
-      while (byte <= last_byte) {
+        for (; byte <= last_byte; byte++) {
+          if (*byte == g1_young_gen) {
+            continue;
+          }
         if (*byte != dirty_card) {
           *byte = dirty_card;
           _dcqs.shared_dirty_card_queue()->enqueue(byte);
         }
-        byte++;
+        }
       }
     }
   }
 }