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(); }
bool HeapRegionSetBase::verify_region(HeapRegion* hr, HeapRegionSetBase* expected_containing_set) { const char* error_message = NULL; if (!regions_humongous()) { if (hr->isHumongous()) { error_message = "the region should not be humongous"; } } else { if (!hr->isHumongous() || !hr->startsHumongous()) { error_message = "the region should be 'starts humongous'"; } } if (!regions_empty()) { if (hr->is_empty()) { error_message = "the region should not be empty"; } } else { if (!hr->is_empty()) { error_message = "the region should be empty"; } } #ifdef ASSERT // The _containing_set field is only available when ASSERT is defined. if (hr->containing_set() != expected_containing_set) { error_message = "inconsistent containing set found"; } #endif // ASSERT const char* extra_error_message = verify_region_extra(hr); if (extra_error_message != NULL) { error_message = extra_error_message; } if (error_message != NULL) { outputStream* out = tty; out->cr(); out->print_cr("## [%s] %s", name(), error_message); out->print_cr("## Offending Region: "PTR_FORMAT, hr); out->print_cr(" "HR_FORMAT, HR_FORMAT_PARAMS(hr)); #ifdef ASSERT out->print_cr(" containing set: "PTR_FORMAT, hr->containing_set()); #endif // ASSERT out->print_cr("## Offending Region Set: "PTR_FORMAT, this); print_on(out); return false; } else { return true; } }
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; } }
void HeapRegionSeq::verify_optional() { guarantee(length() <= _allocated_length, err_msg("invariant: _length: %u _allocated_length: %u", length(), _allocated_length)); guarantee(_allocated_length <= max_length(), err_msg("invariant: _allocated_length: %u _max_length: %u", _allocated_length, max_length())); guarantee(_next_search_index <= length(), err_msg("invariant: _next_search_index: %u _length: %u", _next_search_index, length())); HeapWord* prev_end = heap_bottom(); for (uint i = 0; i < _allocated_length; i += 1) { HeapRegion* hr = _regions.get_by_index(i); guarantee(hr != NULL, err_msg("invariant: i: %u", i)); guarantee(hr->bottom() == prev_end, err_msg("invariant i: %u "HR_FORMAT" prev_end: "PTR_FORMAT, i, HR_FORMAT_PARAMS(hr), p2i(prev_end))); guarantee(hr->hrs_index() == i, err_msg("invariant: i: %u hrs_index(): %u", i, hr->hrs_index())); if (i < length()) { // Asserts will fire if i is >= _length HeapWord* addr = hr->bottom(); guarantee(addr_to_region(addr) == hr, "sanity"); guarantee(addr_to_region_unsafe(addr) == hr, "sanity"); } else { guarantee(hr->is_empty(), "sanity"); guarantee(!hr->isHumongous(), "sanity"); // using assert instead of guarantee here since containing_set() // is only available in non-product builds. assert(hr->containing_set() == NULL, "sanity"); } if (hr->startsHumongous()) { prev_end = hr->orig_end(); } else { prev_end = hr->end(); } } for (uint i = _allocated_length; i < max_length(); i += 1) { guarantee(_regions.get_by_index(i) == NULL, err_msg("invariant i: %u", i)); } }
void HeapRegionManager::verify() { guarantee(length() <= _allocated_heapregions_length, "invariant: _length: %u _allocated_length: %u", length(), _allocated_heapregions_length); guarantee(_allocated_heapregions_length <= max_length(), "invariant: _allocated_length: %u _max_length: %u", _allocated_heapregions_length, max_length()); bool prev_committed = true; uint num_committed = 0; HeapWord* prev_end = heap_bottom(); for (uint i = 0; i < _allocated_heapregions_length; i++) { if (!is_available(i)) { prev_committed = false; continue; } num_committed++; HeapRegion* hr = _regions.get_by_index(i); guarantee(hr != NULL, "invariant: i: %u", i); guarantee(!prev_committed || hr->bottom() == prev_end, "invariant i: %u " HR_FORMAT " prev_end: " PTR_FORMAT, i, HR_FORMAT_PARAMS(hr), p2i(prev_end)); guarantee(hr->hrm_index() == i, "invariant: i: %u hrm_index(): %u", i, hr->hrm_index()); // Asserts will fire if i is >= _length HeapWord* addr = hr->bottom(); guarantee(addr_to_region(addr) == hr, "sanity"); // We cannot check whether the region is part of a particular set: at the time // this method may be called, we have only completed allocation of the regions, // but not put into a region set. prev_committed = true; prev_end = hr->end(); } for (uint i = _allocated_heapregions_length; i < max_length(); i++) { guarantee(_regions.get_by_index(i) == NULL, "invariant i: %u", i); } guarantee(num_committed == _num_committed, "Found %u committed regions, but should be %u", num_committed, _num_committed); _free_list.verify(); }
void G1RemSetSummary::print_on(outputStream* out) { out->print_cr("\n Concurrent RS processed "SIZE_FORMAT" cards", num_concurrent_refined_cards()); out->print_cr(" Of %d completed buffers:", num_processed_buf_total()); out->print_cr(" %8d (%5.1f%%) by concurrent RS threads.", num_processed_buf_total(), calc_percentage(num_processed_buf_rs_threads(), num_processed_buf_total())); out->print_cr(" %8d (%5.1f%%) by mutator threads.", num_processed_buf_mutator(), calc_percentage(num_processed_buf_mutator(), num_processed_buf_total())); out->print_cr(" Concurrent RS threads times (s)"); out->print(" "); for (uint i = 0; i < _num_vtimes; i++) { out->print(" %5.2f", rs_thread_vtime(i)); } out->cr(); out->print_cr(" Concurrent sampling threads times (s)"); out->print_cr(" %5.2f", sampling_thread_vtime()); HRRSStatsIter blk; G1CollectedHeap::heap()->heap_region_iterate(&blk); out->print_cr(" Total heap region rem set sizes = "SIZE_FORMAT"K." " Max = "SIZE_FORMAT"K.", blk.total_mem_sz()/K, blk.max_mem_sz()/K); out->print_cr(" Static structures = "SIZE_FORMAT"K," " free_lists = "SIZE_FORMAT"K.", HeapRegionRemSet::static_mem_size() / K, HeapRegionRemSet::fl_mem_size() / K); out->print_cr(" "SIZE_FORMAT" occupied cards represented.", blk.occupied()); HeapRegion* max_mem_sz_region = blk.max_mem_sz_region(); HeapRegionRemSet* rem_set = max_mem_sz_region->rem_set(); out->print_cr(" Max size region = "HR_FORMAT", " "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.", HR_FORMAT_PARAMS(max_mem_sz_region), (rem_set->mem_size() + K - 1)/K, (rem_set->occupied() + K - 1)/K); out->print_cr(" Did %d coarsenings.", num_coarsenings()); }
void YoungList::print() { HeapRegion* lists[] = {_head, _survivor_head}; const char* names[] = {"YOUNG", "SURVIVOR"}; for (uint list = 0; list < ARRAY_SIZE(lists); ++list) { tty->print_cr("%s LIST CONTENTS", names[list]); HeapRegion *curr = lists[list]; if (curr == NULL) { tty->print_cr(" empty"); } while (curr != NULL) { tty->print_cr(" " HR_FORMAT ", P: " PTR_FORMAT ", N: " PTR_FORMAT ", age: %4d", HR_FORMAT_PARAMS(curr), p2i(curr->prev_top_at_mark_start()), p2i(curr->next_top_at_mark_start()), curr->age_in_surv_rate_group_cond()); curr = curr->get_next_young_region(); } } tty->cr(); }
void G1AllocRegion::trace(const char* str, size_t word_size, HeapWord* result) { // All the calls to trace that set either just the size or the size // and the result are considered part of level 2 tracing and are // skipped during level 1 tracing. if ((word_size == 0 && result == NULL) || (G1_ALLOC_REGION_TRACING > 1)) { const size_t buffer_length = 128; char hr_buffer[buffer_length]; char rest_buffer[buffer_length]; HeapRegion* alloc_region = _alloc_region; if (alloc_region == NULL) { jio_snprintf(hr_buffer, buffer_length, "NULL"); } else if (alloc_region == _dummy_region) { jio_snprintf(hr_buffer, buffer_length, "DUMMY"); } else { jio_snprintf(hr_buffer, buffer_length, HR_FORMAT, HR_FORMAT_PARAMS(alloc_region)); } if (G1_ALLOC_REGION_TRACING > 1) { if (result != NULL) { jio_snprintf(rest_buffer, buffer_length, SIZE_FORMAT" "PTR_FORMAT, word_size, result); } else if (word_size != 0) { jio_snprintf(rest_buffer, buffer_length, SIZE_FORMAT, word_size); } else { jio_snprintf(rest_buffer, buffer_length, ""); } } else { jio_snprintf(rest_buffer, buffer_length, ""); } tty->print_cr("[%s] %u %s : %s %s", _name, _count, hr_buffer, str, rest_buffer); } }
void do_oop_work(T* p) { assert(_containing_obj != NULL, "Precondition"); assert(!_g1h->is_obj_dead_cond(_containing_obj, _vo), "Precondition"); T heap_oop = oopDesc::load_heap_oop(p); if (!oopDesc::is_null(heap_oop)) { oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); bool failed = false; if (!_g1h->is_in_closed_subset(obj) || _g1h->is_obj_dead_cond(obj, _vo)) { MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag); if (!_failures) { gclog_or_tty->cr(); gclog_or_tty->print_cr("----------"); } if (!_g1h->is_in_closed_subset(obj)) { HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p); gclog_or_tty->print_cr("Field "PTR_FORMAT " of live obj "PTR_FORMAT" in region " "["PTR_FORMAT", "PTR_FORMAT")", p, (void*) _containing_obj, from->bottom(), from->end()); print_object(gclog_or_tty, _containing_obj); gclog_or_tty->print_cr("points to obj "PTR_FORMAT" not in the heap", (void*) obj); } else { HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p); HeapRegion* to = _g1h->heap_region_containing((HeapWord*)obj); gclog_or_tty->print_cr("Field "PTR_FORMAT " of live obj "PTR_FORMAT" in region " "["PTR_FORMAT", "PTR_FORMAT")", p, (void*) _containing_obj, from->bottom(), from->end()); print_object(gclog_or_tty, _containing_obj); gclog_or_tty->print_cr("points to dead obj "PTR_FORMAT" in region " "["PTR_FORMAT", "PTR_FORMAT")", (void*) obj, to->bottom(), to->end()); print_object(gclog_or_tty, obj); } gclog_or_tty->print_cr("----------"); gclog_or_tty->flush(); _failures = true; failed = true; _n_failures++; } if (!_g1h->full_collection() || G1VerifyRSetsDuringFullGC) { HeapRegion* from = _g1h->heap_region_containing((HeapWord*)p); HeapRegion* to = _g1h->heap_region_containing(obj); if (from != NULL && to != NULL && from != to && !to->isHumongous()) { jbyte cv_obj = *_bs->byte_for_const(_containing_obj); jbyte cv_field = *_bs->byte_for_const(p); const jbyte dirty = CardTableModRefBS::dirty_card_val(); bool is_bad = !(from->is_young() || to->rem_set()->contains_reference(p) || !G1HRRSFlushLogBuffersOnVerify && // buffers were not flushed (_containing_obj->is_objArray() ? cv_field == dirty : cv_obj == dirty || cv_field == dirty)); if (is_bad) { MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag); if (!_failures) { gclog_or_tty->cr(); gclog_or_tty->print_cr("----------"); } gclog_or_tty->print_cr("Missing rem set entry:"); gclog_or_tty->print_cr("Field "PTR_FORMAT" " "of obj "PTR_FORMAT", " "in region "HR_FORMAT, p, (void*) _containing_obj, HR_FORMAT_PARAMS(from)); _containing_obj->print_on(gclog_or_tty); gclog_or_tty->print_cr("points to obj "PTR_FORMAT" " "in region "HR_FORMAT, (void*) obj, HR_FORMAT_PARAMS(to)); obj->print_on(gclog_or_tty); gclog_or_tty->print_cr("Obj head CTE = %d, field CTE = %d.", cv_obj, cv_field); gclog_or_tty->print_cr("----------"); gclog_or_tty->flush(); _failures = true; if (!failed) _n_failures++; } } } } }