提交 53708f26 编写于 作者: B brutisso

8057768: Make heap region region type in G1 HeapRegion explicit

Reviewed-by: brutisso, tschatzl
上级 df52a660
......@@ -4736,7 +4736,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();
......@@ -4747,15 +4747,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");
......@@ -4768,12 +4760,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;
......
......@@ -207,7 +207,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;
}
}
......@@ -366,7 +369,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(),
......@@ -800,6 +803,7 @@ HeapWord* G1CollectedHeap::humongous_obj_allocate(size_t word_size, AllocationCo
#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");
}
......@@ -1227,21 +1231,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;
}
......@@ -2127,8 +2131,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);
......@@ -4021,14 +4025,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();
}
......@@ -5948,7 +5944,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");
......@@ -5978,14 +5974,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;
}
......@@ -6290,9 +6286,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());
}
......@@ -6579,16 +6575,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;
}
......@@ -6638,6 +6633,7 @@ public:
if (r->is_empty()) {
// Add free regions to the free list
r->set_free();
r->set_allocation_context(AllocationContext::system());
_hrm->insert_into_free_list(r);
} else if (!_free_list_only) {
......@@ -6646,7 +6642,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();
......@@ -6713,7 +6713,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);
_allocator->increase_used(allocated_bytes);
......@@ -6762,6 +6762,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);
}
......@@ -6821,9 +6822,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;
}
......
......@@ -1664,7 +1664,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);
......@@ -1810,7 +1810,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);
......@@ -1828,7 +1828,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);
......@@ -1988,7 +1988,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.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);
}
......
......@@ -258,14 +258,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
......@@ -195,8 +195,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,
......@@ -207,7 +205,7 @@ void HeapRegion::hr_clear(bool par, bool clear_space, bool locked) {
set_allocation_context(AllocationContext::system());
set_young_index_in_cset(-1);
uninstall_surv_rate_group();
set_young_type(NotYoung);
set_free();
reset_pre_dummy_top();
if (!par) {
......@@ -258,7 +256,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);
......@@ -272,11 +270,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()) {
......@@ -292,7 +290,6 @@ void HeapRegion::set_notHumongous() {
}
assert(capacity() == HeapRegion::GrainBytes, "pre-condition");
_humongous_type = NotHumongous;
_humongous_start_region = NULL;
}
......@@ -336,12 +333,12 @@ HeapRegion::HeapRegion(uint hrm_index,
G1OffsetTableContigSpace(sharedOffsetArray, mr),
_hrm_index(hrm_index),
_allocation_context(AllocationContext::system()),
_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),
......@@ -703,27 +700,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 {
st->print("AC%4u", allocation_context());
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());
......
......@@ -28,6 +28,7 @@
#include "gc_implementation/g1/g1AllocationContext.hpp"
#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"
......@@ -35,8 +36,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.
......@@ -56,10 +55,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
......@@ -220,12 +216,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.)
......@@ -239,7 +229,8 @@ class HeapRegion: public G1OffsetTableContigSpace {
AllocationContext_t _allocation_context;
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().
......@@ -281,13 +272,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;
......@@ -312,12 +296,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
......@@ -437,9 +415,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;
......@@ -503,7 +493,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 {
......@@ -638,9 +628,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" );
......@@ -692,11 +679,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
......@@ -841,6 +830,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());
......
/*
* 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;
}
/*
* 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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册