changeset 549:d1d334a18b5c

6819098: G1: reduce RSet scanning times Summary: Added a feedback-driven exponential skipping for parallel RSet scanning. Reviewed-by: tonyp, apetrusenko
author iveresov
date Mon, 27 Apr 2009 16:52:18 -0700
parents 3a18c3dc7d98
children ac375e93531e
files src/share/vm/gc_implementation/g1/g1RemSet.cpp
diffstat 1 files changed, 27 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Thu Apr 23 16:58:16 2009 -0400
+++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Mon Apr 27 16:52:18 2009 -0700
@@ -180,6 +180,7 @@
   CardTableModRefBS *_ct_bs;
   int _worker_i;
   bool _try_claimed;
+  size_t _min_skip_distance, _max_skip_distance;
 public:
   ScanRSClosure(OopsInHeapRegionClosure* oc, int worker_i) :
     _oc(oc),
@@ -191,6 +192,8 @@
     _g1h = G1CollectedHeap::heap();
     _bot_shared = _g1h->bot_shared();
     _ct_bs = (CardTableModRefBS*) (_g1h->barrier_set());
+    _min_skip_distance = 16;
+    _max_skip_distance = 2 * _g1h->n_par_threads() * _min_skip_distance;
   }
 
   void set_try_claimed() { _try_claimed = true; }
@@ -245,9 +248,13 @@
     HeapRegionRemSetIterator* iter = _g1h->rem_set_iterator(_worker_i);
     hrrs->init_iterator(iter);
     size_t card_index;
+    size_t skip_distance = 0, current_card = 0, jump_to_card = 0;
     while (iter->has_next(card_index)) {
+      if (current_card < jump_to_card) {
+        ++current_card;
+        continue;
+      }
       HeapWord* card_start = _g1h->bot_shared()->address_for_index(card_index);
-
 #if 0
       gclog_or_tty->print("Rem set iteration yielded card [" PTR_FORMAT ", " PTR_FORMAT ").\n",
                           card_start, card_start + CardTableModRefBS::card_size_in_words);
@@ -257,20 +264,28 @@
       assert(card_region != NULL, "Yielding cards not in the heap?");
       _cards++;
 
-      if (!card_region->in_collection_set()) {
-        // If the card is dirty, then we will scan it during updateRS.
-        if (!_ct_bs->is_card_claimed(card_index) &&
-            !_ct_bs->is_card_dirty(card_index)) {
-          assert(_ct_bs->is_card_clean(card_index) ||
-                 _ct_bs->is_card_claimed(card_index) ||
-                 _ct_bs->is_card_deferred(card_index),
-                 "Card is either clean, claimed or deferred");
-          if (_ct_bs->claim_card(card_index))
+       // If the card is dirty, then we will scan it during updateRS.
+      if (!card_region->in_collection_set() && !_ct_bs->is_card_dirty(card_index)) {
+          if (!_ct_bs->is_card_claimed(card_index) && _ct_bs->claim_card(card_index)) {
             scanCard(card_index, card_region);
-        }
+          } else if (_try_claimed) {
+            if (jump_to_card == 0 || jump_to_card != current_card) {
+              // We did some useful work in the previous iteration.
+              // Decrease the distance.
+              skip_distance = MAX2(skip_distance >> 1, _min_skip_distance);
+            } else {
+              // Previous iteration resulted in a claim failure.
+              // Increase the distance.
+              skip_distance = MIN2(skip_distance << 1, _max_skip_distance);
+            }
+            jump_to_card = current_card + skip_distance;
+          }
       }
+      ++current_card;
     }
-    hrrs->set_iter_complete();
+    if (!_try_claimed) {
+      hrrs->set_iter_complete();
+    }
     return false;
   }
   // Set all cards back to clean.