< prev index next >

src/hotspot/share/gc/g1/g1RemSet.cpp

Print this page
rev 52310 : imported patch 8071913-almost-done

*** 131,144 **** public: G1ResetScanTopClosure(HeapWord** scan_top) : _scan_top(scan_top) { } virtual bool do_heap_region(HeapRegion* r) { uint hrm_index = r->hrm_index(); ! if (!r->in_collection_set() && r->is_old_or_humongous_or_archive()) { _scan_top[hrm_index] = r->top(); } else { ! _scan_top[hrm_index] = r->bottom(); } return false; } }; --- 131,144 ---- public: G1ResetScanTopClosure(HeapWord** scan_top) : _scan_top(scan_top) { } virtual bool do_heap_region(HeapRegion* r) { uint hrm_index = r->hrm_index(); ! if (!r->in_collection_set() && r->is_old_or_humongous_or_archive() && !r->is_empty()) { _scan_top[hrm_index] = r->top(); } else { ! _scan_top[hrm_index] = NULL; } return false; } };
*** 189,198 **** --- 189,199 ---- } void reset() { for (uint i = 0; i < _max_regions; i++) { _iter_states[i] = Unclaimed; + _scan_top[i] = NULL; } G1ResetScanTopClosure cl(_scan_top); G1CollectedHeap::heap()->heap_region_iterate(&cl);
*** 348,357 **** --- 349,362 ---- // clear the card table concurrently therefore we won't need to // add regions of the collection set to the dirty cards region. _scan_state->add_dirty_region(region_idx); } + if (r->rem_set()->cardset_is_empty()) { + return; + } + // We claim cards in blocks so as to reduce the contention. size_t const block_size = G1RSetScanBlockSize; HeapRegionRemSetIterator iter(r->rem_set()); size_t card_index;
*** 365,389 **** _cards_skipped++; continue; } _cards_claimed++; ! // If the card is dirty, then G1 will scan it during Update RS. ! if (_ct->is_card_claimed(card_index) || _ct->is_card_dirty(card_index)) { ! continue; ! } ! ! HeapWord* const card_start = _g1h->bot()->address_for_index(card_index); uint const region_idx_for_card = _g1h->addr_to_region(card_start); ! assert(_g1h->region_at(region_idx_for_card)->is_in_reserved(card_start), "Card start " PTR_FORMAT " to scan outside of region %u", p2i(card_start), _g1h->region_at(region_idx_for_card)->hrm_index()); HeapWord* const top = _scan_state->scan_top(region_idx_for_card); if (card_start >= top) { continue; } // We claim 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). // Claim the card after checking bounds above: the remembered set may contain // random cards into current survivor, and we would then have an incorrectly // claimed card in survivor space. Card table clear does not reset the card table --- 370,397 ---- _cards_skipped++; continue; } _cards_claimed++; ! HeapWord* const card_start = _g1h->bot()->address_for_index_raw(card_index); uint const region_idx_for_card = _g1h->addr_to_region(card_start); ! #ifdef ASSERT ! HeapRegion* hr = _g1h->region_at_or_null(region_idx_for_card); ! assert(hr == NULL || hr->is_in_reserved(card_start), "Card start " PTR_FORMAT " to scan outside of region %u", p2i(card_start), _g1h->region_at(region_idx_for_card)->hrm_index()); + #endif HeapWord* const top = _scan_state->scan_top(region_idx_for_card); if (card_start >= top) { continue; } + // If the card is dirty, then G1 will scan it during Update RS. + if (_ct->is_card_claimed(card_index) || _ct->is_card_dirty(card_index)) { + continue; + } + // We claim 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). // Claim the card after checking bounds above: the remembered set may contain // random cards into current survivor, and we would then have an incorrectly // claimed card in survivor space. Card table clear does not reset the card table
*** 543,564 **** void G1RemSet::refine_card_concurrently(jbyte* card_ptr, uint worker_i) { assert(!_g1h->is_gc_active(), "Only call concurrently"); check_card_ptr(card_ptr, _ct); // If the card is no longer dirty, nothing to do. if (*card_ptr != G1CardTable::dirty_card_val()) { return; } - // Construct the region representing the card. - HeapWord* start = _ct->addr_for(card_ptr); - // And find the region containing it. - HeapRegion* r = _g1h->heap_region_containing(start); - // This check is needed for some uncommon cases where we should // ignore the card. // // The region could be young. Cards for young regions are // distinctly marked (set to g1_young_gen), so the post-barrier will --- 551,577 ---- void G1RemSet::refine_card_concurrently(jbyte* card_ptr, uint worker_i) { assert(!_g1h->is_gc_active(), "Only call concurrently"); + // Construct the region representing the card. + HeapWord* start = _ct->addr_for(card_ptr); + // And find the region containing it. + HeapRegion* r = _g1h->heap_region_containing_or_null(start); + + // If this is a (stale) card into an uncommitted region, exit. + if (r == NULL) { + return; + } + check_card_ptr(card_ptr, _ct); // If the card is no longer dirty, nothing to do. if (*card_ptr != G1CardTable::dirty_card_val()) { return; } // This check is needed for some uncommon cases where we should // ignore the card. // // The region could be young. Cards for young regions are // distinctly marked (set to g1_young_gen), so the post-barrier will
*** 677,686 **** --- 690,711 ---- bool G1RemSet::refine_card_during_gc(jbyte* card_ptr, G1ScanObjsDuringUpdateRSClosure* update_rs_cl) { assert(_g1h->is_gc_active(), "Only call during GC"); + // Construct the region representing the card. + HeapWord* card_start = _ct->addr_for(card_ptr); + // And find the region containing it. + uint const card_region_idx = _g1h->addr_to_region(card_start); + + HeapWord* scan_limit = _scan_state->scan_top(card_region_idx); + if (scan_limit == NULL) { + // This is a card into an uncommitted region. We need to bail out early as we + // should not access the corresponding card table entry. + return false; + } + check_card_ptr(card_ptr, _ct); // If the card is no longer dirty, nothing to do. This covers cards that were already // scanned as parts of the remembered sets. if (*card_ptr != G1CardTable::dirty_card_val()) {
*** 689,705 **** // We claim lazily (so races are possible but they're benign), which reduces the // number of potential duplicate scans (multiple threads may enqueue the same card twice). *card_ptr = G1CardTable::clean_card_val() | G1CardTable::claimed_card_val(); - // Construct the region representing the card. - HeapWord* card_start = _ct->addr_for(card_ptr); - // And find the region containing it. - uint const card_region_idx = _g1h->addr_to_region(card_start); - _scan_state->add_dirty_region(card_region_idx); - HeapWord* scan_limit = _scan_state->scan_top(card_region_idx); if (scan_limit <= card_start) { // If the card starts above the area in the region containing objects to scan, skip it. return false; } --- 714,724 ----
< prev index next >