8208498: Put archive regions into a first-class HeapRegionSet
Summary: Maintain archive regions in a HeapRegionSet like other region types.
Reviewed-by: phh, sangheki
--- a/src/hotspot/share/gc/g1/collectionSetChooser.cpp Wed Aug 22 10:28:34 2018 -0700
+++ b/src/hotspot/share/gc/g1/collectionSetChooser.cpp Wed Aug 22 20:37:07 2018 +0200
@@ -243,7 +243,7 @@
// 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());
}
--- a/src/hotspot/share/gc/g1/g1Allocator.cpp Wed Aug 22 10:28:34 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1Allocator.cpp Wed Aug 22 20:37:07 2018 +0200
@@ -361,7 +361,7 @@
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;
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Wed Aug 22 10:28:34 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Wed Aug 22 20:37:07 2018 +0200
@@ -643,7 +643,7 @@
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 @@
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 @@
_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 @@
#endif // ASSERT
class TearDownRegionSetsClosure : public HeapRegionClosure {
-private:
HeapRegionSet *_old_set;
public:
@@ -4606,9 +4606,9 @@
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 @@
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 @@
_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 @@
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);
}
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Wed Aug 22 10:28:34 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Wed Aug 22 20:37:07 2018 +0200
@@ -169,10 +169,9 @@
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 @@
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 @@
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
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp Wed Aug 22 10:28:34 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp Wed Aug 22 20:37:07 2018 +0200
@@ -92,6 +92,10 @@
_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
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp Wed Aug 22 10:28:34 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp Wed Aug 22 20:37:07 2018 +0200
@@ -52,7 +52,7 @@
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) {
--- a/src/hotspot/share/gc/g1/g1HeapTransition.cpp Wed Aug 22 10:28:34 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1HeapTransition.cpp Wed Aug 22 20:37:07 2018 +0200
@@ -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 @@
_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 @@
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 @@
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 @@
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 @@
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",
--- a/src/hotspot/share/gc/g1/g1HeapTransition.hpp Wed Aug 22 10:28:34 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1HeapTransition.hpp Wed Aug 22 20:37:07 2018 +0200
@@ -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 @@
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;
--- a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp Wed Aug 22 10:28:34 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp Wed Aug 22 20:37:07 2018 +0200
@@ -488,19 +488,22 @@
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 @@
} 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 @@
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 @@
// 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 @@
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);
--- a/src/hotspot/share/gc/g1/g1RemSet.cpp Wed Aug 22 10:28:34 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1RemSet.cpp Wed Aug 22 20:37:07 2018 +0200
@@ -132,7 +132,7 @@
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 @@
// 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 @@
// 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.
--- a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp Wed Aug 22 10:28:34 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp Wed Aug 22 20:37:07 2018 +0200
@@ -226,6 +226,7 @@
RegionTypeCounter _humongous;
RegionTypeCounter _free;
RegionTypeCounter _old;
+ RegionTypeCounter _archive;
RegionTypeCounter _all;
size_t _max_rs_mem_sz;
@@ -248,7 +249,7 @@
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 @@
current = &_humongous;
} else if (r->is_old()) {
current = &_old;
+ } else if (r->is_archive()) {
+ current = &_archive;
} else {
ShouldNotReachHere();
}
@@ -290,7 +293,7 @@
}
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."
--- a/src/hotspot/share/gc/g1/g1RemSetTrackingPolicy.cpp Wed Aug 22 10:28:34 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1RemSetTrackingPolicy.cpp Wed Aug 22 20:37:07 2018 +0200
@@ -141,8 +141,9 @@
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();
--- a/src/hotspot/share/gc/g1/heapRegion.hpp Wed Aug 22 10:28:34 2018 -0700
+++ b/src/hotspot/share/gc/g1/heapRegion.hpp Wed Aug 22 20:37:07 2018 +0200
@@ -426,6 +426,8 @@
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(); }
--- a/src/hotspot/share/gc/g1/heapRegion.inline.hpp Wed Aug 22 10:28:34 2018 -0700
+++ b/src/hotspot/share/gc/g1/heapRegion.inline.hpp Wed Aug 22 20:37:07 2018 +0200
@@ -350,7 +350,7 @@
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
--- a/src/hotspot/share/gc/g1/heapRegionSet.cpp Wed Aug 22 10:28:34 2018 -0700
+++ b/src/hotspot/share/gc/g1/heapRegionSet.cpp Wed Aug 22 20:37:07 2018 +0200
@@ -77,19 +77,17 @@
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 @@
"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.");
+}
--- a/src/hotspot/share/gc/g1/heapRegionSet.hpp Wed Aug 22 10:28:34 2018 -0700
+++ b/src/hotspot/share/gc/g1/heapRegionSet.hpp Wed Aug 22 20:37:07 2018 +0200
@@ -55,6 +55,7 @@
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 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 @@
// 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 @@
}
}
- 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 @@
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 @@
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 @@
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();
}
--- a/src/hotspot/share/gc/g1/heapRegionType.hpp Wed Aug 22 10:28:34 2018 -0700
+++ b/src/hotspot/share/gc/g1/heapRegionType.hpp Wed Aug 22 20:37:07 2018 +0200
@@ -86,8 +86,8 @@
// 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 @@
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; }
--- a/src/hotspot/share/gc/g1/vmStructs_g1.hpp Wed Aug 22 10:28:34 2018 -0700
+++ b/src/hotspot/share/gc/g1/vmStructs_g1.hpp Wed Aug 22 20:37:07 2018 +0200
@@ -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) \
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1CollectedHeap.java Wed Aug 22 10:28:34 2018 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1CollectedHeap.java Wed Aug 22 20:37:07 2018 +0200
@@ -56,6 +56,8 @@
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 @@
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 @@
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,
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Wed Aug 22 10:28:34 2018 -0700
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Wed Aug 22 20:37:07 2018 +0200
@@ -228,8 +228,9 @@
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:");