void HeapRegion::hr_clear(bool par, bool clear_space) { _humongous_type = NotHumongous; _humongous_start_region = NULL; _in_collection_set = false; _is_gc_alloc_region = false; // Age stuff (if parallel, this will be done separately, since it needs // to be sequential). G1CollectedHeap* g1h = G1CollectedHeap::heap(); set_young_index_in_cset(-1); uninstall_surv_rate_group(); set_young_type(NotYoung); // In case it had been the start of a humongous sequence, reset its end. set_end(_orig_end); if (!par) { // If this is parallel, this will be done later. HeapRegionRemSet* hrrs = rem_set(); if (hrrs != NULL) hrrs->clear(); _claimed = InitialClaimValue; } zero_marked_bytes(); set_sort_index(-1); _offsets.resize(HeapRegion::GrainWords); init_top_at_mark_start(); if (clear_space) clear(SpaceDecorator::Mangle); }
void HeapRegion::hr_clear(bool par, bool clear_space, bool locked) { assert(_humongous_type == NotHumongous, "we should have already filtered out humongous regions"); assert(_humongous_start_region == NULL, "we should have already filtered out humongous regions"); assert(_end == _orig_end, "we should have already filtered out humongous regions"); _in_collection_set = false; set_young_index_in_cset(-1); uninstall_surv_rate_group(); set_young_type(NotYoung); reset_pre_dummy_top(); if (!par) { // If this is parallel, this will be done later. HeapRegionRemSet* hrrs = rem_set(); if (locked) { hrrs->clear_locked(); } else { hrrs->clear(); } _claimed = InitialClaimValue; } zero_marked_bytes(); _offsets.resize(HeapRegion::GrainWords); init_top_at_mark_start(); if (clear_space) clear(SpaceDecorator::Mangle); }
void HeapRegion::migrate_strong_code_roots() { assert(in_collection_set(), "only collection set regions"); assert(!isHumongous(), err_msg("humongous region "HR_FORMAT" should not have been added to collection set", HR_FORMAT_PARAMS(this))); HeapRegionRemSet* hrrs = rem_set(); hrrs->migrate_strong_code_roots(); }
void HeapRegion::par_clear() { assert(used() == 0, "the region should have been already cleared"); assert(capacity() == HeapRegion::GrainBytes, "should be back to normal"); HeapRegionRemSet* hrrs = rem_set(); hrrs->clear(); CardTableModRefBS* ct_bs = (CardTableModRefBS*)G1CollectedHeap::heap()->barrier_set(); ct_bs->clear(MemRegion(bottom(), end())); }
void HeapRegion::verify_strong_code_roots(VerifyOption vo, bool* failures) const { if (!G1VerifyHeapRegionCodeRoots) { // We're not verifying code roots. return; } if (vo == VerifyOption_G1UseMarkWord) { // Marking verification during a full GC is performed after class // unloading, code cache unloading, etc so the strong code roots // attached to each heap region are in an inconsistent state. They won't // be consistent until the strong code roots are rebuilt after the // actual GC. Skip verifying the strong code roots in this particular // time. assert(VerifyDuringGC, "only way to get here"); return; } HeapRegionRemSet* hrrs = rem_set(); size_t strong_code_roots_length = hrrs->strong_code_roots_list_length(); // if this region is empty then there should be no entries // on its strong code root list if (is_empty()) { if (strong_code_roots_length > 0) { gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] is empty " "but has "SIZE_FORMAT" code root entries", bottom(), end(), strong_code_roots_length); *failures = true; } return; } if (continuesHumongous()) { if (strong_code_roots_length > 0) { gclog_or_tty->print_cr("region "HR_FORMAT" is a continuation of a humongous " "region but has "SIZE_FORMAT" code root entries", HR_FORMAT_PARAMS(this), strong_code_roots_length); *failures = true; } return; } VerifyStrongCodeRootCodeBlobClosure cb_cl(this); strong_code_roots_do(&cb_cl); if (cb_cl.failures()) { *failures = true; } }
bool doHeapRegion(HeapRegion* r) { HeapRegionRemSet* hrrs = r->rem_set(); _count += (int) hrrs->occupied(); if (hrrs->occupied() == 0) { gclog_or_tty->print("Heap Region [" PTR_FORMAT ", " PTR_FORMAT ") " "has no remset entries\n", r->bottom(), r->end()); } else { gclog_or_tty->print("Printing rem set for heap region [" PTR_FORMAT ", " PTR_FORMAT ")\n", r->bottom(), r->end()); r->print(); hrrs->print(); gclog_or_tty->print("\nDone printing rem set\n"); } 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; _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; }
void HeapRegion::strong_code_roots_do(CodeBlobClosure* blk) const { HeapRegionRemSet* hrrs = rem_set(); hrrs->strong_code_roots_do(blk); }
void HeapRegion::remove_strong_code_root(nmethod* nm) { HeapRegionRemSet* hrrs = rem_set(); hrrs->remove_strong_code_root(nm); }
void HeapRegion::add_strong_code_root_locked(nmethod* nm) { assert_locked_or_safepoint(CodeCache_lock); HeapRegionRemSet* hrrs = rem_set(); hrrs->add_strong_code_root_locked(nm); }
bool doHeapRegion(HeapRegion *r) { HeapRegionRemSet* hrrs = r->rem_set(); hrrs->init_for_par_iteration(); return false; }