hotspot/src/share/vm/gc/g1/g1RemSet.cpp
changeset 34246 d2c05216f375
parent 34135 317af749634b
child 35061 be6025ebffea
equal deleted inserted replaced
34245:8ab9cefd6373 34246:d2c05216f375
    71     assert(_cset_rs_update_cl[i] == NULL, "it should be");
    71     assert(_cset_rs_update_cl[i] == NULL, "it should be");
    72   }
    72   }
    73   FREE_C_HEAP_ARRAY(G1ParPushHeapRSClosure*, _cset_rs_update_cl);
    73   FREE_C_HEAP_ARRAY(G1ParPushHeapRSClosure*, _cset_rs_update_cl);
    74 }
    74 }
    75 
    75 
    76 class ScanRSClosure : public HeapRegionClosure {
    76 ScanRSClosure::ScanRSClosure(G1ParPushHeapRSClosure* oc,
    77   size_t _cards_done, _cards;
    77                              CodeBlobClosure* code_root_cl,
    78   G1CollectedHeap* _g1h;
    78                              uint worker_i) :
    79 
       
    80   G1ParPushHeapRSClosure* _oc;
       
    81   CodeBlobClosure* _code_root_cl;
       
    82 
       
    83   G1BlockOffsetSharedArray* _bot_shared;
       
    84   G1SATBCardTableModRefBS *_ct_bs;
       
    85 
       
    86   double _strong_code_root_scan_time_sec;
       
    87   uint   _worker_i;
       
    88   size_t _block_size;
       
    89   bool   _try_claimed;
       
    90 
       
    91 public:
       
    92   ScanRSClosure(G1ParPushHeapRSClosure* oc,
       
    93                 CodeBlobClosure* code_root_cl,
       
    94                 uint worker_i) :
       
    95     _oc(oc),
    79     _oc(oc),
    96     _code_root_cl(code_root_cl),
    80     _code_root_cl(code_root_cl),
    97     _strong_code_root_scan_time_sec(0.0),
    81     _strong_code_root_scan_time_sec(0.0),
    98     _cards(0),
    82     _cards(0),
    99     _cards_done(0),
    83     _cards_done(0),
   100     _worker_i(worker_i),
    84     _worker_i(worker_i),
   101     _try_claimed(false)
    85     _try_claimed(false) {
   102   {
    86   _g1h = G1CollectedHeap::heap();
   103     _g1h = G1CollectedHeap::heap();
    87   _bot_shared = _g1h->bot_shared();
   104     _bot_shared = _g1h->bot_shared();
    88   _ct_bs = _g1h->g1_barrier_set();
   105     _ct_bs = _g1h->g1_barrier_set();
    89   _block_size = MAX2<size_t>(G1RSetScanBlockSize, 1);
   106     _block_size = MAX2<size_t>(G1RSetScanBlockSize, 1);
    90 }
   107   }
    91 
   108 
    92 void ScanRSClosure::scanCard(size_t index, HeapRegion *r) {
   109   void set_try_claimed() { _try_claimed = true; }
    93   // Stack allocate the DirtyCardToOopClosure instance
   110 
    94   HeapRegionDCTOC cl(_g1h, r, _oc,
   111   void scanCard(size_t index, HeapRegion *r) {
    95       CardTableModRefBS::Precise);
   112     // Stack allocate the DirtyCardToOopClosure instance
    96 
   113     HeapRegionDCTOC cl(_g1h, r, _oc,
    97   // Set the "from" region in the closure.
   114                        CardTableModRefBS::Precise);
    98   _oc->set_region(r);
   115 
    99   MemRegion card_region(_bot_shared->address_for_index(index), G1BlockOffsetSharedArray::N_words);
   116     // Set the "from" region in the closure.
   100   MemRegion pre_gc_allocated(r->bottom(), r->scan_top());
   117     _oc->set_region(r);
   101   MemRegion mr = pre_gc_allocated.intersection(card_region);
   118     MemRegion card_region(_bot_shared->address_for_index(index), G1BlockOffsetSharedArray::N_words);
   102   if (!mr.is_empty() && !_ct_bs->is_card_claimed(index)) {
   119     MemRegion pre_gc_allocated(r->bottom(), r->scan_top());
   103     // We make the card as "claimed" lazily (so races are possible
   120     MemRegion mr = pre_gc_allocated.intersection(card_region);
   104     // but they're benign), which reduces the number of duplicate
   121     if (!mr.is_empty() && !_ct_bs->is_card_claimed(index)) {
   105     // scans (the rsets of the regions in the cset can intersect).
   122       // We make the card as "claimed" lazily (so races are possible
   106     _ct_bs->set_card_claimed(index);
   123       // but they're benign), which reduces the number of duplicate
   107     _cards_done++;
   124       // scans (the rsets of the regions in the cset can intersect).
   108     cl.do_MemRegion(mr);
   125       _ct_bs->set_card_claimed(index);
   109   }
   126       _cards_done++;
   110 }
   127       cl.do_MemRegion(mr);
   111 
   128     }
   112 void ScanRSClosure::printCard(HeapRegion* card_region, size_t card_index,
   129   }
   113     HeapWord* card_start) {
   130 
   114   gclog_or_tty->print_cr("T %u Region [" PTR_FORMAT ", " PTR_FORMAT ") "
   131   void printCard(HeapRegion* card_region, size_t card_index,
   115       "RS names card " SIZE_FORMAT_HEX ": "
   132                  HeapWord* card_start) {
   116       "[" PTR_FORMAT ", " PTR_FORMAT ")",
   133     gclog_or_tty->print_cr("T %u Region [" PTR_FORMAT ", " PTR_FORMAT ") "
   117       _worker_i,
   134                            "RS names card " SIZE_FORMAT_HEX ": "
   118       p2i(card_region->bottom()), p2i(card_region->end()),
   135                            "[" PTR_FORMAT ", " PTR_FORMAT ")",
   119       card_index,
   136                            _worker_i,
   120       p2i(card_start), p2i(card_start + G1BlockOffsetSharedArray::N_words));
   137                            p2i(card_region->bottom()), p2i(card_region->end()),
   121 }
   138                            card_index,
   122 
   139                            p2i(card_start), p2i(card_start + G1BlockOffsetSharedArray::N_words));
   123 void ScanRSClosure::scan_strong_code_roots(HeapRegion* r) {
   140   }
   124   double scan_start = os::elapsedTime();
   141 
   125   r->strong_code_roots_do(_code_root_cl);
   142   void scan_strong_code_roots(HeapRegion* r) {
   126   _strong_code_root_scan_time_sec += (os::elapsedTime() - scan_start);
   143     double scan_start = os::elapsedTime();
   127 }
   144     r->strong_code_roots_do(_code_root_cl);
   128 
   145     _strong_code_root_scan_time_sec += (os::elapsedTime() - scan_start);
   129 bool ScanRSClosure::doHeapRegion(HeapRegion* r) {
   146   }
   130   assert(r->in_collection_set(), "should only be called on elements of CS.");
   147 
   131   HeapRegionRemSet* hrrs = r->rem_set();
   148   bool doHeapRegion(HeapRegion* r) {
   132   if (hrrs->iter_is_complete()) return false; // All done.
   149     assert(r->in_collection_set(), "should only be called on elements of CS.");
   133   if (!_try_claimed && !hrrs->claim_iter()) return false;
   150     HeapRegionRemSet* hrrs = r->rem_set();
   134   // If we ever free the collection set concurrently, we should also
   151     if (hrrs->iter_is_complete()) return false; // All done.
   135   // clear the card table concurrently therefore we won't need to
   152     if (!_try_claimed && !hrrs->claim_iter()) return false;
   136   // add regions of the collection set to the dirty cards region.
   153     // If we ever free the collection set concurrently, we should also
   137   _g1h->push_dirty_cards_region(r);
   154     // clear the card table concurrently therefore we won't need to
   138   // If we didn't return above, then
   155     // add regions of the collection set to the dirty cards region.
   139   //   _try_claimed || r->claim_iter()
   156     _g1h->push_dirty_cards_region(r);
   140   // is true: either we're supposed to work on claimed-but-not-complete
   157     // If we didn't return above, then
   141   // regions, or we successfully claimed the region.
   158     //   _try_claimed || r->claim_iter()
   142 
   159     // is true: either we're supposed to work on claimed-but-not-complete
   143   HeapRegionRemSetIterator iter(hrrs);
   160     // regions, or we successfully claimed the region.
   144   size_t card_index;
   161 
   145 
   162     HeapRegionRemSetIterator iter(hrrs);
   146   // We claim cards in block so as to reduce the contention. The block size is determined by
   163     size_t card_index;
   147   // the G1RSetScanBlockSize parameter.
   164 
   148   size_t jump_to_card = hrrs->iter_claimed_next(_block_size);
   165     // We claim cards in block so as to reduce the contention. The block size is determined by
   149   for (size_t current_card = 0; iter.has_next(card_index); current_card++) {
   166     // the G1RSetScanBlockSize parameter.
   150     if (current_card >= jump_to_card + _block_size) {
   167     size_t jump_to_card = hrrs->iter_claimed_next(_block_size);
   151       jump_to_card = hrrs->iter_claimed_next(_block_size);
   168     for (size_t current_card = 0; iter.has_next(card_index); current_card++) {
   152     }
   169       if (current_card >= jump_to_card + _block_size) {
   153     if (current_card < jump_to_card) continue;
   170         jump_to_card = hrrs->iter_claimed_next(_block_size);
   154     HeapWord* card_start = _g1h->bot_shared()->address_for_index(card_index);
   171       }
       
   172       if (current_card < jump_to_card) continue;
       
   173       HeapWord* card_start = _g1h->bot_shared()->address_for_index(card_index);
       
   174 #if 0
   155 #if 0
   175       gclog_or_tty->print("Rem set iteration yielded card [" PTR_FORMAT ", " PTR_FORMAT ").\n",
   156     gclog_or_tty->print("Rem set iteration yielded card [" PTR_FORMAT ", " PTR_FORMAT ").\n",
   176                           card_start, card_start + CardTableModRefBS::card_size_in_words);
   157         card_start, card_start + CardTableModRefBS::card_size_in_words);
   177 #endif
   158 #endif
   178 
   159 
   179       HeapRegion* card_region = _g1h->heap_region_containing(card_start);
   160     HeapRegion* card_region = _g1h->heap_region_containing(card_start);
   180       _cards++;
   161     _cards++;
   181 
   162 
   182       if (!card_region->is_on_dirty_cards_region_list()) {
   163     if (!card_region->is_on_dirty_cards_region_list()) {
   183         _g1h->push_dirty_cards_region(card_region);
   164       _g1h->push_dirty_cards_region(card_region);
   184       }
   165     }
   185 
   166 
   186       // If the card is dirty, then we will scan it during updateRS.
   167     // If the card is dirty, then we will scan it during updateRS.
   187       if (!card_region->in_collection_set() &&
   168     if (!card_region->in_collection_set() &&
   188           !_ct_bs->is_card_dirty(card_index)) {
   169         !_ct_bs->is_card_dirty(card_index)) {
   189         scanCard(card_index, card_region);
   170       scanCard(card_index, card_region);
   190       }
   171     }
   191     }
   172   }
   192     if (!_try_claimed) {
   173   if (!_try_claimed) {
   193       // Scan the strong code root list attached to the current region
   174     // Scan the strong code root list attached to the current region
   194       scan_strong_code_roots(r);
   175     scan_strong_code_roots(r);
   195 
   176 
   196       hrrs->set_iter_complete();
   177     hrrs->set_iter_complete();
   197     }
   178   }
   198     return false;
   179   return false;
   199   }
   180 }
   200 
       
   201   double strong_code_root_scan_time_sec() {
       
   202     return _strong_code_root_scan_time_sec;
       
   203   }
       
   204 
       
   205   size_t cards_done() { return _cards_done;}
       
   206   size_t cards_looked_up() { return _cards;}
       
   207 };
       
   208 
   181 
   209 size_t G1RemSet::scanRS(G1ParPushHeapRSClosure* oc,
   182 size_t G1RemSet::scanRS(G1ParPushHeapRSClosure* oc,
   210                         CodeBlobClosure* heap_region_codeblobs,
   183                         CodeBlobClosure* heap_region_codeblobs,
   211                         uint worker_i) {
   184                         uint worker_i) {
   212   double rs_time_start = os::elapsedTime();
   185   double rs_time_start = os::elapsedTime();