< prev index next >
src/share/vm/gc/g1/g1CollectedHeap.cpp
Print this page
@@ -318,16 +318,12 @@
// This will be the "starts humongous" region.
HeapRegion* first_hr = region_at(first);
// The header of the new object will be placed at the bottom of
// the first region.
HeapWord* new_obj = first_hr->bottom();
- // This will be the new end of the first region in the series that
- // should also match the end of the last region in the series.
- HeapWord* new_end = new_obj + word_size_sum;
- // This will be the new top of the first region that will reflect
- // this allocation.
- HeapWord* new_top = new_obj + word_size;
+ // This will be the new top of the new object.
+ HeapWord* obj_top = new_obj + word_size;
// First, we need to zero the header of the space that we will be
// allocating. When we update top further down, some refinement
// threads might try to scan the region. By zeroing the header we
// ensure that any thread that will try to scan the region will
@@ -344,23 +340,20 @@
// We will set up the first region as "starts humongous". This
// will also update the BOT covering all the regions to reflect
// that there is a single object that starts at the bottom of the
// first region.
- first_hr->set_starts_humongous(new_top, new_end);
+ first_hr->set_starts_humongous(obj_top);
first_hr->set_allocation_context(context);
// Then, if there are any, we will set up the "continues
// humongous" regions.
HeapRegion* hr = NULL;
for (uint i = first + 1; i < last; ++i) {
hr = region_at(i);
hr->set_continues_humongous(first_hr);
hr->set_allocation_context(context);
}
- // If we have "continues humongous" regions (hr != NULL), then the
- // end of the last one should match new_end.
- assert(hr == NULL || hr->end() == new_end, "sanity");
// Up to this point no concurrent thread would have been able to
// do any scanning on any region in this series. All the top
// fields still point to bottom, so the intersection between
// [bottom,top] and [card_start,card_end] will be empty. Before we
@@ -369,23 +362,13 @@
// object header and the BOT initialization.
OrderAccess::storestore();
// Now that the BOT and the object header have been initialized,
// we can update top of the "starts humongous" region.
- assert(first_hr->bottom() < new_top && new_top <= first_hr->end(),
- "new_top should be in this region");
- first_hr->set_top(new_top);
+ first_hr->set_top(MIN2(first_hr->end(), obj_top));
if (_hr_printer.is_active()) {
- HeapWord* bottom = first_hr->bottom();
- HeapWord* end = first_hr->orig_end();
- if ((first + 1) == last) {
- // the series has a single humongous region
- _hr_printer.alloc(G1HRPrinter::SingleHumongous, first_hr, new_top);
- } else {
- // the series has more than one humongous regions
- _hr_printer.alloc(G1HRPrinter::StartsHumongous, first_hr, end);
- }
+ _hr_printer.alloc(G1HRPrinter::StartsHumongous, first_hr, first_hr->top());
}
// Now, we will update the top fields of the "continues humongous"
// regions. The reason we need to do this is that, otherwise,
// these regions would look empty and this will confuse parts of
@@ -400,31 +383,31 @@
hr = NULL;
for (uint i = first + 1; i < last; ++i) {
hr = region_at(i);
if ((i + 1) == last) {
// last continues humongous region
- assert(hr->bottom() < new_top && new_top <= hr->end(),
+ assert(hr->bottom() < obj_top && obj_top <= hr->end(),
"new_top should fall on this region");
- hr->set_top(new_top);
- _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, new_top);
+ hr->set_top(obj_top);
+ _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, obj_top);
} else {
// not last one
- assert(new_top > hr->end(), "new_top should be above this region");
+ assert(obj_top > hr->end(), "obj_top should be above this region");
hr->set_top(hr->end());
_hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, hr->end());
}
}
- // If we have continues humongous regions (hr != NULL), then the
- // end of the last one should match new_end and its top should
- // match new_top.
- assert(hr == NULL ||
- (hr->end() == new_end && hr->top() == new_top), "sanity");
+ // If we have continues humongous regions (hr != NULL), its top should
+ // match obj_top.
+ assert(hr == NULL || (hr->top() == obj_top), "sanity");
check_bitmaps("Humongous Region Allocation", first_hr);
- assert(first_hr->used() == word_size * HeapWordSize, "invariant");
- increase_used(first_hr->used());
- _humongous_set.add(first_hr);
+ increase_used(word_size * HeapWordSize);
+
+ for (uint i = first; i < last; ++i) {
+ _humongous_set.add(region_at(i));
+ }
return new_obj;
}
// If could fit into free regions w/o expansion, try.
@@ -1137,19 +1120,19 @@
_g1h(g1h), _mr_bs(mr_bs) {}
bool doHeapRegion(HeapRegion* r) {
HeapRegionRemSet* hrrs = r->rem_set();
+ _g1h->reset_gc_time_stamps(r);
+
if (r->is_continues_humongous()) {
// We'll assert that the strong code root list and RSet is empty
assert(hrrs->strong_code_roots_list_length() == 0, "sanity");
assert(hrrs->occupied() == 0, "RSet should be empty");
- return false;
- }
-
- _g1h->reset_gc_time_stamps(r);
+ } else {
hrrs->clear();
+ }
// You might think here that we could clear just the cards
// corresponding to the used region. But no: if we leave a dirty card
// in a region we might allocate into, then it would prevent that card
// from being enqueued, and cause it to be missed.
// Re: the performance cost: we shouldn't be doing full GC anyway!
@@ -1203,16 +1186,11 @@
bool doHeapRegion(HeapRegion* hr) {
assert(!hr->is_young(), "not expecting to find young regions");
if (hr->is_free()) {
// We only generate output for non-empty regions.
} else if (hr->is_starts_humongous()) {
- if (hr->region_num() == 1) {
- // single humongous region
- _hr_printer->post_compaction(hr, G1HRPrinter::SingleHumongous);
- } else {
_hr_printer->post_compaction(hr, G1HRPrinter::StartsHumongous);
- }
} else if (hr->is_continues_humongous()) {
_hr_printer->post_compaction(hr, G1HRPrinter::ContinuesHumongous);
} else if (hr->is_archive()) {
_hr_printer->post_compaction(hr, G1HRPrinter::Archive);
} else if (hr->is_old()) {
@@ -2220,21 +2198,11 @@
size_t G1CollectedHeap::capacity() const {
return _hrm.length() * HeapRegion::GrainBytes;
}
void G1CollectedHeap::reset_gc_time_stamps(HeapRegion* hr) {
- assert(!hr->is_continues_humongous(), "pre-condition");
hr->reset_gc_time_stamp();
- if (hr->is_starts_humongous()) {
- uint first_index = hr->hrm_index() + 1;
- uint last_index = hr->last_hc_index();
- for (uint i = first_index; i < last_index; i += 1) {
- HeapRegion* chr = region_at(i);
- assert(chr->is_continues_humongous(), "sanity");
- chr->reset_gc_time_stamp();
- }
- }
}
#ifndef PRODUCT
class CheckGCTimeStampsHRClosure : public HeapRegionClosure {
@@ -2298,13 +2266,11 @@
class SumUsedClosure: public HeapRegionClosure {
size_t _used;
public:
SumUsedClosure() : _used(0) {}
bool doHeapRegion(HeapRegion* r) {
- if (!r->is_continues_humongous()) {
_used += r->used();
- }
return false;
}
size_t result() { return _used; }
};
@@ -2521,13 +2487,13 @@
}
bool G1CollectedHeap::is_in(const void* p) const {
if (_hrm.reserved().contains(p)) {
// Given that we know that p is in the reserved space,
- // heap_region_containing_raw() should successfully
+ // heap_region_containing() should successfully
// return the containing region.
- HeapRegion* hr = heap_region_containing_raw(p);
+ HeapRegion* hr = heap_region_containing(p);
return hr->is_in(p);
} else {
return false;
}
}
@@ -3060,11 +3026,11 @@
if (!r->is_continues_humongous()) {
bool failures = false;
r->verify(_vo, &failures);
if (failures) {
_failures = true;
- } else {
+ } else if (!r->is_starts_humongous()) {
VerifyObjsInRegionClosure not_dead_yet_cl(r, _vo);
r->object_iterate(¬_dead_yet_cl);
if (_vo != VerifyOption_G1UseNextMarking) {
if (r->max_live_bytes() < not_dead_yet_cl.live_bytes()) {
gclog_or_tty->print_cr("[" PTR_FORMAT "," PTR_FORMAT "] "
@@ -5314,28 +5280,14 @@
}
void G1CollectedHeap::free_humongous_region(HeapRegion* hr,
FreeRegionList* free_list,
bool par) {
- assert(hr->is_starts_humongous(), "this is only for starts humongous regions");
+ assert(hr->is_humongous(), "this is only for humongous regions");
assert(free_list != NULL, "pre-condition");
-
- size_t hr_capacity = hr->capacity();
- // 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->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->is_continues_humongous(), "invariant");
- curr_hr->clear_humongous();
- free_region(curr_hr, free_list, par);
- i += 1;
- }
}
void G1CollectedHeap::remove_from_old_sets(const HeapRegionSetCount& old_regions_removed,
const HeapRegionSetCount& humongous_regions_removed) {
if (old_regions_removed.length() > 0 || humongous_regions_removed.length() > 0) {
@@ -5495,12 +5447,10 @@
_caller(caller), _g1h(g1h), _failures(false) { }
bool failures() { return _failures; }
virtual bool doHeapRegion(HeapRegion* hr) {
- if (hr->is_continues_humongous()) return false;
-
bool result = _g1h->verify_bitmaps(_caller, hr);
if (!result) {
_failures = true;
}
return false;
@@ -5770,15 +5720,14 @@
uint region_idx = r->hrm_index();
if (!g1h->is_humongous_reclaim_candidate(region_idx) ||
!r->rem_set()->is_empty()) {
if (G1TraceEagerReclaimHumongousObjects) {
- gclog_or_tty->print_cr("Live humongous region %u size " SIZE_FORMAT " start " PTR_FORMAT " length %u with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
+ gclog_or_tty->print_cr("Live humongous region %u object size " SIZE_FORMAT " start " PTR_FORMAT " with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
region_idx,
(size_t)obj->size() * HeapWordSize,
p2i(r->bottom()),
- r->region_num(),
r->rem_set()->occupied(),
r->rem_set()->strong_code_roots_list_length(),
next_bitmap->isMarked(r->bottom()),
g1h->is_humongous_reclaim_candidate(region_idx),
obj->is_typeArray()
@@ -5791,15 +5740,14 @@
guarantee(obj->is_typeArray(),
"Only eagerly reclaiming type arrays is supported, but the object "
PTR_FORMAT " is not.", p2i(r->bottom()));
if (G1TraceEagerReclaimHumongousObjects) {
- gclog_or_tty->print_cr("Dead humongous region %u size " SIZE_FORMAT " start " PTR_FORMAT " length %u with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
+ gclog_or_tty->print_cr("Dead humongous region %u object size " SIZE_FORMAT " start " PTR_FORMAT " with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
region_idx,
(size_t)obj->size() * HeapWordSize,
p2i(r->bottom()),
- r->region_num(),
r->rem_set()->occupied(),
r->rem_set()->strong_code_roots_list_length(),
next_bitmap->isMarked(r->bottom()),
g1h->is_humongous_reclaim_candidate(region_idx),
obj->is_typeArray()
@@ -5807,14 +5755,18 @@
}
// Need to clear mark bit of the humongous object if already set.
if (next_bitmap->isMarked(r->bottom())) {
next_bitmap->clear(r->bottom());
}
+ do {
+ HeapRegion* next = g1h->next_region_in_humongous(r);
_freed_bytes += r->used();
r->set_containing_set(NULL);
_humongous_regions_removed.increment(1u, r->capacity());
g1h->free_humongous_region(r, _free_region_list, false);
+ r = next;
+ } while (r != NULL);
return false;
}
HeapRegionSetCount& humongous_free_count() {
@@ -6045,14 +5997,10 @@
assert(_old_set->is_empty(), "pre-condition");
}
}
bool doHeapRegion(HeapRegion* r) {
- if (r->is_continues_humongous()) {
- return false;
- }
-
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);
@@ -6236,18 +6184,14 @@
HeapRegionManager* hrm) :
_old_set(old_set), _humongous_set(humongous_set), _hrm(hrm),
_old_count(), _humongous_count(), _free_count(){ }
bool doHeapRegion(HeapRegion* hr) {
- if (hr->is_continues_humongous()) {
- return false;
- }
-
if (hr->is_young()) {
// TODO
- } else if (hr->is_starts_humongous()) {
- assert(hr->containing_set() == _humongous_set, "Heap region %u is starts humongous but not in humongous set.", hr->hrm_index());
+ } else if (hr->is_humongous()) {
+ assert(hr->containing_set() == _humongous_set, "Heap region %u is humongous but not in humongous set.", hr->hrm_index());
_humongous_count.increment(1u, hr->capacity());
} 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.increment(1u, hr->capacity());
} else if (hr->is_old()) {
< prev index next >