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(); }