ScanRSClosure(OopsInHeapRegionClosure* oc, int worker_i) : _oc(oc), _cards(0), _cards_done(0), _worker_i(worker_i), _try_claimed(false) { _g1h = G1CollectedHeap::heap(); _bot_shared = _g1h->bot_shared(); _ct_bs = (CardTableModRefBS*) (_g1h->barrier_set()); _block_size = MAX2<int>(G1RSetScanBlockSize, 1); }
bool doHeapRegion(HeapRegion* r) { assert(r->in_collection_set(), "should only be called on elements of CS."); HeapRegionRemSet* hrrs = r->rem_set(); if (hrrs->iter_is_complete()) return false; // All done. if (!_try_claimed && !hrrs->claim_iter()) return false; _g1h->push_dirty_cards_region(r); // If we didn't return above, then // _try_claimed || r->claim_iter() // is true: either we're supposed to work on claimed-but-not-complete // regions, or we successfully claimed the region. HeapRegionRemSetIterator* iter = _g1h->rem_set_iterator(_worker_i); hrrs->init_iterator(iter); size_t card_index; // We claim cards in block so as to recude the contention. The block size is determined by // the G1RSetScanBlockSize parameter. size_t jump_to_card = hrrs->iter_claimed_next(_block_size); for (size_t current_card = 0; iter->has_next(card_index); current_card++) { if (current_card >= jump_to_card + _block_size) { jump_to_card = hrrs->iter_claimed_next(_block_size); } if (current_card < jump_to_card) continue; HeapWord* card_start = _g1h->bot_shared()->address_for_index(card_index); #if 0 gclog_or_tty->print("Rem set iteration yielded card [" PTR_FORMAT ", " PTR_FORMAT ").\n", card_start, card_start + CardTableModRefBS::card_size_in_words); #endif HeapRegion* card_region = _g1h->heap_region_containing(card_start); assert(card_region != NULL, "Yielding cards not in the heap?"); _cards++; if (!card_region->is_on_dirty_cards_region_list()) { _g1h->push_dirty_cards_region(card_region); } // If the card is dirty, then we will scan it during updateRS. if (!card_region->in_collection_set() && !_ct_bs->is_card_dirty(card_index)) { // We make the card as "claimed" lazily (so races are possible but they're benign), // which reduces the number of duplicate scans (the rsets of the regions in the cset // can intersect). if (!_ct_bs->is_card_claimed(card_index)) { _ct_bs->set_card_claimed(card_index); scanCard(card_index, card_region); } } } if (!_try_claimed) { hrrs->set_iter_complete(); } return false; }
bool doHeapRegion(HeapRegion* r) { assert(r->in_collection_set(), "should only be called on elements of CS."); HeapRegionRemSet* hrrs = r->rem_set(); if (hrrs->iter_is_complete()) return false; // All done. if (!_try_claimed && !hrrs->claim_iter()) return false; // If we ever free the collection set concurrently, we should also // clear the card table concurrently therefore we won't need to // add regions of the collection set to the dirty cards region. _g1h->push_dirty_cards_region(r); // If we didn't return above, then // _try_claimed || r->claim_iter() // is true: either we're supposed to work on claimed-but-not-complete // regions, or we successfully claimed the region. HeapRegionRemSetIterator iter(hrrs); size_t card_index; // We claim cards in block so as to reduce the contention. The block size is determined by // the G1RSetScanBlockSize parameter. size_t jump_to_card = hrrs->iter_claimed_next(_block_size); for (size_t current_card = 0; iter.has_next(card_index); current_card++) { if (current_card >= jump_to_card + _block_size) { jump_to_card = hrrs->iter_claimed_next(_block_size); } if (current_card < jump_to_card) continue; HeapWord* card_start = _g1h->bot_shared()->address_for_index(card_index); #if 0 gclog_or_tty->print("Rem set iteration yielded card [" PTR_FORMAT ", " PTR_FORMAT ").\n", card_start, card_start + CardTableModRefBS::card_size_in_words); #endif HeapRegion* card_region = _g1h->heap_region_containing(card_start); _cards++; if (!card_region->is_on_dirty_cards_region_list()) { _g1h->push_dirty_cards_region(card_region); } // If the card is dirty, then we will scan it during updateRS. if (!card_region->in_collection_set() && !_ct_bs->is_card_dirty(card_index)) { scanCard(card_index, card_region); } } if (!_try_claimed) { // Scan the strong code root list attached to the current region scan_strong_code_roots(r); hrrs->set_iter_complete(); } return false; }
ScanRSClosure(G1ParPushHeapRSClosure* oc, CodeBlobClosure* code_root_cl, uint worker_i) : _oc(oc), _code_root_cl(code_root_cl), _strong_code_root_scan_time_sec(0.0), _cards(0), _cards_done(0), _worker_i(worker_i), _try_claimed(false) { _g1h = G1CollectedHeap::heap(); _bot_shared = _g1h->bot_shared(); _ct_bs = _g1h->g1_barrier_set(); _block_size = MAX2<int>(G1RSetScanBlockSize, 1); }