1.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp Tue Feb 09 13:56:09 2010 -0800 1.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp Thu Feb 11 15:52:19 2010 -0800 1.3 @@ -155,8 +155,8 @@ 1.4 G1BlockOffsetSharedArray* _bot_shared; 1.5 CardTableModRefBS *_ct_bs; 1.6 int _worker_i; 1.7 + int _block_size; 1.8 bool _try_claimed; 1.9 - size_t _min_skip_distance, _max_skip_distance; 1.10 public: 1.11 ScanRSClosure(OopsInHeapRegionClosure* oc, int worker_i) : 1.12 _oc(oc), 1.13 @@ -168,8 +168,7 @@ 1.14 _g1h = G1CollectedHeap::heap(); 1.15 _bot_shared = _g1h->bot_shared(); 1.16 _ct_bs = (CardTableModRefBS*) (_g1h->barrier_set()); 1.17 - _min_skip_distance = 16; 1.18 - _max_skip_distance = 2 * _g1h->n_par_threads() * _min_skip_distance; 1.19 + _block_size = MAX2<int>(G1RSetScanBlockSize, 1); 1.20 } 1.21 1.22 void set_try_claimed() { _try_claimed = true; } 1.23 @@ -225,12 +224,15 @@ 1.24 HeapRegionRemSetIterator* iter = _g1h->rem_set_iterator(_worker_i); 1.25 hrrs->init_iterator(iter); 1.26 size_t card_index; 1.27 - size_t skip_distance = 0, current_card = 0, jump_to_card = 0; 1.28 - while (iter->has_next(card_index)) { 1.29 - if (current_card < jump_to_card) { 1.30 - ++current_card; 1.31 - continue; 1.32 + 1.33 + // We claim cards in block so as to recude the contention. The block size is determined by 1.34 + // the G1RSetScanBlockSize parameter. 1.35 + size_t jump_to_card = hrrs->iter_claimed_next(_block_size); 1.36 + for (size_t current_card = 0; iter->has_next(card_index); current_card++) { 1.37 + if (current_card >= jump_to_card + _block_size) { 1.38 + jump_to_card = hrrs->iter_claimed_next(_block_size); 1.39 } 1.40 + if (current_card < jump_to_card) continue; 1.41 HeapWord* card_start = _g1h->bot_shared()->address_for_index(card_index); 1.42 #if 0 1.43 gclog_or_tty->print("Rem set iteration yielded card [" PTR_FORMAT ", " PTR_FORMAT ").\n", 1.44 @@ -247,22 +249,14 @@ 1.45 1.46 // If the card is dirty, then we will scan it during updateRS. 1.47 if (!card_region->in_collection_set() && !_ct_bs->is_card_dirty(card_index)) { 1.48 - if (!_ct_bs->is_card_claimed(card_index) && _ct_bs->claim_card(card_index)) { 1.49 - scanCard(card_index, card_region); 1.50 - } else if (_try_claimed) { 1.51 - if (jump_to_card == 0 || jump_to_card != current_card) { 1.52 - // We did some useful work in the previous iteration. 1.53 - // Decrease the distance. 1.54 - skip_distance = MAX2(skip_distance >> 1, _min_skip_distance); 1.55 - } else { 1.56 - // Previous iteration resulted in a claim failure. 1.57 - // Increase the distance. 1.58 - skip_distance = MIN2(skip_distance << 1, _max_skip_distance); 1.59 - } 1.60 - jump_to_card = current_card + skip_distance; 1.61 - } 1.62 + // We make the card as "claimed" lazily (so races are possible but they're benign), 1.63 + // which reduces the number of duplicate scans (the rsets of the regions in the cset 1.64 + // can intersect). 1.65 + if (!_ct_bs->is_card_claimed(card_index)) { 1.66 + _ct_bs->set_card_claimed(card_index); 1.67 + scanCard(card_index, card_region); 1.68 + } 1.69 } 1.70 - ++current_card; 1.71 } 1.72 if (!_try_claimed) { 1.73 hrrs->set_iter_complete(); 1.74 @@ -299,30 +293,18 @@ 1.75 double rs_time_start = os::elapsedTime(); 1.76 HeapRegion *startRegion = calculateStartRegion(worker_i); 1.77 1.78 - BufferingOopsInHeapRegionClosure boc(oc); 1.79 - ScanRSClosure scanRScl(&boc, worker_i); 1.80 + ScanRSClosure scanRScl(oc, worker_i); 1.81 _g1->collection_set_iterate_from(startRegion, &scanRScl); 1.82 scanRScl.set_try_claimed(); 1.83 _g1->collection_set_iterate_from(startRegion, &scanRScl); 1.84 1.85 - boc.done(); 1.86 - double closure_app_time_sec = boc.closure_app_seconds(); 1.87 - double scan_rs_time_sec = (os::elapsedTime() - rs_time_start) - 1.88 - closure_app_time_sec; 1.89 - double closure_app_time_ms = closure_app_time_sec * 1000.0; 1.90 + double scan_rs_time_sec = os::elapsedTime() - rs_time_start; 1.91 1.92 assert( _cards_scanned != NULL, "invariant" ); 1.93 _cards_scanned[worker_i] = scanRScl.cards_done(); 1.94 1.95 _g1p->record_scan_rs_start_time(worker_i, rs_time_start * 1000.0); 1.96 _g1p->record_scan_rs_time(worker_i, scan_rs_time_sec * 1000.0); 1.97 - 1.98 - double scan_new_refs_time_ms = _g1p->get_scan_new_refs_time(worker_i); 1.99 - if (scan_new_refs_time_ms > 0.0) { 1.100 - closure_app_time_ms += scan_new_refs_time_ms; 1.101 - } 1.102 - 1.103 - _g1p->record_obj_copy_time(worker_i, closure_app_time_ms); 1.104 } 1.105 1.106 void HRInto_G1RemSet::updateRS(int worker_i) { 1.107 @@ -449,9 +431,8 @@ 1.108 oc->do_oop(p); 1.109 } 1.110 } 1.111 - _g1p->record_scan_new_refs_time(worker_i, 1.112 - (os::elapsedTime() - scan_new_refs_start_sec) 1.113 - * 1000.0); 1.114 + double scan_new_refs_time_ms = (os::elapsedTime() - scan_new_refs_start_sec) * 1000.0; 1.115 + _g1p->record_scan_new_refs_time(worker_i, scan_new_refs_time_ms); 1.116 } 1.117 1.118 void HRInto_G1RemSet::cleanupHRRS() {