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:
Thomas Schatzl 2018-08-22 20:37:07 +02:00
parent 1b39447545
commit 8e264e259d
20 changed files with 134 additions and 87 deletions

@ -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:");