8057768: Make heap region region type in G1 HeapRegion explicit
Reviewed-by: brutisso, tschatzl
This commit is contained in:
parent
debb101f7b
commit
a2984b6c88
@ -4737,7 +4737,7 @@ void G1PrintRegionLivenessInfoClosure::get_hum_bytes(size_t* used_bytes,
|
||||
}
|
||||
|
||||
bool G1PrintRegionLivenessInfoClosure::doHeapRegion(HeapRegion* r) {
|
||||
const char* type = "";
|
||||
const char* type = r->get_type_str();
|
||||
HeapWord* bottom = r->bottom();
|
||||
HeapWord* end = r->end();
|
||||
size_t capacity_bytes = r->capacity();
|
||||
@ -4748,15 +4748,7 @@ bool G1PrintRegionLivenessInfoClosure::doHeapRegion(HeapRegion* r) {
|
||||
size_t remset_bytes = r->rem_set()->mem_size();
|
||||
size_t strong_code_roots_bytes = r->rem_set()->strong_code_roots_mem_size();
|
||||
|
||||
if (r->used() == 0) {
|
||||
type = "FREE";
|
||||
} else if (r->is_survivor()) {
|
||||
type = "SURV";
|
||||
} else if (r->is_young()) {
|
||||
type = "EDEN";
|
||||
} else if (r->startsHumongous()) {
|
||||
type = "HUMS";
|
||||
|
||||
if (r->startsHumongous()) {
|
||||
assert(_hum_used_bytes == 0 && _hum_capacity_bytes == 0 &&
|
||||
_hum_prev_live_bytes == 0 && _hum_next_live_bytes == 0,
|
||||
"they should have been zeroed after the last time we used them");
|
||||
@ -4769,12 +4761,9 @@ bool G1PrintRegionLivenessInfoClosure::doHeapRegion(HeapRegion* r) {
|
||||
&prev_live_bytes, &next_live_bytes);
|
||||
end = bottom + HeapRegion::GrainWords;
|
||||
} else if (r->continuesHumongous()) {
|
||||
type = "HUMC";
|
||||
get_hum_bytes(&used_bytes, &capacity_bytes,
|
||||
&prev_live_bytes, &next_live_bytes);
|
||||
assert(end == bottom + HeapRegion::GrainWords, "invariant");
|
||||
} else {
|
||||
type = "OLD";
|
||||
}
|
||||
|
||||
_total_used_bytes += used_bytes;
|
||||
|
@ -211,7 +211,10 @@ void YoungList::empty_list(HeapRegion* list) {
|
||||
HeapRegion* next = list->get_next_young_region();
|
||||
list->set_next_young_region(NULL);
|
||||
list->uninstall_surv_rate_group();
|
||||
list->set_not_young();
|
||||
// This is called before a Full GC and all the non-empty /
|
||||
// non-humongous regions at the end of the Full GC will end up as
|
||||
// old anyway.
|
||||
list->set_old();
|
||||
list = next;
|
||||
}
|
||||
}
|
||||
@ -370,7 +373,7 @@ void YoungList::print() {
|
||||
if (curr == NULL)
|
||||
gclog_or_tty->print_cr(" empty");
|
||||
while (curr != NULL) {
|
||||
gclog_or_tty->print_cr(" "HR_FORMAT", P: "PTR_FORMAT "N: "PTR_FORMAT", age: %4d",
|
||||
gclog_or_tty->print_cr(" "HR_FORMAT", P: "PTR_FORMAT ", N: "PTR_FORMAT", age: %4d",
|
||||
HR_FORMAT_PARAMS(curr),
|
||||
curr->prev_top_at_mark_start(),
|
||||
curr->next_top_at_mark_start(),
|
||||
@ -802,6 +805,7 @@ HeapWord* G1CollectedHeap::humongous_obj_allocate(size_t word_size) {
|
||||
#ifdef ASSERT
|
||||
for (uint i = first; i < first + obj_regions; ++i) {
|
||||
HeapRegion* hr = region_at(i);
|
||||
assert(hr->is_free(), "sanity");
|
||||
assert(hr->is_empty(), "sanity");
|
||||
assert(is_on_master_free_list(hr), "sanity");
|
||||
}
|
||||
@ -1225,21 +1229,21 @@ private:
|
||||
public:
|
||||
bool doHeapRegion(HeapRegion* hr) {
|
||||
assert(!hr->is_young(), "not expecting to find young regions");
|
||||
// We only generate output for non-empty regions.
|
||||
if (!hr->is_empty()) {
|
||||
if (!hr->isHumongous()) {
|
||||
_hr_printer->post_compaction(hr, G1HRPrinter::Old);
|
||||
} else if (hr->startsHumongous()) {
|
||||
if (hr->region_num() == 1) {
|
||||
// single humongous region
|
||||
_hr_printer->post_compaction(hr, G1HRPrinter::SingleHumongous);
|
||||
} else {
|
||||
_hr_printer->post_compaction(hr, G1HRPrinter::StartsHumongous);
|
||||
}
|
||||
if (hr->is_free()) {
|
||||
// We only generate output for non-empty regions.
|
||||
} else if (hr->startsHumongous()) {
|
||||
if (hr->region_num() == 1) {
|
||||
// single humongous region
|
||||
_hr_printer->post_compaction(hr, G1HRPrinter::SingleHumongous);
|
||||
} else {
|
||||
assert(hr->continuesHumongous(), "only way to get here");
|
||||
_hr_printer->post_compaction(hr, G1HRPrinter::ContinuesHumongous);
|
||||
_hr_printer->post_compaction(hr, G1HRPrinter::StartsHumongous);
|
||||
}
|
||||
} else if (hr->continuesHumongous()) {
|
||||
_hr_printer->post_compaction(hr, G1HRPrinter::ContinuesHumongous);
|
||||
} else if (hr->is_old()) {
|
||||
_hr_printer->post_compaction(hr, G1HRPrinter::Old);
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -2121,8 +2125,8 @@ jint G1CollectedHeap::initialize() {
|
||||
// We'll re-use the same region whether the alloc region will
|
||||
// require BOT updates or not and, if it doesn't, then a non-young
|
||||
// region will complain that it cannot support allocations without
|
||||
// BOT updates. So we'll tag the dummy region as young to avoid that.
|
||||
dummy_region->set_young();
|
||||
// BOT updates. So we'll tag the dummy region as eden to avoid that.
|
||||
dummy_region->set_eden();
|
||||
// Make sure it's full.
|
||||
dummy_region->set_top(dummy_region->end());
|
||||
G1AllocRegion::setup(this, dummy_region);
|
||||
@ -4031,14 +4035,6 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
|
||||
if (_hr_printer.is_active()) {
|
||||
HeapRegion* hr = g1_policy()->collection_set();
|
||||
while (hr != NULL) {
|
||||
G1HRPrinter::RegionType type;
|
||||
if (!hr->is_young()) {
|
||||
type = G1HRPrinter::Old;
|
||||
} else if (hr->is_survivor()) {
|
||||
type = G1HRPrinter::Survivor;
|
||||
} else {
|
||||
type = G1HRPrinter::Eden;
|
||||
}
|
||||
_hr_printer.cset(hr);
|
||||
hr = hr->next_in_collection_set();
|
||||
}
|
||||
@ -6063,7 +6059,7 @@ void G1CollectedHeap::free_region(HeapRegion* hr,
|
||||
FreeRegionList* free_list,
|
||||
bool par,
|
||||
bool locked) {
|
||||
assert(!hr->isHumongous(), "this is only for non-humongous regions");
|
||||
assert(!hr->is_free(), "the region should not be free");
|
||||
assert(!hr->is_empty(), "the region should not be empty");
|
||||
assert(_hrm.is_available(hr->hrm_index()), "region should be committed");
|
||||
assert(free_list != NULL, "pre-condition");
|
||||
@ -6093,14 +6089,14 @@ void G1CollectedHeap::free_humongous_region(HeapRegion* hr,
|
||||
// We need to read this before we make the region non-humongous,
|
||||
// otherwise the information will be gone.
|
||||
uint last_index = hr->last_hc_index();
|
||||
hr->set_notHumongous();
|
||||
hr->clear_humongous();
|
||||
free_region(hr, free_list, par);
|
||||
|
||||
uint i = hr->hrm_index() + 1;
|
||||
while (i < last_index) {
|
||||
HeapRegion* curr_hr = region_at(i);
|
||||
assert(curr_hr->continuesHumongous(), "invariant");
|
||||
curr_hr->set_notHumongous();
|
||||
curr_hr->clear_humongous();
|
||||
free_region(curr_hr, free_list, par);
|
||||
i += 1;
|
||||
}
|
||||
@ -6408,9 +6404,9 @@ void G1CollectedHeap::free_collection_set(HeapRegion* cs_head, EvacuationInfo& e
|
||||
if (cur->is_young()) {
|
||||
cur->set_young_index_in_cset(-1);
|
||||
}
|
||||
cur->set_not_young();
|
||||
cur->set_evacuation_failed(false);
|
||||
// The region is now considered to be old.
|
||||
cur->set_old();
|
||||
_old_set.add(cur);
|
||||
evacuation_info.increment_collectionset_used_after(cur->used());
|
||||
}
|
||||
@ -6697,16 +6693,15 @@ public:
|
||||
TearDownRegionSetsClosure(HeapRegionSet* old_set) : _old_set(old_set) { }
|
||||
|
||||
bool doHeapRegion(HeapRegion* r) {
|
||||
if (r->is_empty()) {
|
||||
// We ignore empty regions, we'll empty the free list afterwards
|
||||
} else if (r->is_young()) {
|
||||
// We ignore young regions, we'll empty the young list afterwards
|
||||
} else if (r->isHumongous()) {
|
||||
// We ignore humongous regions, we're not tearing down the
|
||||
// humongous region set
|
||||
} else {
|
||||
// The rest should be old
|
||||
if (r->is_old()) {
|
||||
_old_set->remove(r);
|
||||
} else {
|
||||
// We ignore free regions, we'll empty the free list afterwards.
|
||||
// We ignore young regions, we'll empty the young list afterwards.
|
||||
// We ignore humongous regions, we're not tearing down the
|
||||
// humongous regions set.
|
||||
assert(r->is_free() || r->is_young() || r->isHumongous(),
|
||||
"it cannot be another type");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -6756,6 +6751,7 @@ public:
|
||||
|
||||
if (r->is_empty()) {
|
||||
// Add free regions to the free list
|
||||
r->set_free();
|
||||
_hrm->insert_into_free_list(r);
|
||||
} else if (!_free_list_only) {
|
||||
assert(!r->is_young(), "we should not come across young regions");
|
||||
@ -6763,7 +6759,11 @@ public:
|
||||
if (r->isHumongous()) {
|
||||
// We ignore humongous regions, we left the humongous set unchanged
|
||||
} else {
|
||||
// The rest should be old, add them to the old set
|
||||
// Objects that were compacted would have ended up on regions
|
||||
// that were previously old or free.
|
||||
assert(r->is_free() || r->is_old(), "invariant");
|
||||
// We now consider them old, so register as such.
|
||||
r->set_old();
|
||||
_old_set->add(r);
|
||||
}
|
||||
_total_used += r->used();
|
||||
@ -6830,7 +6830,7 @@ HeapRegion* G1CollectedHeap::new_mutator_alloc_region(size_t word_size,
|
||||
void G1CollectedHeap::retire_mutator_alloc_region(HeapRegion* alloc_region,
|
||||
size_t allocated_bytes) {
|
||||
assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */);
|
||||
assert(alloc_region->is_young(), "all mutator alloc regions should be young");
|
||||
assert(alloc_region->is_eden(), "all mutator alloc regions should be eden");
|
||||
|
||||
g1_policy()->add_region_to_incremental_cset_lhs(alloc_region);
|
||||
_summary_bytes_used += allocated_bytes;
|
||||
@ -6889,6 +6889,7 @@ HeapRegion* G1CollectedHeap::new_gc_alloc_region(size_t word_size,
|
||||
_hr_printer.alloc(new_alloc_region, G1HRPrinter::Survivor);
|
||||
check_bitmaps("Survivor Region Allocation", new_alloc_region);
|
||||
} else {
|
||||
new_alloc_region->set_old();
|
||||
_hr_printer.alloc(new_alloc_region, G1HRPrinter::Old);
|
||||
check_bitmaps("Old Region Allocation", new_alloc_region);
|
||||
}
|
||||
@ -7000,9 +7001,11 @@ public:
|
||||
} else if (hr->is_empty()) {
|
||||
assert(_hrm->is_free(hr), err_msg("Heap region %u is empty but not on the free list.", hr->hrm_index()));
|
||||
_free_count.increment(1u, hr->capacity());
|
||||
} else {
|
||||
} else if (hr->is_old()) {
|
||||
assert(hr->containing_set() == _old_set, err_msg("Heap region %u is old but not in the old set.", hr->hrm_index()));
|
||||
_old_count.increment(1u, hr->capacity());
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1665,7 +1665,7 @@ G1CollectorPolicy::record_concurrent_mark_cleanup_end(int no_of_gc_threads) {
|
||||
// Add the heap region at the head of the non-incremental collection set
|
||||
void G1CollectorPolicy::add_old_region_to_cset(HeapRegion* hr) {
|
||||
assert(_inc_cset_build_state == Active, "Precondition");
|
||||
assert(!hr->is_young(), "non-incremental add of young region");
|
||||
assert(hr->is_old(), "the region should be old");
|
||||
|
||||
assert(!hr->in_collection_set(), "should not already be in the CSet");
|
||||
hr->set_in_collection_set(true);
|
||||
@ -1811,7 +1811,7 @@ void G1CollectorPolicy::add_region_to_incremental_cset_common(HeapRegion* hr) {
|
||||
// Add the region at the RHS of the incremental cset
|
||||
void G1CollectorPolicy::add_region_to_incremental_cset_rhs(HeapRegion* hr) {
|
||||
// We should only ever be appending survivors at the end of a pause
|
||||
assert( hr->is_survivor(), "Logic");
|
||||
assert(hr->is_survivor(), "Logic");
|
||||
|
||||
// Do the 'common' stuff
|
||||
add_region_to_incremental_cset_common(hr);
|
||||
@ -1829,7 +1829,7 @@ void G1CollectorPolicy::add_region_to_incremental_cset_rhs(HeapRegion* hr) {
|
||||
// Add the region to the LHS of the incremental cset
|
||||
void G1CollectorPolicy::add_region_to_incremental_cset_lhs(HeapRegion* hr) {
|
||||
// Survivors should be added to the RHS at the end of a pause
|
||||
assert(!hr->is_survivor(), "Logic");
|
||||
assert(hr->is_eden(), "Logic");
|
||||
|
||||
// Do the 'common' stuff
|
||||
add_region_to_incremental_cset_common(hr);
|
||||
@ -1989,7 +1989,11 @@ void G1CollectorPolicy::finalize_cset(double target_pause_time_ms, EvacuationInf
|
||||
HeapRegion* hr = young_list->first_survivor_region();
|
||||
while (hr != NULL) {
|
||||
assert(hr->is_survivor(), "badly formed young list");
|
||||
hr->set_young();
|
||||
// There is a convention that all the young regions in the CSet
|
||||
// are tagged as "eden", so we do this for the survivors here. We
|
||||
// use the special set_eden_pre_gc() as it doesn't check that the
|
||||
// region is free (which is not the case here).
|
||||
hr->set_eden_pre_gc();
|
||||
hr = hr->get_next_young_region();
|
||||
}
|
||||
|
||||
|
@ -299,13 +299,13 @@ public:
|
||||
// Accessors
|
||||
|
||||
void set_region_eden(HeapRegion* hr, int young_index_in_cset) {
|
||||
hr->set_young();
|
||||
hr->set_eden();
|
||||
hr->install_surv_rate_group(_short_lived_surv_rate_group);
|
||||
hr->set_young_index_in_cset(young_index_in_cset);
|
||||
}
|
||||
|
||||
void set_region_survivor(HeapRegion* hr, int young_index_in_cset) {
|
||||
assert(hr->is_young() && hr->is_survivor(), "pre-condition");
|
||||
assert(hr->is_survivor(), "pre-condition");
|
||||
hr->install_surv_rate_group(_survivor_surv_rate_group);
|
||||
hr->set_young_index_in_cset(young_index_in_cset);
|
||||
}
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
|
||||
#include "gc_implementation/g1/g1HotCardCache.hpp"
|
||||
#include "gc_implementation/g1/g1RemSet.hpp"
|
||||
#include "gc_implementation/g1/heapRegion.hpp"
|
||||
#include "runtime/atomic.inline.hpp"
|
||||
|
||||
G1HotCardCache::G1HotCardCache(G1CollectedHeap *g1h):
|
||||
@ -136,7 +135,6 @@ void G1HotCardCache::drain(uint worker_i,
|
||||
}
|
||||
|
||||
void G1HotCardCache::reset_card_counts(HeapRegion* hr) {
|
||||
assert(!hr->isHumongous(), "Should have been cleared");
|
||||
_card_counts.clear_region(hr);
|
||||
}
|
||||
|
||||
|
@ -259,14 +259,16 @@ public:
|
||||
size_t code_root_elems = hrrs->strong_code_roots_list_length();
|
||||
|
||||
RegionTypeCounter* current = NULL;
|
||||
if (r->is_young()) {
|
||||
if (r->is_free()) {
|
||||
current = &_free;
|
||||
} else if (r->is_young()) {
|
||||
current = &_young;
|
||||
} else if (r->isHumongous()) {
|
||||
current = &_humonguous;
|
||||
} else if (r->is_empty()) {
|
||||
current = &_free;
|
||||
} else {
|
||||
} else if (r->is_old()) {
|
||||
current = &_old;
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
current->add(rs_mem_sz, occupied_cards, code_root_mem_sz, code_root_elems);
|
||||
_all.add(rs_mem_sz, occupied_cards, code_root_mem_sz, code_root_elems);
|
||||
|
@ -31,8 +31,6 @@
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
#if INCLUDE_ALL_GCS
|
||||
|
||||
class DirtyCardQueueSet;
|
||||
class G1SATBCardTableLoggingModRefBS;
|
||||
|
||||
@ -180,7 +178,4 @@ class G1SATBCardTableLoggingModRefBS: public G1SATBCardTableModRefBS {
|
||||
void write_ref_array_work(MemRegion mr) { invalidate(mr); }
|
||||
};
|
||||
|
||||
|
||||
#endif // INCLUDE_ALL_GCS
|
||||
|
||||
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1SATBCARDTABLEMODREFBS_HPP
|
||||
|
@ -211,8 +211,6 @@ void HeapRegion::reset_after_compaction() {
|
||||
}
|
||||
|
||||
void HeapRegion::hr_clear(bool par, bool clear_space, bool locked) {
|
||||
assert(_humongous_type == NotHumongous,
|
||||
"we should have already filtered out humongous regions");
|
||||
assert(_humongous_start_region == NULL,
|
||||
"we should have already filtered out humongous regions");
|
||||
assert(_end == _orig_end,
|
||||
@ -222,7 +220,7 @@ void HeapRegion::hr_clear(bool par, bool clear_space, bool locked) {
|
||||
|
||||
set_young_index_in_cset(-1);
|
||||
uninstall_surv_rate_group();
|
||||
set_young_type(NotYoung);
|
||||
set_free();
|
||||
reset_pre_dummy_top();
|
||||
|
||||
if (!par) {
|
||||
@ -273,7 +271,7 @@ void HeapRegion::set_startsHumongous(HeapWord* new_top, HeapWord* new_end) {
|
||||
assert(top() == bottom(), "should be empty");
|
||||
assert(bottom() <= new_top && new_top <= new_end, "pre-condition");
|
||||
|
||||
_humongous_type = StartsHumongous;
|
||||
_type.set_starts_humongous();
|
||||
_humongous_start_region = this;
|
||||
|
||||
set_end(new_end);
|
||||
@ -287,11 +285,11 @@ void HeapRegion::set_continuesHumongous(HeapRegion* first_hr) {
|
||||
assert(top() == bottom(), "should be empty");
|
||||
assert(first_hr->startsHumongous(), "pre-condition");
|
||||
|
||||
_humongous_type = ContinuesHumongous;
|
||||
_type.set_continues_humongous();
|
||||
_humongous_start_region = first_hr;
|
||||
}
|
||||
|
||||
void HeapRegion::set_notHumongous() {
|
||||
void HeapRegion::clear_humongous() {
|
||||
assert(isHumongous(), "pre-condition");
|
||||
|
||||
if (startsHumongous()) {
|
||||
@ -307,7 +305,6 @@ void HeapRegion::set_notHumongous() {
|
||||
}
|
||||
|
||||
assert(capacity() == HeapRegion::GrainBytes, "pre-condition");
|
||||
_humongous_type = NotHumongous;
|
||||
_humongous_start_region = NULL;
|
||||
}
|
||||
|
||||
@ -327,12 +324,12 @@ HeapRegion::HeapRegion(uint hrm_index,
|
||||
MemRegion mr) :
|
||||
G1OffsetTableContigSpace(sharedOffsetArray, mr),
|
||||
_hrm_index(hrm_index),
|
||||
_humongous_type(NotHumongous), _humongous_start_region(NULL),
|
||||
_humongous_start_region(NULL),
|
||||
_in_collection_set(false),
|
||||
_next_in_special_set(NULL), _orig_end(NULL),
|
||||
_claimed(InitialClaimValue), _evacuation_failed(false),
|
||||
_prev_marked_bytes(0), _next_marked_bytes(0), _gc_efficiency(0.0),
|
||||
_young_type(NotYoung), _next_young_region(NULL),
|
||||
_next_young_region(NULL),
|
||||
_next_dirty_cards_region(NULL), _next(NULL), _prev(NULL),
|
||||
#ifdef ASSERT
|
||||
_containing_set(NULL),
|
||||
@ -686,26 +683,11 @@ void HeapRegion::verify_strong_code_roots(VerifyOption vo, bool* failures) const
|
||||
|
||||
void HeapRegion::print() const { print_on(gclog_or_tty); }
|
||||
void HeapRegion::print_on(outputStream* st) const {
|
||||
if (isHumongous()) {
|
||||
if (startsHumongous())
|
||||
st->print(" HS");
|
||||
else
|
||||
st->print(" HC");
|
||||
} else {
|
||||
st->print(" ");
|
||||
}
|
||||
st->print(" %2s", get_short_type_str());
|
||||
if (in_collection_set())
|
||||
st->print(" CS");
|
||||
else
|
||||
st->print(" ");
|
||||
if (is_young())
|
||||
st->print(is_survivor() ? " SU" : " Y ");
|
||||
else
|
||||
st->print(" ");
|
||||
if (is_empty())
|
||||
st->print(" F");
|
||||
else
|
||||
st->print(" ");
|
||||
st->print(" TS %5d", _gc_time_stamp);
|
||||
st->print(" PTAMS "PTR_FORMAT" NTAMS "PTR_FORMAT,
|
||||
prev_top_at_mark_start(), next_top_at_mark_start());
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include "gc_implementation/g1/g1BlockOffsetTable.hpp"
|
||||
#include "gc_implementation/g1/g1_specialized_oop_closures.hpp"
|
||||
#include "gc_implementation/g1/heapRegionType.hpp"
|
||||
#include "gc_implementation/g1/survRateGroup.hpp"
|
||||
#include "gc_implementation/shared/ageTable.hpp"
|
||||
#include "gc_implementation/shared/spaceDecorator.hpp"
|
||||
@ -34,8 +35,6 @@
|
||||
#include "memory/watermark.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
#if INCLUDE_ALL_GCS
|
||||
|
||||
// A HeapRegion is the smallest piece of a G1CollectedHeap that
|
||||
// can be collected independently.
|
||||
|
||||
@ -55,10 +54,7 @@ class nmethod;
|
||||
#define HR_FORMAT "%u:(%s)["PTR_FORMAT","PTR_FORMAT","PTR_FORMAT"]"
|
||||
#define HR_FORMAT_PARAMS(_hr_) \
|
||||
(_hr_)->hrm_index(), \
|
||||
(_hr_)->is_survivor() ? "S" : (_hr_)->is_young() ? "E" : \
|
||||
(_hr_)->startsHumongous() ? "HS" : \
|
||||
(_hr_)->continuesHumongous() ? "HC" : \
|
||||
!(_hr_)->is_empty() ? "O" : "F", \
|
||||
(_hr_)->get_short_type_str(), \
|
||||
p2i((_hr_)->bottom()), p2i((_hr_)->top()), p2i((_hr_)->end())
|
||||
|
||||
// sentinel value for hrm_index
|
||||
@ -215,12 +211,6 @@ class HeapRegion: public G1OffsetTableContigSpace {
|
||||
friend class VMStructs;
|
||||
private:
|
||||
|
||||
enum HumongousType {
|
||||
NotHumongous = 0,
|
||||
StartsHumongous,
|
||||
ContinuesHumongous
|
||||
};
|
||||
|
||||
// The remembered set for this region.
|
||||
// (Might want to make this "inline" later, to avoid some alloc failure
|
||||
// issues.)
|
||||
@ -232,7 +222,8 @@ class HeapRegion: public G1OffsetTableContigSpace {
|
||||
// The index of this region in the heap region sequence.
|
||||
uint _hrm_index;
|
||||
|
||||
HumongousType _humongous_type;
|
||||
HeapRegionType _type;
|
||||
|
||||
// For a humongous region, region in which it starts.
|
||||
HeapRegion* _humongous_start_region;
|
||||
// For the start region of a humongous sequence, it's original end().
|
||||
@ -274,13 +265,6 @@ class HeapRegion: public G1OffsetTableContigSpace {
|
||||
// The calculated GC efficiency of the region.
|
||||
double _gc_efficiency;
|
||||
|
||||
enum YoungType {
|
||||
NotYoung, // a region is not young
|
||||
Young, // a region is young
|
||||
Survivor // a region is young and it contains survivors
|
||||
};
|
||||
|
||||
volatile YoungType _young_type;
|
||||
int _young_index_in_cset;
|
||||
SurvRateGroup* _surv_rate_group;
|
||||
int _age_index;
|
||||
@ -305,12 +289,6 @@ class HeapRegion: public G1OffsetTableContigSpace {
|
||||
_next_top_at_mark_start = bot;
|
||||
}
|
||||
|
||||
void set_young_type(YoungType new_type) {
|
||||
//assert(_young_type != new_type, "setting the same type" );
|
||||
// TODO: add more assertions here
|
||||
_young_type = new_type;
|
||||
}
|
||||
|
||||
// Cached attributes used in the collection set policy information
|
||||
|
||||
// The RSet length that was added to the total value
|
||||
@ -430,9 +408,21 @@ class HeapRegion: public G1OffsetTableContigSpace {
|
||||
_prev_marked_bytes = _next_marked_bytes = 0;
|
||||
}
|
||||
|
||||
bool isHumongous() const { return _humongous_type != NotHumongous; }
|
||||
bool startsHumongous() const { return _humongous_type == StartsHumongous; }
|
||||
bool continuesHumongous() const { return _humongous_type == ContinuesHumongous; }
|
||||
const char* get_type_str() const { return _type.get_str(); }
|
||||
const char* get_short_type_str() const { return _type.get_short_str(); }
|
||||
|
||||
bool is_free() const { return _type.is_free(); }
|
||||
|
||||
bool is_young() const { return _type.is_young(); }
|
||||
bool is_eden() const { return _type.is_eden(); }
|
||||
bool is_survivor() const { return _type.is_survivor(); }
|
||||
|
||||
bool isHumongous() const { return _type.is_humongous(); }
|
||||
bool startsHumongous() const { return _type.is_starts_humongous(); }
|
||||
bool continuesHumongous() const { return _type.is_continues_humongous(); }
|
||||
|
||||
bool is_old() const { return _type.is_old(); }
|
||||
|
||||
// For a humongous region, region in which it starts.
|
||||
HeapRegion* humongous_start_region() const {
|
||||
return _humongous_start_region;
|
||||
@ -496,7 +486,7 @@ class HeapRegion: public G1OffsetTableContigSpace {
|
||||
void set_continuesHumongous(HeapRegion* first_hr);
|
||||
|
||||
// Unsets the humongous-related fields on the region.
|
||||
void set_notHumongous();
|
||||
void clear_humongous();
|
||||
|
||||
// If the region has a remembered set, return a pointer to it.
|
||||
HeapRegionRemSet* rem_set() const {
|
||||
@ -623,9 +613,6 @@ class HeapRegion: public G1OffsetTableContigSpace {
|
||||
void calc_gc_efficiency(void);
|
||||
double gc_efficiency() { return _gc_efficiency;}
|
||||
|
||||
bool is_young() const { return _young_type != NotYoung; }
|
||||
bool is_survivor() const { return _young_type == Survivor; }
|
||||
|
||||
int young_index_in_cset() const { return _young_index_in_cset; }
|
||||
void set_young_index_in_cset(int index) {
|
||||
assert( (index == -1) || is_young(), "pre-condition" );
|
||||
@ -677,11 +664,13 @@ class HeapRegion: public G1OffsetTableContigSpace {
|
||||
}
|
||||
}
|
||||
|
||||
void set_young() { set_young_type(Young); }
|
||||
void set_free() { _type.set_free(); }
|
||||
|
||||
void set_survivor() { set_young_type(Survivor); }
|
||||
void set_eden() { _type.set_eden(); }
|
||||
void set_eden_pre_gc() { _type.set_eden_pre_gc(); }
|
||||
void set_survivor() { _type.set_survivor(); }
|
||||
|
||||
void set_not_young() { set_young_type(NotYoung); }
|
||||
void set_old() { _type.set_old(); }
|
||||
|
||||
// Determine if an object has been allocated since the last
|
||||
// mark performed by the collector. This returns true iff the object
|
||||
@ -809,6 +798,4 @@ class HeapRegionClosure : public StackObj {
|
||||
bool complete() { return _complete; }
|
||||
};
|
||||
|
||||
#endif // INCLUDE_ALL_GCS
|
||||
|
||||
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGION_HPP
|
||||
|
@ -42,7 +42,9 @@ void HeapRegionSetBase::verify_region(HeapRegion* hr) {
|
||||
assert(hr->containing_set() == this, err_msg("Inconsistent containing set for %u", hr->hrm_index()));
|
||||
assert(!hr->is_young(), err_msg("Adding young region %u", hr->hrm_index())); // currently we don't use these sets for young regions
|
||||
assert(hr->isHumongous() == regions_humongous(), err_msg("Wrong humongous state for region %u and set %s", hr->hrm_index(), name()));
|
||||
assert(hr->is_empty() == regions_empty(), err_msg("Wrong empty state for region %u and set %s", hr->hrm_index(), name()));
|
||||
assert(hr->is_free() == regions_free(), err_msg("Wrong free state for region %u and set %s", hr->hrm_index(), name()));
|
||||
assert(!hr->is_free() || hr->is_empty(), err_msg("Free region %u is not empty for set %s", hr->hrm_index(), name()));
|
||||
assert(!hr->is_empty() || hr->is_free(), err_msg("Empty region %u is not free for set %s", hr->hrm_index(), name()));
|
||||
assert(hr->rem_set()->verify_ready_for_par_iteration(), err_msg("Wrong iteration state %u", hr->hrm_index()));
|
||||
}
|
||||
#endif
|
||||
@ -85,16 +87,16 @@ void HeapRegionSetBase::print_on(outputStream* out, bool print_contents) {
|
||||
out->print_cr("Set: %s ("PTR_FORMAT")", name(), this);
|
||||
out->print_cr(" Region Assumptions");
|
||||
out->print_cr(" humongous : %s", BOOL_TO_STR(regions_humongous()));
|
||||
out->print_cr(" empty : %s", BOOL_TO_STR(regions_empty()));
|
||||
out->print_cr(" free : %s", BOOL_TO_STR(regions_free()));
|
||||
out->print_cr(" Attributes");
|
||||
out->print_cr(" length : %14u", length());
|
||||
out->print_cr(" total capacity : "SIZE_FORMAT_W(14)" bytes",
|
||||
total_capacity_bytes());
|
||||
}
|
||||
|
||||
HeapRegionSetBase::HeapRegionSetBase(const char* name, bool humongous, bool empty, HRSMtSafeChecker* mt_safety_checker)
|
||||
HeapRegionSetBase::HeapRegionSetBase(const char* name, bool humongous, bool free, HRSMtSafeChecker* mt_safety_checker)
|
||||
: _name(name), _verify_in_progress(false),
|
||||
_is_humongous(humongous), _is_empty(empty), _mt_safety_checker(mt_safety_checker),
|
||||
_is_humongous(humongous), _is_free(free), _mt_safety_checker(mt_safety_checker),
|
||||
_count()
|
||||
{ }
|
||||
|
||||
|
@ -81,7 +81,7 @@ class HeapRegionSetBase VALUE_OBJ_CLASS_SPEC {
|
||||
friend class VMStructs;
|
||||
private:
|
||||
bool _is_humongous;
|
||||
bool _is_empty;
|
||||
bool _is_free;
|
||||
HRSMtSafeChecker* _mt_safety_checker;
|
||||
|
||||
protected:
|
||||
@ -102,9 +102,9 @@ protected:
|
||||
// not. Only used during verification.
|
||||
bool regions_humongous() { return _is_humongous; }
|
||||
|
||||
// Indicates whether all regions in the set should be empty or
|
||||
// Indicates whether all regions in the set should be free or
|
||||
// not. Only used during verification.
|
||||
bool regions_empty() { return _is_empty; }
|
||||
bool regions_free() { return _is_free; }
|
||||
|
||||
void check_mt_safety() {
|
||||
if (_mt_safety_checker != NULL) {
|
||||
@ -114,7 +114,7 @@ protected:
|
||||
|
||||
virtual void fill_in_ext_msg_extra(hrs_ext_msg* msg) { }
|
||||
|
||||
HeapRegionSetBase(const char* name, bool humongous, bool empty, HRSMtSafeChecker* mt_safety_checker);
|
||||
HeapRegionSetBase(const char* name, bool humongous, bool free, HRSMtSafeChecker* mt_safety_checker);
|
||||
|
||||
public:
|
||||
const char* name() { return _name; }
|
||||
@ -171,7 +171,7 @@ public:
|
||||
do { \
|
||||
assert(((_set1_)->regions_humongous() == \
|
||||
(_set2_)->regions_humongous()) && \
|
||||
((_set1_)->regions_empty() == (_set2_)->regions_empty()), \
|
||||
((_set1_)->regions_free() == (_set2_)->regions_free()), \
|
||||
hrs_err_msg("the contents of set %s and set %s should match", \
|
||||
(_set1_)->name(), (_set2_)->name())); \
|
||||
} while (0)
|
||||
@ -184,7 +184,7 @@ public:
|
||||
class HeapRegionSet : public HeapRegionSetBase {
|
||||
public:
|
||||
HeapRegionSet(const char* name, bool humongous, HRSMtSafeChecker* mt_safety_checker):
|
||||
HeapRegionSetBase(name, humongous, false /* empty */, mt_safety_checker) { }
|
||||
HeapRegionSetBase(name, humongous, false /* free */, mt_safety_checker) { }
|
||||
|
||||
void bulk_remove(const HeapRegionSetCount& removed) {
|
||||
_count.decrement(removed.length(), removed.capacity());
|
||||
|
69
hotspot/src/share/vm/gc_implementation/g1/heapRegionType.cpp
Normal file
69
hotspot/src/share/vm/gc_implementation/g1/heapRegionType.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "gc_implementation/g1/heapRegionType.hpp"
|
||||
|
||||
bool HeapRegionType::is_valid(Tag tag) {
|
||||
switch (tag) {
|
||||
case FreeTag:
|
||||
case EdenTag:
|
||||
case SurvTag:
|
||||
case HumStartsTag:
|
||||
case HumContTag:
|
||||
case OldTag:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* HeapRegionType::get_str() const {
|
||||
hrt_assert_is_valid(_tag);
|
||||
switch (_tag) {
|
||||
case FreeTag: return "FREE";
|
||||
case EdenTag: return "EDEN";
|
||||
case SurvTag: return "SURV";
|
||||
case HumStartsTag: return "HUMS";
|
||||
case HumContTag: return "HUMC";
|
||||
case OldTag: return "OLD";
|
||||
}
|
||||
ShouldNotReachHere();
|
||||
// keep some compilers happy
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* HeapRegionType::get_short_str() const {
|
||||
hrt_assert_is_valid(_tag);
|
||||
switch (_tag) {
|
||||
case FreeTag: return "F";
|
||||
case EdenTag: return "E";
|
||||
case SurvTag: return "S";
|
||||
case HumStartsTag: return "HS";
|
||||
case HumContTag: return "HC";
|
||||
case OldTag: return "O";
|
||||
}
|
||||
ShouldNotReachHere();
|
||||
// keep some compilers happy
|
||||
return NULL;
|
||||
}
|
134
hotspot/src/share/vm/gc_implementation/g1/heapRegionType.hpp
Normal file
134
hotspot/src/share/vm/gc_implementation/g1/heapRegionType.hpp
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONTYPE_HPP
|
||||
#define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONTYPE_HPP
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
|
||||
#define hrt_assert_is_valid(tag) \
|
||||
assert(is_valid((tag)), err_msg("invalid HR type: %u", (uint) (tag)))
|
||||
|
||||
class HeapRegionType VALUE_OBJ_CLASS_SPEC {
|
||||
private:
|
||||
// We encode the value of the heap region type so the generation can be
|
||||
// determined quickly. The tag is split into two parts:
|
||||
//
|
||||
// major type (young, humongous) : top N-1 bits
|
||||
// minor type (eden / survivor, starts / cont hum, etc.) : bottom 1 bit
|
||||
//
|
||||
// If there's need to increase the number of minor types in the
|
||||
// future, we'll have to increase the size of the latter and hence
|
||||
// decrease the size of the former.
|
||||
//
|
||||
// 0000 0 [ 0] Free
|
||||
//
|
||||
// 0001 0 Young Mask
|
||||
// 0001 0 [ 2] Eden
|
||||
// 0001 1 [ 3] Survivor
|
||||
//
|
||||
// 0010 0 Humongous Mask
|
||||
// 0010 0 [ 4] Humongous Starts
|
||||
// 0010 1 [ 5] Humongous Continues
|
||||
//
|
||||
// 01000 [ 8] Old
|
||||
typedef enum {
|
||||
FreeTag = 0,
|
||||
|
||||
YoungMask = 2,
|
||||
EdenTag = YoungMask,
|
||||
SurvTag = YoungMask + 1,
|
||||
|
||||
HumMask = 4,
|
||||
HumStartsTag = HumMask,
|
||||
HumContTag = HumMask + 1,
|
||||
|
||||
OldTag = 8
|
||||
} Tag;
|
||||
|
||||
volatile Tag _tag;
|
||||
|
||||
static bool is_valid(Tag tag);
|
||||
|
||||
Tag get() const {
|
||||
hrt_assert_is_valid(_tag);
|
||||
return _tag;
|
||||
}
|
||||
|
||||
// Sets the type to 'tag'.
|
||||
void set(Tag tag) {
|
||||
hrt_assert_is_valid(tag);
|
||||
hrt_assert_is_valid(_tag);
|
||||
_tag = tag;
|
||||
}
|
||||
|
||||
// Sets the type to 'tag', expecting the type to be 'before'. This
|
||||
// is available for when we want to add sanity checking to the type
|
||||
// transition.
|
||||
void set_from(Tag tag, Tag before) {
|
||||
hrt_assert_is_valid(tag);
|
||||
hrt_assert_is_valid(before);
|
||||
hrt_assert_is_valid(_tag);
|
||||
assert(_tag == before,
|
||||
err_msg("HR tag: %u, expected: %u new tag; %u", _tag, before, tag));
|
||||
_tag = tag;
|
||||
}
|
||||
|
||||
public:
|
||||
// Queries
|
||||
|
||||
bool is_free() const { return get() == FreeTag; }
|
||||
|
||||
bool is_young() const { return (get() & YoungMask) != 0; }
|
||||
bool is_eden() const { return get() == EdenTag; }
|
||||
bool is_survivor() const { return get() == SurvTag; }
|
||||
|
||||
bool is_humongous() const { return (get() & HumMask) != 0; }
|
||||
bool is_starts_humongous() const { return get() == HumStartsTag; }
|
||||
bool is_continues_humongous() const { return get() == HumContTag; }
|
||||
|
||||
bool is_old() const { return get() == OldTag; }
|
||||
|
||||
// Setters
|
||||
|
||||
void set_free() { set(FreeTag); }
|
||||
|
||||
void set_eden() { set_from(EdenTag, FreeTag); }
|
||||
void set_eden_pre_gc() { set_from(EdenTag, SurvTag); }
|
||||
void set_survivor() { set_from(SurvTag, FreeTag); }
|
||||
|
||||
void set_starts_humongous() { set_from(HumStartsTag, FreeTag); }
|
||||
void set_continues_humongous() { set_from(HumContTag, FreeTag); }
|
||||
|
||||
void set_old() { set(OldTag); }
|
||||
|
||||
// Misc
|
||||
|
||||
const char* get_str() const;
|
||||
const char* get_short_str() const;
|
||||
|
||||
HeapRegionType() : _tag(FreeTag) { hrt_assert_is_valid(_tag); }
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONTYPE_HPP
|
Loading…
Reference in New Issue
Block a user