8208498: Put archive regions into a first-class HeapRegionSet
Maintain archive regions in a HeapRegionSet like other region types. Reviewed-by: phh, sangheki
This commit is contained in:
parent
1b39447545
commit
8e264e259d
src
hotspot/share/gc/g1
collectionSetChooser.cppg1Allocator.cppg1CollectedHeap.cppg1CollectedHeap.hppg1CollectedHeap.inline.hppg1ConcurrentMark.inline.hppg1HeapTransition.cppg1HeapTransition.hppg1HeapVerifier.cppg1RemSet.cppg1RemSetSummary.cppg1RemSetTrackingPolicy.cppheapRegion.hppheapRegion.inline.hppheapRegionSet.cppheapRegionSet.hppheapRegionType.hppvmStructs_g1.hpp
jdk.hotspot.agent/share/classes/sun/jvm/hotspot
@ -243,7 +243,7 @@ public:
|
||||
// sets for old regions.
|
||||
r->rem_set()->clear(true /* only_cardset */);
|
||||
} else {
|
||||
assert(!r->is_old() || !r->rem_set()->is_tracked(),
|
||||
assert(r->is_archive() || !r->is_old() || !r->rem_set()->is_tracked(),
|
||||
"Missed to clear unused remembered set of region %u (%s) that is %s",
|
||||
r->hrm_index(), r->get_type_str(), r->rem_set()->get_state_str());
|
||||
}
|
||||
|
@ -361,7 +361,7 @@ bool G1ArchiveAllocator::alloc_new_region() {
|
||||
hr->set_closed_archive();
|
||||
}
|
||||
_g1h->g1_policy()->remset_tracker()->update_at_allocate(hr);
|
||||
_g1h->old_set_add(hr);
|
||||
_g1h->archive_set_add(hr);
|
||||
_g1h->hr_printer()->alloc(hr);
|
||||
_allocated_regions.append(hr);
|
||||
_allocation_region = hr;
|
||||
|
@ -643,7 +643,7 @@ bool G1CollectedHeap::alloc_archive_regions(MemRegion* ranges,
|
||||
curr_region->set_closed_archive();
|
||||
}
|
||||
_hr_printer.alloc(curr_region);
|
||||
_old_set.add(curr_region);
|
||||
_archive_set.add(curr_region);
|
||||
HeapWord* top;
|
||||
HeapRegion* next_region;
|
||||
if (curr_region != last_region) {
|
||||
@ -800,7 +800,7 @@ void G1CollectedHeap::dealloc_archive_regions(MemRegion* ranges, size_t count) {
|
||||
guarantee(curr_region->is_archive(),
|
||||
"Expected archive region at index %u", curr_region->hrm_index());
|
||||
uint curr_index = curr_region->hrm_index();
|
||||
_old_set.remove(curr_region);
|
||||
_archive_set.remove(curr_region);
|
||||
curr_region->set_free();
|
||||
curr_region->set_top(curr_region->bottom());
|
||||
if (curr_region != last_region) {
|
||||
@ -1417,8 +1417,9 @@ G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* collector_policy) :
|
||||
_eden_pool(NULL),
|
||||
_survivor_pool(NULL),
|
||||
_old_pool(NULL),
|
||||
_old_set("Old Set", false /* humongous */, new OldRegionSetMtSafeChecker()),
|
||||
_humongous_set("Master Humongous Set", true /* humongous */, new HumongousRegionSetMtSafeChecker()),
|
||||
_old_set("Old Region Set", HeapRegionSetBase::ForOldRegions, new OldRegionSetMtSafeChecker()),
|
||||
_archive_set("Archive Region Set", HeapRegionSetBase::ForArchiveRegions, new ArchiveRegionSetMtSafeChecker()),
|
||||
_humongous_set("Humongous Region Set", HeapRegionSetBase::ForHumongousRegions, new HumongousRegionSetMtSafeChecker()),
|
||||
_bot(NULL),
|
||||
_listener(),
|
||||
_hrm(),
|
||||
@ -4593,7 +4594,6 @@ bool G1CollectedHeap::check_young_list_empty() {
|
||||
#endif // ASSERT
|
||||
|
||||
class TearDownRegionSetsClosure : public HeapRegionClosure {
|
||||
private:
|
||||
HeapRegionSet *_old_set;
|
||||
|
||||
public:
|
||||
@ -4606,9 +4606,9 @@ public:
|
||||
r->uninstall_surv_rate_group();
|
||||
} else {
|
||||
// We ignore free regions, we'll empty the free list afterwards.
|
||||
// We ignore humongous regions, we're not tearing down the
|
||||
// humongous regions set.
|
||||
assert(r->is_free() || r->is_humongous(),
|
||||
// We ignore humongous and archive regions, we're not tearing down these
|
||||
// sets.
|
||||
assert(r->is_archive() || r->is_free() || r->is_humongous(),
|
||||
"it cannot be another type");
|
||||
}
|
||||
return false;
|
||||
@ -4651,14 +4651,17 @@ void G1CollectedHeap::set_used(size_t bytes) {
|
||||
|
||||
class RebuildRegionSetsClosure : public HeapRegionClosure {
|
||||
private:
|
||||
bool _free_list_only;
|
||||
HeapRegionSet* _old_set;
|
||||
HeapRegionManager* _hrm;
|
||||
size_t _total_used;
|
||||
bool _free_list_only;
|
||||
|
||||
HeapRegionSet* _old_set;
|
||||
HeapRegionManager* _hrm;
|
||||
|
||||
size_t _total_used;
|
||||
|
||||
public:
|
||||
RebuildRegionSetsClosure(bool free_list_only,
|
||||
HeapRegionSet* old_set, HeapRegionManager* hrm) :
|
||||
HeapRegionSet* old_set,
|
||||
HeapRegionManager* hrm) :
|
||||
_free_list_only(free_list_only),
|
||||
_old_set(old_set), _hrm(hrm), _total_used(0) {
|
||||
assert(_hrm->num_free_regions() == 0, "pre-condition");
|
||||
@ -4676,11 +4679,11 @@ public:
|
||||
_hrm->insert_into_free_list(r);
|
||||
} else if (!_free_list_only) {
|
||||
|
||||
if (r->is_humongous()) {
|
||||
// We ignore humongous regions. We left the humongous set unchanged.
|
||||
if (r->is_archive() || r->is_humongous()) {
|
||||
// We ignore archive and humongous regions. We left these sets unchanged.
|
||||
} else {
|
||||
assert(r->is_young() || r->is_free() || r->is_old(), "invariant");
|
||||
// We now move all (non-humongous, non-old) regions to old gen, and register them as such.
|
||||
// We now move all (non-humongous, non-old, non-archive) regions to old gen, and register them as such.
|
||||
r->move_to_old();
|
||||
_old_set->add(r);
|
||||
}
|
||||
@ -4805,7 +4808,7 @@ void G1CollectedHeap::retire_gc_alloc_region(HeapRegion* alloc_region,
|
||||
alloc_region->note_end_of_copying(during_im);
|
||||
g1_policy()->record_bytes_copied_during_gc(allocated_bytes);
|
||||
if (dest.is_old()) {
|
||||
_old_set.add(alloc_region);
|
||||
old_set_add(alloc_region);
|
||||
}
|
||||
_hr_printer.retire(alloc_region);
|
||||
}
|
||||
|
@ -169,10 +169,9 @@ private:
|
||||
|
||||
static size_t _humongous_object_threshold_in_words;
|
||||
|
||||
// It keeps track of the old regions.
|
||||
// These sets keep track of old, archive and humongous regions respectively.
|
||||
HeapRegionSet _old_set;
|
||||
|
||||
// It keeps track of the humongous regions.
|
||||
HeapRegionSet _archive_set;
|
||||
HeapRegionSet _humongous_set;
|
||||
|
||||
virtual void initialize_serviceability();
|
||||
@ -1046,8 +1045,10 @@ public:
|
||||
inline void old_set_add(HeapRegion* hr);
|
||||
inline void old_set_remove(HeapRegion* hr);
|
||||
|
||||
inline void archive_set_add(HeapRegion* hr);
|
||||
|
||||
size_t non_young_capacity_bytes() {
|
||||
return (_old_set.length() + _humongous_set.length()) * HeapRegion::GrainBytes;
|
||||
return (old_regions_count() + _archive_set.length() + humongous_regions_count()) * HeapRegion::GrainBytes;
|
||||
}
|
||||
|
||||
// Determine whether the given region is one that we are using as an
|
||||
@ -1232,20 +1233,11 @@ public:
|
||||
|
||||
const G1SurvivorRegions* survivor() const { return &_survivor; }
|
||||
|
||||
uint survivor_regions_count() const {
|
||||
return _survivor.length();
|
||||
}
|
||||
|
||||
uint eden_regions_count() const {
|
||||
return _eden.length();
|
||||
}
|
||||
|
||||
uint young_regions_count() const {
|
||||
return _eden.length() + _survivor.length();
|
||||
}
|
||||
|
||||
uint eden_regions_count() const { return _eden.length(); }
|
||||
uint survivor_regions_count() const { return _survivor.length(); }
|
||||
uint young_regions_count() const { return _eden.length() + _survivor.length(); }
|
||||
uint old_regions_count() const { return _old_set.length(); }
|
||||
|
||||
uint archive_regions_count() const { return _archive_set.length(); }
|
||||
uint humongous_regions_count() const { return _humongous_set.length(); }
|
||||
|
||||
#ifdef ASSERT
|
||||
|
@ -92,6 +92,10 @@ inline void G1CollectedHeap::old_set_remove(HeapRegion* hr) {
|
||||
_old_set.remove(hr);
|
||||
}
|
||||
|
||||
inline void G1CollectedHeap::archive_set_add(HeapRegion* hr) {
|
||||
_archive_set.add(hr);
|
||||
}
|
||||
|
||||
// It dirties the cards that cover the block so that the post
|
||||
// write barrier never queues anything when updating objects on this
|
||||
// block. It is assumed (and in fact we assert) that the block
|
||||
|
@ -52,7 +52,7 @@ inline bool G1CMSubjectToDiscoveryClosure::do_object_b(oop obj) {
|
||||
return false;
|
||||
}
|
||||
assert(_g1h->is_in_reserved(obj), "Trying to discover obj " PTR_FORMAT " not in heap", p2i(obj));
|
||||
return _g1h->heap_region_containing(obj)->is_old_or_humongous();
|
||||
return _g1h->heap_region_containing(obj)->is_old_or_humongous_or_archive();
|
||||
}
|
||||
|
||||
inline bool G1ConcurrentMark::mark_in_next_bitmap(uint const worker_id, oop const obj, size_t const obj_size) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -33,6 +33,7 @@ G1HeapTransition::Data::Data(G1CollectedHeap* g1_heap) {
|
||||
_eden_length = g1_heap->eden_regions_count();
|
||||
_survivor_length = g1_heap->survivor_regions_count();
|
||||
_old_length = g1_heap->old_regions_count();
|
||||
_archive_length = g1_heap->archive_regions_count();
|
||||
_humongous_length = g1_heap->humongous_regions_count();
|
||||
_metaspace_used_bytes = MetaspaceUtils::used_bytes();
|
||||
}
|
||||
@ -43,16 +44,19 @@ struct DetailedUsage : public StackObj {
|
||||
size_t _eden_used;
|
||||
size_t _survivor_used;
|
||||
size_t _old_used;
|
||||
size_t _archive_used;
|
||||
size_t _humongous_used;
|
||||
|
||||
size_t _eden_region_count;
|
||||
size_t _survivor_region_count;
|
||||
size_t _old_region_count;
|
||||
size_t _archive_region_count;
|
||||
size_t _humongous_region_count;
|
||||
|
||||
DetailedUsage() :
|
||||
_eden_used(0), _survivor_used(0), _old_used(0), _humongous_used(0),
|
||||
_eden_region_count(0), _survivor_region_count(0), _old_region_count(0), _humongous_region_count(0) {}
|
||||
_eden_used(0), _survivor_used(0), _old_used(0), _archive_used(0), _humongous_used(0),
|
||||
_eden_region_count(0), _survivor_region_count(0), _old_region_count(0),
|
||||
_archive_region_count(0), _humongous_region_count(0) {}
|
||||
};
|
||||
|
||||
class DetailedUsageClosure: public HeapRegionClosure {
|
||||
@ -62,6 +66,9 @@ public:
|
||||
if (r->is_old()) {
|
||||
_usage._old_used += r->used();
|
||||
_usage._old_region_count++;
|
||||
} else if (r->is_archive()) {
|
||||
_usage._archive_used += r->used();
|
||||
_usage._archive_region_count++;
|
||||
} else if (r->is_survivor()) {
|
||||
_usage._survivor_used += r->used();
|
||||
_usage._survivor_region_count++;
|
||||
@ -94,6 +101,8 @@ void G1HeapTransition::print() {
|
||||
after._survivor_length, usage._survivor_region_count);
|
||||
assert(usage._old_region_count == after._old_length, "Expected old to be " SIZE_FORMAT " but was " SIZE_FORMAT,
|
||||
after._old_length, usage._old_region_count);
|
||||
assert(usage._archive_region_count == after._archive_length, "Expected archive to be " SIZE_FORMAT " but was " SIZE_FORMAT,
|
||||
after._archive_length, usage._archive_region_count);
|
||||
assert(usage._humongous_region_count == after._humongous_length, "Expected humongous to be " SIZE_FORMAT " but was " SIZE_FORMAT,
|
||||
after._humongous_length, usage._humongous_region_count);
|
||||
}
|
||||
@ -112,6 +121,11 @@ void G1HeapTransition::print() {
|
||||
log_trace(gc, heap)(" Used: " SIZE_FORMAT "K, Waste: " SIZE_FORMAT "K",
|
||||
usage._old_used / K, ((after._old_length * HeapRegion::GrainBytes) - usage._old_used) / K);
|
||||
|
||||
log_info(gc, heap)("Archive regions: " SIZE_FORMAT "->" SIZE_FORMAT,
|
||||
_before._archive_length, after._archive_length);
|
||||
log_trace(gc, heap)(" Used: " SIZE_FORMAT "K, Waste: " SIZE_FORMAT "K",
|
||||
usage._archive_used / K, ((after._archive_length * HeapRegion::GrainBytes) - usage._archive_used) / K);
|
||||
|
||||
log_info(gc, heap)("Humongous regions: " SIZE_FORMAT "->" SIZE_FORMAT,
|
||||
_before._humongous_length, after._humongous_length);
|
||||
log_trace(gc, heap)(" Used: " SIZE_FORMAT "K, Waste: " SIZE_FORMAT "K",
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -34,6 +34,7 @@ class G1HeapTransition {
|
||||
size_t _eden_length;
|
||||
size_t _survivor_length;
|
||||
size_t _old_length;
|
||||
size_t _archive_length;
|
||||
size_t _humongous_length;
|
||||
size_t _metaspace_used_bytes;
|
||||
|
||||
|
@ -488,19 +488,22 @@ void G1HeapVerifier::verify(VerifyOption vo) {
|
||||
class VerifyRegionListsClosure : public HeapRegionClosure {
|
||||
private:
|
||||
HeapRegionSet* _old_set;
|
||||
HeapRegionSet* _archive_set;
|
||||
HeapRegionSet* _humongous_set;
|
||||
HeapRegionManager* _hrm;
|
||||
HeapRegionManager* _hrm;
|
||||
|
||||
public:
|
||||
uint _old_count;
|
||||
uint _archive_count;
|
||||
uint _humongous_count;
|
||||
uint _free_count;
|
||||
|
||||
VerifyRegionListsClosure(HeapRegionSet* old_set,
|
||||
HeapRegionSet* archive_set,
|
||||
HeapRegionSet* humongous_set,
|
||||
HeapRegionManager* hrm) :
|
||||
_old_set(old_set), _humongous_set(humongous_set), _hrm(hrm),
|
||||
_old_count(), _humongous_count(), _free_count(){ }
|
||||
_old_set(old_set), _archive_set(archive_set), _humongous_set(humongous_set), _hrm(hrm),
|
||||
_old_count(), _archive_count(), _humongous_count(), _free_count(){ }
|
||||
|
||||
bool do_heap_region(HeapRegion* hr) {
|
||||
if (hr->is_young()) {
|
||||
@ -511,6 +514,9 @@ public:
|
||||
} else if (hr->is_empty()) {
|
||||
assert(_hrm->is_free(hr), "Heap region %u is empty but not on the free list.", hr->hrm_index());
|
||||
_free_count++;
|
||||
} else if (hr->is_archive()) {
|
||||
assert(hr->containing_set() == _archive_set, "Heap region %u is archive but not in the archive set.", hr->hrm_index());
|
||||
_archive_count++;
|
||||
} else if (hr->is_old()) {
|
||||
assert(hr->containing_set() == _old_set, "Heap region %u is old but not in the old set.", hr->hrm_index());
|
||||
_old_count++;
|
||||
@ -523,8 +529,9 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
void verify_counts(HeapRegionSet* old_set, HeapRegionSet* humongous_set, HeapRegionManager* free_list) {
|
||||
void verify_counts(HeapRegionSet* old_set, HeapRegionSet* archive_set, HeapRegionSet* humongous_set, HeapRegionManager* free_list) {
|
||||
guarantee(old_set->length() == _old_count, "Old set count mismatch. Expected %u, actual %u.", old_set->length(), _old_count);
|
||||
guarantee(archive_set->length() == _archive_count, "Archive set count mismatch. Expected %u, actual %u.", archive_set->length(), _archive_count);
|
||||
guarantee(humongous_set->length() == _humongous_count, "Hum set count mismatch. Expected %u, actual %u.", humongous_set->length(), _humongous_count);
|
||||
guarantee(free_list->num_free_regions() == _free_count, "Free list count mismatch. Expected %u, actual %u.", free_list->num_free_regions(), _free_count);
|
||||
}
|
||||
@ -539,9 +546,9 @@ void G1HeapVerifier::verify_region_sets() {
|
||||
// Finally, make sure that the region accounting in the lists is
|
||||
// consistent with what we see in the heap.
|
||||
|
||||
VerifyRegionListsClosure cl(&_g1h->_old_set, &_g1h->_humongous_set, &_g1h->_hrm);
|
||||
VerifyRegionListsClosure cl(&_g1h->_old_set, &_g1h->_archive_set, &_g1h->_humongous_set, &_g1h->_hrm);
|
||||
_g1h->heap_region_iterate(&cl);
|
||||
cl.verify_counts(&_g1h->_old_set, &_g1h->_humongous_set, &_g1h->_hrm);
|
||||
cl.verify_counts(&_g1h->_old_set, &_g1h->_archive_set, &_g1h->_humongous_set, &_g1h->_hrm);
|
||||
}
|
||||
|
||||
void G1HeapVerifier::prepare_for_verify() {
|
||||
@ -755,6 +762,11 @@ class G1CheckCSetFastTableClosure : public HeapRegionClosure {
|
||||
return true;
|
||||
}
|
||||
if (cset_state.is_in_cset()) {
|
||||
if (hr->is_archive()) {
|
||||
log_error(gc, verify)("## is_archive in collection set for region %u", i);
|
||||
_failures = true;
|
||||
return true;
|
||||
}
|
||||
if (hr->is_young() != (cset_state.is_young())) {
|
||||
log_error(gc, verify)("## is_young %d / cset state " CSETSTATE_FORMAT " inconsistency for region %u",
|
||||
hr->is_young(), cset_state.value(), i);
|
||||
|
@ -132,7 +132,7 @@ private:
|
||||
|
||||
virtual bool do_heap_region(HeapRegion* r) {
|
||||
uint hrm_index = r->hrm_index();
|
||||
if (!r->in_collection_set() && r->is_old_or_humongous()) {
|
||||
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();
|
||||
@ -571,7 +571,7 @@ void G1RemSet::refine_card_concurrently(jbyte* card_ptr,
|
||||
// In the normal (non-stale) case, the synchronization between the
|
||||
// enqueueing of the card and processing it here will have ensured
|
||||
// we see the up-to-date region type here.
|
||||
if (!r->is_old_or_humongous()) {
|
||||
if (!r->is_old_or_humongous_or_archive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -600,7 +600,7 @@ void G1RemSet::refine_card_concurrently(jbyte* card_ptr,
|
||||
// Check whether the region formerly in the cache should be
|
||||
// ignored, as discussed earlier for the original card. The
|
||||
// region could have been freed while in the cache.
|
||||
if (!r->is_old_or_humongous()) {
|
||||
if (!r->is_old_or_humongous_or_archive()) {
|
||||
return;
|
||||
}
|
||||
} // Else we still have the original card.
|
||||
|
@ -226,6 +226,7 @@ private:
|
||||
RegionTypeCounter _humongous;
|
||||
RegionTypeCounter _free;
|
||||
RegionTypeCounter _old;
|
||||
RegionTypeCounter _archive;
|
||||
RegionTypeCounter _all;
|
||||
|
||||
size_t _max_rs_mem_sz;
|
||||
@ -248,7 +249,7 @@ private:
|
||||
|
||||
public:
|
||||
HRRSStatsIter() : _young("Young"), _humongous("Humongous"),
|
||||
_free("Free"), _old("Old"), _all("All"),
|
||||
_free("Free"), _old("Old"), _archive("Archive"), _all("All"),
|
||||
_max_rs_mem_sz(0), _max_rs_mem_sz_region(NULL),
|
||||
_max_code_root_mem_sz(0), _max_code_root_mem_sz_region(NULL)
|
||||
{}
|
||||
@ -280,6 +281,8 @@ public:
|
||||
current = &_humongous;
|
||||
} else if (r->is_old()) {
|
||||
current = &_old;
|
||||
} else if (r->is_archive()) {
|
||||
current = &_archive;
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
@ -290,7 +293,7 @@ public:
|
||||
}
|
||||
|
||||
void print_summary_on(outputStream* out) {
|
||||
RegionTypeCounter* counters[] = { &_young, &_humongous, &_free, &_old, NULL };
|
||||
RegionTypeCounter* counters[] = { &_young, &_humongous, &_free, &_old, &_archive, NULL };
|
||||
|
||||
out->print_cr(" Current rem set statistics");
|
||||
out->print_cr(" Total per region rem sets sizes = " SIZE_FORMAT "%s."
|
||||
|
@ -141,8 +141,9 @@ bool G1RemSetTrackingPolicy::update_before_rebuild(HeapRegion* r, size_t live_by
|
||||
void G1RemSetTrackingPolicy::update_after_rebuild(HeapRegion* r) {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
|
||||
|
||||
if (r->is_old_or_humongous()) {
|
||||
if (r->is_old_or_humongous_or_archive()) {
|
||||
if (r->rem_set()->is_updating()) {
|
||||
assert(!r->is_archive(), "Archive region %u with remembered set", r->hrm_index());
|
||||
r->rem_set()->set_state_complete();
|
||||
}
|
||||
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
||||
|
@ -426,6 +426,8 @@ class HeapRegion: public G1ContiguousSpace {
|
||||
|
||||
bool is_old_or_humongous() const { return _type.is_old_or_humongous(); }
|
||||
|
||||
bool is_old_or_humongous_or_archive() const { return _type.is_old_or_humongous_or_archive(); }
|
||||
|
||||
// A pinned region contains objects which are not moved by garbage collections.
|
||||
// Humongous regions and archive regions are pinned.
|
||||
bool is_pinned() const { return _type.is_pinned(); }
|
||||
|
@ -350,7 +350,7 @@ bool HeapRegion::oops_on_card_seq_iterate_careful(MemRegion mr,
|
||||
if (is_humongous()) {
|
||||
return do_oops_on_card_in_humongous<Closure, is_gc_active>(mr, cl, g1h);
|
||||
}
|
||||
assert(is_old(), "precondition");
|
||||
assert(is_old() || is_archive(), "Wrongly trying to iterate over region %u type %s", _hrm_index, get_type_str());
|
||||
|
||||
// Because mr has been trimmed to what's been allocated in this
|
||||
// region, the parts of the heap that are examined here are always
|
||||
|
@ -77,19 +77,17 @@ void HeapRegionSetBase::print_on(outputStream* out, bool print_contents) {
|
||||
out->print_cr("Set: %s (" PTR_FORMAT ")", name(), p2i(this));
|
||||
out->print_cr(" Region Assumptions");
|
||||
out->print_cr(" humongous : %s", BOOL_TO_STR(regions_humongous()));
|
||||
out->print_cr(" archive : %s", BOOL_TO_STR(regions_archive()));
|
||||
out->print_cr(" free : %s", BOOL_TO_STR(regions_free()));
|
||||
out->print_cr(" Attributes");
|
||||
out->print_cr(" length : %14u", length());
|
||||
}
|
||||
|
||||
HeapRegionSetBase::HeapRegionSetBase(const char* name, bool humongous, bool free, HRSMtSafeChecker* mt_safety_checker)
|
||||
: _is_humongous(humongous),
|
||||
_is_free(free),
|
||||
_mt_safety_checker(mt_safety_checker),
|
||||
_length(0),
|
||||
_name(name),
|
||||
_verify_in_progress(false)
|
||||
{ }
|
||||
HeapRegionSetBase::HeapRegionSetBase(const char* name, RegionSetKind kind, HRSMtSafeChecker* mt_safety_checker)
|
||||
: _region_kind(kind), _mt_safety_checker(mt_safety_checker), _length(0), _name(name), _verify_in_progress(false)
|
||||
{
|
||||
assert(kind >= ForOldRegions && kind <= ForFreeRegions, "Invalid heap region set kind %d.", kind);
|
||||
}
|
||||
|
||||
void FreeRegionList::set_unrealistically_long_length(uint len) {
|
||||
guarantee(_unrealistically_long_length == 0, "should only be set once");
|
||||
@ -365,3 +363,8 @@ void HumongousRegionSetMtSafeChecker::check() {
|
||||
"master humongous set MT safety protocol outside a safepoint");
|
||||
}
|
||||
}
|
||||
|
||||
void ArchiveRegionSetMtSafeChecker::check() {
|
||||
guarantee(!Universe::is_fully_initialized() || SafepointSynchronize::is_at_safepoint(),
|
||||
"May only change archive regions during initialization or safepoint.");
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ public:
|
||||
class MasterFreeRegionListMtSafeChecker : public HRSMtSafeChecker { public: void check(); };
|
||||
class HumongousRegionSetMtSafeChecker : public HRSMtSafeChecker { public: void check(); };
|
||||
class OldRegionSetMtSafeChecker : public HRSMtSafeChecker { public: void check(); };
|
||||
class ArchiveRegionSetMtSafeChecker : public HRSMtSafeChecker { public: void check(); };
|
||||
|
||||
// Base class for all the classes that represent heap region sets. It
|
||||
// contains the basic attributes that each set needs to maintain
|
||||
@ -63,9 +64,16 @@ class OldRegionSetMtSafeChecker : public HRSMtSafeChecker { public: v
|
||||
|
||||
class HeapRegionSetBase {
|
||||
friend class VMStructs;
|
||||
public:
|
||||
enum RegionSetKind {
|
||||
ForOldRegions,
|
||||
ForHumongousRegions,
|
||||
ForArchiveRegions,
|
||||
ForFreeRegions
|
||||
};
|
||||
|
||||
private:
|
||||
bool _is_humongous;
|
||||
bool _is_free;
|
||||
RegionSetKind _region_kind;
|
||||
HRSMtSafeChecker* _mt_safety_checker;
|
||||
|
||||
protected:
|
||||
@ -80,13 +88,11 @@ protected:
|
||||
// added to / removed from a set are consistent.
|
||||
void verify_region(HeapRegion* hr) PRODUCT_RETURN;
|
||||
|
||||
// Indicates whether all regions in the set should be humongous or
|
||||
// not. Only used during verification.
|
||||
bool regions_humongous() { return _is_humongous; }
|
||||
|
||||
// Indicates whether all regions in the set should be free or
|
||||
// not. Only used during verification.
|
||||
bool regions_free() { return _is_free; }
|
||||
// Indicates whether all regions in the set should be of a given particular type.
|
||||
// Only used for verification.
|
||||
bool regions_humongous() const { return _region_kind == ForHumongousRegions; }
|
||||
bool regions_archive() const { return _region_kind == ForArchiveRegions; }
|
||||
bool regions_free() const { return _region_kind == ForFreeRegions; }
|
||||
|
||||
void check_mt_safety() {
|
||||
if (_mt_safety_checker != NULL) {
|
||||
@ -94,7 +100,7 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
HeapRegionSetBase(const char* name, bool humongous, bool free, HRSMtSafeChecker* mt_safety_checker);
|
||||
HeapRegionSetBase(const char* name, RegionSetKind kind, HRSMtSafeChecker* mt_safety_checker);
|
||||
|
||||
public:
|
||||
const char* name() { return _name; }
|
||||
@ -121,15 +127,6 @@ public:
|
||||
virtual void print_on(outputStream* out, bool print_contents = false);
|
||||
};
|
||||
|
||||
#define hrs_assert_sets_match(_set1_, _set2_) \
|
||||
do { \
|
||||
assert(((_set1_)->regions_humongous() == (_set2_)->regions_humongous()) && \
|
||||
((_set1_)->regions_free() == (_set2_)->regions_free()), \
|
||||
"the contents of set %s and set %s should match", \
|
||||
(_set1_)->name(), \
|
||||
(_set2_)->name()); \
|
||||
} while (0)
|
||||
|
||||
// This class represents heap region sets whose members are not
|
||||
// explicitly tracked. It's helpful to group regions using such sets
|
||||
// so that we can reason about all the region groups in the heap using
|
||||
@ -137,8 +134,10 @@ public:
|
||||
|
||||
class HeapRegionSet : public HeapRegionSetBase {
|
||||
public:
|
||||
HeapRegionSet(const char* name, bool humongous, HRSMtSafeChecker* mt_safety_checker):
|
||||
HeapRegionSetBase(name, humongous, false /* free */, mt_safety_checker) { }
|
||||
HeapRegionSet(const char* name, RegionSetKind kind, HRSMtSafeChecker* mt_safety_checker):
|
||||
HeapRegionSetBase(name, kind, mt_safety_checker) {
|
||||
assert(kind != ForFreeRegions, "Must not call this constructor for Free regions.");
|
||||
}
|
||||
|
||||
void bulk_remove(const uint removed) {
|
||||
_length -= removed;
|
||||
@ -174,7 +173,7 @@ protected:
|
||||
|
||||
public:
|
||||
FreeRegionList(const char* name, HRSMtSafeChecker* mt_safety_checker = NULL):
|
||||
HeapRegionSetBase(name, false /* humongous */, true /* empty */, mt_safety_checker) {
|
||||
HeapRegionSetBase(name, ForFreeRegions, mt_safety_checker) {
|
||||
clear();
|
||||
}
|
||||
|
||||
|
@ -86,8 +86,8 @@ private:
|
||||
// Objects within these regions are allowed to have references to objects
|
||||
// contained in any other kind of regions.
|
||||
ArchiveMask = 32,
|
||||
OpenArchiveTag = ArchiveMask | PinnedMask | OldMask,
|
||||
ClosedArchiveTag = ArchiveMask | PinnedMask | OldMask + 1
|
||||
OpenArchiveTag = ArchiveMask | PinnedMask,
|
||||
ClosedArchiveTag = ArchiveMask | PinnedMask + 1
|
||||
} Tag;
|
||||
|
||||
volatile Tag _tag;
|
||||
@ -139,6 +139,8 @@ public:
|
||||
|
||||
bool is_old_or_humongous() const { return (get() & (OldMask | HumongousMask)) != 0; }
|
||||
|
||||
bool is_old_or_humongous_or_archive() const { return (get() & (OldMask | HumongousMask | ArchiveMask)) != 0; }
|
||||
|
||||
// is_pinned regions may be archive or humongous
|
||||
bool is_pinned() const { return (get() & PinnedMask) != 0; }
|
||||
|
||||
|
@ -56,6 +56,7 @@
|
||||
nonstatic_field(G1CollectedHeap, _hrm, HeapRegionManager) \
|
||||
nonstatic_field(G1CollectedHeap, _g1mm, G1MonitoringSupport*) \
|
||||
nonstatic_field(G1CollectedHeap, _old_set, HeapRegionSetBase) \
|
||||
nonstatic_field(G1CollectedHeap, _archive_set, HeapRegionSetBase) \
|
||||
nonstatic_field(G1CollectedHeap, _humongous_set, HeapRegionSetBase) \
|
||||
\
|
||||
nonstatic_field(G1MonitoringSupport, _eden_committed, size_t) \
|
||||
|
@ -56,6 +56,8 @@ public class G1CollectedHeap extends CollectedHeap {
|
||||
static private AddressField g1mmField;
|
||||
// HeapRegionSet _old_set;
|
||||
static private long oldSetFieldOffset;
|
||||
// HeapRegionSet _archive_set;
|
||||
static private long archiveSetFieldOffset;
|
||||
// HeapRegionSet _humongous_set;
|
||||
static private long humongousSetFieldOffset;
|
||||
|
||||
@ -74,6 +76,7 @@ public class G1CollectedHeap extends CollectedHeap {
|
||||
summaryBytesUsedField = type.getCIntegerField("_summary_bytes_used");
|
||||
g1mmField = type.getAddressField("_g1mm");
|
||||
oldSetFieldOffset = type.getField("_old_set").getOffset();
|
||||
archiveSetFieldOffset = type.getField("_archive_set").getOffset();
|
||||
humongousSetFieldOffset = type.getField("_humongous_set").getOffset();
|
||||
}
|
||||
|
||||
@ -106,6 +109,12 @@ public class G1CollectedHeap extends CollectedHeap {
|
||||
oldSetAddr);
|
||||
}
|
||||
|
||||
public HeapRegionSetBase archiveSet() {
|
||||
Address archiveSetAddr = addr.addOffsetTo(archiveSetFieldOffset);
|
||||
return (HeapRegionSetBase) VMObjectFactory.newObject(HeapRegionSetBase.class,
|
||||
archiveSetAddr);
|
||||
}
|
||||
|
||||
public HeapRegionSetBase humongousSet() {
|
||||
Address humongousSetAddr = addr.addOffsetTo(humongousSetFieldOffset);
|
||||
return (HeapRegionSetBase) VMObjectFactory.newObject(HeapRegionSetBase.class,
|
||||
|
@ -228,8 +228,9 @@ public class HeapSummary extends Tool {
|
||||
long edenRegionNum = g1mm.edenRegionNum();
|
||||
long survivorRegionNum = g1mm.survivorRegionNum();
|
||||
HeapRegionSetBase oldSet = g1h.oldSet();
|
||||
HeapRegionSetBase archiveSet = g1h.archiveSet();
|
||||
HeapRegionSetBase humongousSet = g1h.humongousSet();
|
||||
long oldRegionNum = oldSet.length() + humongousSet.length();
|
||||
long oldRegionNum = oldSet.length() + archiveSet.length() + humongousSet.length();
|
||||
printG1Space("G1 Heap:", g1h.n_regions(),
|
||||
g1h.used(), g1h.capacity());
|
||||
System.out.println("G1 Young Generation:");
|
||||
|
Loading…
x
Reference in New Issue
Block a user