src/share/vm/memory/cardTableRS.cpp

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -171,10 +171,14 @@
     assert(!_is_par ||
            (SharedHeap::heap()->n_par_threads() ==
             SharedHeap::heap()->workers()->active_workers()), "Mismatch");
 }
 
+bool ClearNoncleanCardWrapper::is_word_aligned(jbyte* entry) {
+  return (((intptr_t)entry) & (BytesPerWord-1)) == 0;
+}
+
 void ClearNoncleanCardWrapper::do_MemRegion(MemRegion mr) {
   assert(mr.word_size() > 0, "Error");
   assert(_ct->is_aligned(mr.start()), "mr.start() should be card aligned");
   // mr.end() may not necessarily be card aligned.
   jbyte* cur_entry = _ct->byte_for(mr.last());

@@ -185,29 +189,49 @@
     HeapWord* cur_hw = _ct->addr_for(cur_entry);
     if ((*cur_entry != CardTableRS::clean_card_val()) && clear_card(cur_entry)) {
       // Continue the dirty range by opening the
       // dirty window one card to the left.
       start_of_non_clean = cur_hw;
+
+      cur_entry--;
     } else {
       // We hit a "clean" card; process any non-empty
       // "dirty" range accumulated so far.
       if (start_of_non_clean < end_of_non_clean) {
         const MemRegion mrd(start_of_non_clean, end_of_non_clean);
         _dirty_card_closure->do_MemRegion(mrd);
       }
+
+      // fast forward through potential continuous range of clean cards
+      if (is_word_aligned(cur_entry)) {
+        jbyte* cur_row = cur_entry - BytesPerWord;
+        while(cur_row >= limit) {
+          if (*((intptr_t*)cur_row) ==  CardTableRS::clean_card_row()) {
+                cur_row -= BytesPerWord;
+            }
+            else {
+                break;
+            }
+        }
+        cur_entry = cur_row + (BytesPerWord - 1);
+        HeapWord* last_hw = _ct->addr_for(cur_row + BytesPerWord);
+        end_of_non_clean = last_hw;
+        start_of_non_clean = last_hw;
+      } else {
       // Reset the dirty window, while continuing to look
       // for the next dirty card that will start a
       // new dirty window.
       end_of_non_clean = cur_hw;
       start_of_non_clean = cur_hw;
+          cur_entry--;
+      }
     }
     // Note that "cur_entry" leads "start_of_non_clean" in
     // its leftward excursion after this point
     // in the loop and, when we hit the left end of "mr",
     // will point off of the left end of the card-table
     // for "mr".
-    cur_entry--;
   }
   // If the first card of "mr" was dirty, we will have
   // been left with a dirty window, co-initial with "mr",
   // which we now process.
   if (start_of_non_clean < end_of_non_clean) {