comparison src/share/vm/gc_implementation/g1/g1RemSet.cpp @ 747:b803b1b9e206

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 96b229c54d1e
children 20c6f43950b5
comparison
equal deleted inserted replaced
746:4753e4079a5a 747:b803b1b9e206
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;}