< prev index next >
src/share/vm/gc/g1/g1CollectedHeap.cpp
Print this page
*** 318,333 ****
// 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;
// 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
--- 318,329 ----
// 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 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,366 ****
// 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_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
--- 340,359 ----
// 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(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);
}
// 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,391 ****
// 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);
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);
! }
}
// 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
--- 362,374 ----
// 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.
! first_hr->set_top(MIN2(first_hr->end(), obj_top));
if (_hr_printer.is_active()) {
! _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,430 ****
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(),
"new_top should fall on this region");
! hr->set_top(new_top);
! _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, new_top);
} else {
// not last one
! assert(new_top > hr->end(), "new_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");
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);
return new_obj;
}
// If could fit into free regions w/o expansion, try.
--- 383,413 ----
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() < obj_top && obj_top <= hr->end(),
"new_top should fall on this region");
! hr->set_top(obj_top);
! _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, obj_top);
} else {
// not last one
! 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), its top should
! // match obj_top.
! assert(hr == NULL || (hr->top() == obj_top), "sanity");
check_bitmaps("Humongous Region Allocation", 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,1155 ****
_g1h(g1h), _mr_bs(mr_bs) {}
bool doHeapRegion(HeapRegion* r) {
HeapRegionRemSet* hrrs = r->rem_set();
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);
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!
--- 1120,1138 ----
_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");
! } 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,1218 ****
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()) {
--- 1186,1196 ----
*** 2220,2240 ****
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 {
--- 2198,2208 ----
*** 2298,2310 ****
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; }
};
--- 2266,2276 ----
*** 2521,2533 ****
}
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
// return the containing region.
! HeapRegion* hr = heap_region_containing_raw(p);
return hr->is_in(p);
} else {
return false;
}
}
--- 2487,2499 ----
}
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() should successfully
// return the containing region.
! HeapRegion* hr = heap_region_containing(p);
return hr->is_in(p);
} else {
return false;
}
}
*** 3060,3070 ****
if (!r->is_continues_humongous()) {
bool failures = false;
r->verify(_vo, &failures);
if (failures) {
_failures = true;
! } else {
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 "] "
--- 3026,3036 ----
if (!r->is_continues_humongous()) {
bool failures = false;
r->verify(_vo, &failures);
if (failures) {
_failures = true;
! } 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,5341 ****
}
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(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) {
--- 5280,5293 ----
}
void G1CollectedHeap::free_humongous_region(HeapRegion* hr,
FreeRegionList* free_list,
bool par) {
! assert(hr->is_humongous(), "this is only for humongous regions");
assert(free_list != NULL, "pre-condition");
hr->clear_humongous();
free_region(hr, free_list, par);
}
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,5506 ****
_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;
--- 5447,5456 ----
*** 5770,5784 ****
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",
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()
--- 5720,5733 ----
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 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->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,5805 ****
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",
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()
--- 5740,5753 ----
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 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->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,5820 ****
--- 5755,5772 ----
}
// 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,6058 ****
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);
--- 5997,6006 ----
*** 6236,6253 ****
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());
_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()) {
--- 6184,6197 ----
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_young()) {
// TODO
! } 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 >