Mercurial > hg > truffle
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;} |