hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp
changeset 2737 0c3db8869263
parent 2344 f2e09ba7ceab
child 2741 34e2a243d69a
equal deleted inserted replaced
2736:b4cf1910f23e 2737:0c3db8869263
   178   OopsInHeapRegionClosure* _oc;
   178   OopsInHeapRegionClosure* _oc;
   179   G1BlockOffsetSharedArray* _bot_shared;
   179   G1BlockOffsetSharedArray* _bot_shared;
   180   CardTableModRefBS *_ct_bs;
   180   CardTableModRefBS *_ct_bs;
   181   int _worker_i;
   181   int _worker_i;
   182   bool _try_claimed;
   182   bool _try_claimed;
       
   183   size_t _min_skip_distance, _max_skip_distance;
   183 public:
   184 public:
   184   ScanRSClosure(OopsInHeapRegionClosure* oc, int worker_i) :
   185   ScanRSClosure(OopsInHeapRegionClosure* oc, int worker_i) :
   185     _oc(oc),
   186     _oc(oc),
   186     _cards(0),
   187     _cards(0),
   187     _cards_done(0),
   188     _cards_done(0),
   189     _try_claimed(false)
   190     _try_claimed(false)
   190   {
   191   {
   191     _g1h = G1CollectedHeap::heap();
   192     _g1h = G1CollectedHeap::heap();
   192     _bot_shared = _g1h->bot_shared();
   193     _bot_shared = _g1h->bot_shared();
   193     _ct_bs = (CardTableModRefBS*) (_g1h->barrier_set());
   194     _ct_bs = (CardTableModRefBS*) (_g1h->barrier_set());
       
   195     _min_skip_distance = 16;
       
   196     _max_skip_distance = 2 * _g1h->n_par_threads() * _min_skip_distance;
   194   }
   197   }
   195 
   198 
   196   void set_try_claimed() { _try_claimed = true; }
   199   void set_try_claimed() { _try_claimed = true; }
   197 
   200 
   198   void scanCard(size_t index, HeapRegion *r) {
   201   void scanCard(size_t index, HeapRegion *r) {
   243     // is true: either we're supposed to work on claimed-but-not-complete
   246     // is true: either we're supposed to work on claimed-but-not-complete
   244     // regions, or we successfully claimed the region.
   247     // regions, or we successfully claimed the region.
   245     HeapRegionRemSetIterator* iter = _g1h->rem_set_iterator(_worker_i);
   248     HeapRegionRemSetIterator* iter = _g1h->rem_set_iterator(_worker_i);
   246     hrrs->init_iterator(iter);
   249     hrrs->init_iterator(iter);
   247     size_t card_index;
   250     size_t card_index;
       
   251     size_t skip_distance = 0, current_card = 0, jump_to_card = 0;
   248     while (iter->has_next(card_index)) {
   252     while (iter->has_next(card_index)) {
       
   253       if (current_card < jump_to_card) {
       
   254         ++current_card;
       
   255         continue;
       
   256       }
   249       HeapWord* card_start = _g1h->bot_shared()->address_for_index(card_index);
   257       HeapWord* card_start = _g1h->bot_shared()->address_for_index(card_index);
   250 
       
   251 #if 0
   258 #if 0
   252       gclog_or_tty->print("Rem set iteration yielded card [" PTR_FORMAT ", " PTR_FORMAT ").\n",
   259       gclog_or_tty->print("Rem set iteration yielded card [" PTR_FORMAT ", " PTR_FORMAT ").\n",
   253                           card_start, card_start + CardTableModRefBS::card_size_in_words);
   260                           card_start, card_start + CardTableModRefBS::card_size_in_words);
   254 #endif
   261 #endif
   255 
   262 
   256       HeapRegion* card_region = _g1h->heap_region_containing(card_start);
   263       HeapRegion* card_region = _g1h->heap_region_containing(card_start);
   257       assert(card_region != NULL, "Yielding cards not in the heap?");
   264       assert(card_region != NULL, "Yielding cards not in the heap?");
   258       _cards++;
   265       _cards++;
   259 
   266 
   260       if (!card_region->in_collection_set()) {
   267        // If the card is dirty, then we will scan it during updateRS.
   261         // If the card is dirty, then we will scan it during updateRS.
   268       if (!card_region->in_collection_set() && !_ct_bs->is_card_dirty(card_index)) {
   262         if (!_ct_bs->is_card_claimed(card_index) &&
   269           if (!_ct_bs->is_card_claimed(card_index) && _ct_bs->claim_card(card_index)) {
   263             !_ct_bs->is_card_dirty(card_index)) {
       
   264           assert(_ct_bs->is_card_clean(card_index) ||
       
   265                  _ct_bs->is_card_claimed(card_index) ||
       
   266                  _ct_bs->is_card_deferred(card_index),
       
   267                  "Card is either clean, claimed or deferred");
       
   268           if (_ct_bs->claim_card(card_index))
       
   269             scanCard(card_index, card_region);
   270             scanCard(card_index, card_region);
   270         }
   271           } else if (_try_claimed) {
       
   272             if (jump_to_card == 0 || jump_to_card != current_card) {
       
   273               // We did some useful work in the previous iteration.
       
   274               // Decrease the distance.
       
   275               skip_distance = MAX2(skip_distance >> 1, _min_skip_distance);
       
   276             } else {
       
   277               // Previous iteration resulted in a claim failure.
       
   278               // Increase the distance.
       
   279               skip_distance = MIN2(skip_distance << 1, _max_skip_distance);
       
   280             }
       
   281             jump_to_card = current_card + skip_distance;
       
   282           }
   271       }
   283       }
   272     }
   284       ++current_card;
   273     hrrs->set_iter_complete();
   285     }
       
   286     if (!_try_claimed) {
       
   287       hrrs->set_iter_complete();
       
   288     }
   274     return false;
   289     return false;
   275   }
   290   }
   276   // Set all cards back to clean.
   291   // Set all cards back to clean.
   277   void cleanup() {_g1h->cleanUpCardTable();}
   292   void cleanup() {_g1h->cleanUpCardTable();}
   278   size_t cards_done() { return _cards_done;}
   293   size_t cards_done() { return _cards_done;}