src/share/vm/gc_implementation/g1/heapRegion.cpp
Print this page
rev 6589 : 8047818: G1 HeapRegions can no longer be ContiguousSpaces
Reviewed-by:
*** 28,37 ****
--- 28,38 ----
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1OopClosures.inline.hpp"
#include "gc_implementation/g1/heapRegion.inline.hpp"
#include "gc_implementation/g1/heapRegionRemSet.hpp"
#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
+ #include "gc_implementation/shared/liveRange.hpp"
#include "memory/genOopClosures.inline.hpp"
#include "memory/iterator.hpp"
#include "memory/space.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/orderAccess.inline.hpp"
*** 58,89 ****
template<class ClosureType>
HeapWord* walk_mem_region_loop(ClosureType* cl, G1CollectedHeap* g1h,
HeapRegion* hr,
HeapWord* cur, HeapWord* top) {
oop cur_oop = oop(cur);
! int oop_size = cur_oop->size();
HeapWord* next_obj = cur + oop_size;
while (next_obj < top) {
// Keep filtering the remembered set.
if (!g1h->is_obj_dead(cur_oop, hr)) {
// Bottom lies entirely below top, so we can call the
// non-memRegion version of oop_iterate below.
cur_oop->oop_iterate(cl);
}
cur = next_obj;
cur_oop = oop(cur);
! oop_size = cur_oop->size();
next_obj = cur + oop_size;
}
return cur;
}
void HeapRegionDCTOC::walk_mem_region(MemRegion mr,
HeapWord* bottom,
HeapWord* top) {
G1CollectedHeap* g1h = _g1;
! int oop_size;
ExtendedOopClosure* cl2 = NULL;
FilterIntoCSClosure intoCSFilt(this, g1h, _cl);
FilterOutOfRegionClosure outOfRegionFilt(_hr, _cl);
--- 59,90 ----
template<class ClosureType>
HeapWord* walk_mem_region_loop(ClosureType* cl, G1CollectedHeap* g1h,
HeapRegion* hr,
HeapWord* cur, HeapWord* top) {
oop cur_oop = oop(cur);
! size_t oop_size = hr->block_size(cur);
HeapWord* next_obj = cur + oop_size;
while (next_obj < top) {
// Keep filtering the remembered set.
if (!g1h->is_obj_dead(cur_oop, hr)) {
// Bottom lies entirely below top, so we can call the
// non-memRegion version of oop_iterate below.
cur_oop->oop_iterate(cl);
}
cur = next_obj;
cur_oop = oop(cur);
! oop_size = hr->block_size(cur);
next_obj = cur + oop_size;
}
return cur;
}
void HeapRegionDCTOC::walk_mem_region(MemRegion mr,
HeapWord* bottom,
HeapWord* top) {
G1CollectedHeap* g1h = _g1;
! size_t oop_size;
ExtendedOopClosure* cl2 = NULL;
FilterIntoCSClosure intoCSFilt(this, g1h, _cl);
FilterOutOfRegionClosure outOfRegionFilt(_hr, _cl);
*** 99,109 ****
// or it was allocated after marking finished, then we add it. Otherwise
// we can safely ignore the object.
if (!g1h->is_obj_dead(oop(bottom), _hr)) {
oop_size = oop(bottom)->oop_iterate(cl2, mr);
} else {
! oop_size = oop(bottom)->size();
}
bottom += oop_size;
if (bottom < top) {
--- 100,110 ----
// or it was allocated after marking finished, then we add it. Otherwise
// we can safely ignore the object.
if (!g1h->is_obj_dead(oop(bottom), _hr)) {
oop_size = oop(bottom)->oop_iterate(cl2, mr);
} else {
! oop_size = _hr->block_size(bottom);
}
bottom += oop_size;
if (bottom < top) {
*** 458,468 ****
// Ran into an unparseable point.
return cur;
} else if (!g1h->is_obj_dead(obj)) {
cl->do_object(obj);
}
! cur += obj->size();
}
return NULL;
}
HeapWord*
--- 459,469 ----
// Ran into an unparseable point.
return cur;
} else if (!g1h->is_obj_dead(obj)) {
cl->do_object(obj);
}
! cur += block_size(cur);
}
return NULL;
}
HeapWord*
*** 530,551 ****
if (obj->klass_or_null() == NULL) {
// Ran into an unparseable point.
return cur;
}
// Otherwise...
! next = (cur + obj->size());
}
// If we finish the above loop...We have a parseable object that
// begins on or before the start of the memory region, and ends
// inside or spans the entire region.
assert(obj == oop(cur), "sanity");
! assert(cur <= start &&
! obj->klass_or_null() != NULL &&
! (cur + obj->size()) > start,
! "Loop postcondition");
if (!g1h->is_obj_dead(obj)) {
obj->oop_iterate(cl, mr);
}
--- 531,551 ----
if (obj->klass_or_null() == NULL) {
// Ran into an unparseable point.
return cur;
}
// Otherwise...
! next = cur + block_size(cur);
}
// If we finish the above loop...We have a parseable object that
// begins on or before the start of the memory region, and ends
// inside or spans the entire region.
assert(obj == oop(cur), "sanity");
! assert(cur <= start, "Loop postcondition");
! assert(obj->klass_or_null() != NULL, "Loop postcondition");
! assert((cur + block_size(cur)) > start, "Loop postcondition");
if (!g1h->is_obj_dead(obj)) {
obj->oop_iterate(cl, mr);
}
*** 555,565 ****
// Ran into an unparseable point.
return cur;
};
// Otherwise:
! next = (cur + obj->size());
if (!g1h->is_obj_dead(obj)) {
if (next < end || !obj->is_objArray()) {
// This object either does not span the MemRegion
// boundary, or if it does it's not an array.
--- 555,565 ----
// Ran into an unparseable point.
return cur;
};
// Otherwise:
! next = cur + block_size(cur);
if (!g1h->is_obj_dead(obj)) {
if (next < end || !obj->is_objArray()) {
// This object either does not span the MemRegion
// boundary, or if it does it's not an array.
*** 910,920 ****
bool is_humongous = isHumongous();
bool do_bot_verify = !is_young();
size_t object_num = 0;
while (p < top()) {
oop obj = oop(p);
! size_t obj_size = obj->size();
object_num += 1;
if (is_humongous != g1->isHumongous(obj_size)) {
gclog_or_tty->print_cr("obj "PTR_FORMAT" is of %shumongous size ("
SIZE_FORMAT" words) in a %shumongous region",
--- 910,920 ----
bool is_humongous = isHumongous();
bool do_bot_verify = !is_young();
size_t object_num = 0;
while (p < top()) {
oop obj = oop(p);
! size_t obj_size = block_size(p);
object_num += 1;
if (is_humongous != g1->isHumongous(obj_size)) {
gclog_or_tty->print_cr("obj "PTR_FORMAT" is of %shumongous size ("
SIZE_FORMAT" words) in a %shumongous region",
*** 1046,1056 ****
// G1OffsetTableContigSpace code; copied from space.cpp. Hope this can go
// away eventually.
void G1OffsetTableContigSpace::clear(bool mangle_space) {
! ContiguousSpace::clear(mangle_space);
_offsets.zero_bottom_entry();
_offsets.initialize_threshold();
}
void G1OffsetTableContigSpace::set_bottom(HeapWord* new_bottom) {
--- 1046,1057 ----
// G1OffsetTableContigSpace code; copied from space.cpp. Hope this can go
// away eventually.
void G1OffsetTableContigSpace::clear(bool mangle_space) {
! set_top(bottom());
! CompactibleSpace::clear(mangle_space);
_offsets.zero_bottom_entry();
_offsets.initialize_threshold();
}
void G1OffsetTableContigSpace::set_bottom(HeapWord* new_bottom) {
*** 1084,1094 ****
G1CollectedHeap* g1h = G1CollectedHeap::heap();
assert( _gc_time_stamp <= g1h->get_gc_time_stamp(), "invariant" );
if (_gc_time_stamp < g1h->get_gc_time_stamp())
return top();
else
! return ContiguousSpace::saved_mark_word();
}
void G1OffsetTableContigSpace::record_top_and_timestamp() {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
unsigned curr_gc_time_stamp = g1h->get_gc_time_stamp();
--- 1085,1095 ----
G1CollectedHeap* g1h = G1CollectedHeap::heap();
assert( _gc_time_stamp <= g1h->get_gc_time_stamp(), "invariant" );
if (_gc_time_stamp < g1h->get_gc_time_stamp())
return top();
else
! return Space::saved_mark_word();
}
void G1OffsetTableContigSpace::record_top_and_timestamp() {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
unsigned curr_gc_time_stamp = g1h->get_gc_time_stamp();
*** 1099,1127 ****
// set_saved_mark and before _gc_time_stamp = ..., then the latter
// will be false, and it will pick up top() as the high water mark
// of region. If it does so after _gc_time_stamp = ..., then it
// will pick up the right saved_mark_word() as the high water mark
// of the region. Either way, the behavior will be correct.
! ContiguousSpace::set_saved_mark();
OrderAccess::storestore();
_gc_time_stamp = curr_gc_time_stamp;
// No need to do another barrier to flush the writes above. If
// this is called in parallel with other threads trying to
// allocate into the region, the caller should call this while
// holding a lock and when the lock is released the writes will be
// flushed.
}
}
G1OffsetTableContigSpace::
G1OffsetTableContigSpace(G1BlockOffsetSharedArray* sharedOffsetArray,
MemRegion mr) :
_offsets(sharedOffsetArray, mr),
_par_alloc_lock(Mutex::leaf, "OffsetTableContigSpace par alloc lock", true),
_gc_time_stamp(0)
{
_offsets.set_space(this);
// false ==> we'll do the clearing if there's clearing to be done.
! ContiguousSpace::initialize(mr, false, SpaceDecorator::Mangle);
_offsets.zero_bottom_entry();
_offsets.initialize_threshold();
}
--- 1100,1150 ----
// set_saved_mark and before _gc_time_stamp = ..., then the latter
// will be false, and it will pick up top() as the high water mark
// of region. If it does so after _gc_time_stamp = ..., then it
// will pick up the right saved_mark_word() as the high water mark
// of the region. Either way, the behavior will be correct.
! Space::set_saved_mark_word(top());
OrderAccess::storestore();
_gc_time_stamp = curr_gc_time_stamp;
// No need to do another barrier to flush the writes above. If
// this is called in parallel with other threads trying to
// allocate into the region, the caller should call this while
// holding a lock and when the lock is released the writes will be
// flushed.
}
}
+ void G1OffsetTableContigSpace::safe_object_iterate(ObjectClosure* blk) {
+ object_iterate(blk);
+ }
+
+ void G1OffsetTableContigSpace::object_iterate(ObjectClosure* blk) {
+ HeapWord* p = bottom();
+ if (!block_is_obj(p)) {
+ p += block_size(p);
+ }
+ while (p < top()) {
+ blk->do_object(oop(p));
+ p += block_size(p);
+ }
+ }
+
+ #define block_is_always_obj(q) true
+ void G1OffsetTableContigSpace::prepare_for_compaction(CompactPoint* cp) {
+ SCAN_AND_FORWARD(cp, top, block_is_always_obj, block_size);
+ }
+ #undef block_is_always_obj
+
G1OffsetTableContigSpace::
G1OffsetTableContigSpace(G1BlockOffsetSharedArray* sharedOffsetArray,
MemRegion mr) :
+ _top(bottom()),
_offsets(sharedOffsetArray, mr),
_par_alloc_lock(Mutex::leaf, "OffsetTableContigSpace par alloc lock", true),
_gc_time_stamp(0)
{
_offsets.set_space(this);
// false ==> we'll do the clearing if there's clearing to be done.
! CompactibleSpace::initialize(mr, false, SpaceDecorator::Mangle);
_offsets.zero_bottom_entry();
_offsets.initialize_threshold();
}