hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp
changeset 20403 45a89fbcd8f7
parent 20309 7445302daff6
child 20408 ca559663042f
--- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp	Fri Oct 04 13:33:02 2013 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp	Tue Oct 08 17:35:51 2013 +0200
@@ -70,6 +70,12 @@
   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()) {
@@ -85,6 +91,19 @@
   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) :
@@ -97,7 +116,11 @@
 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();
@@ -129,7 +152,7 @@
 
 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) {
@@ -138,25 +161,35 @@
       byte++;
     }
   } else {
-    // Enqueue if necessary.
-    if (thr->is_Java_thread()) {
-      JavaThread* jt = (JavaThread*)thr;
-      while (byte <= last_byte) {
-        if (*byte != dirty_card) {
-          *byte = dirty_card;
-          jt->dirty_card_queue().enqueue(byte);
+    // 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;
+        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) {
-        if (*byte != dirty_card) {
-          *byte = dirty_card;
-          _dcqs.shared_dirty_card_queue()->enqueue(byte);
+      } else {
+        MutexLockerEx x(Shared_DirtyCardQ_lock,
+                        Mutex::_no_safepoint_check_flag);
+        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++;
       }
     }
   }