--- old/src/share/vm/gc/g1/g1ConcurrentMark.cpp 2017-07-20 16:27:13.945748353 +0200 +++ new/src/share/vm/gc/g1/g1ConcurrentMark.cpp 2017-07-20 16:27:13.845745251 +0200 @@ -2716,11 +2716,9 @@ // points to the address of the object we last scanned. If we // leave it there, when we restart this task, we will rescan // the object. It is easy to avoid this. We move the finger by - // enough to point to the next possible object header (the - // bitmap knows by how much we need to move it as it knows its - // granularity). + // enough to point to the next possible object header. assert(_finger < _region_limit, "invariant"); - HeapWord* new_finger = _nextMarkBitMap->addr_after_obj(_finger); + HeapWord* const new_finger = _finger + ((oop)_finger)->size(); // Check if bitmap iteration was aborted while scanning the last object if (new_finger >= _region_limit) { giveup_current_region(); --- old/src/share/vm/gc/g1/g1ConcurrentMark.hpp 2017-07-20 16:27:14.542766874 +0200 +++ new/src/share/vm/gc/g1/g1ConcurrentMark.hpp 2017-07-20 16:27:14.440763709 +0200 @@ -113,8 +113,8 @@ // Closure for iteration over bitmaps class G1CMBitMapClosure VALUE_OBJ_CLASS_SPEC { private: - G1ConcurrentMark* _cm; - G1CMTask* _task; + G1ConcurrentMark* const _cm; + G1CMTask* const _task; public: G1CMBitMapClosure(G1CMTask *task, G1ConcurrentMark* cm) : _task(task), _cm(cm) { } --- old/src/share/vm/gc/g1/g1ConcurrentMark.inline.hpp 2017-07-20 16:27:15.098784122 +0200 +++ new/src/share/vm/gc/g1/g1ConcurrentMark.inline.hpp 2017-07-20 16:27:15.000781082 +0200 @@ -37,45 +37,31 @@ } inline bool G1CMBitMap::iterate(G1CMBitMapClosure* cl, MemRegion mr) { - HeapWord* start_addr = MAX2(_covered.start(), mr.start()); - HeapWord* const end_addr = MIN2(_covered.end(), mr.end()); + assert(!mr.is_empty(), "Does not support empty memregion to iterate over"); + assert(_covered.contains(mr), "Given MemRegion from " PTR_FORMAT " to " PTR_FORMAT " not contained in heap area", p2i(mr.start()), p2i(mr.end())); - if (end_addr > start_addr) { - // Right-open interval [start-offset, end-offset). - BitMap::idx_t start_offset = addr_to_offset(start_addr); - BitMap::idx_t const end_offset = addr_to_offset(end_addr); + BitMap::idx_t const end_offset = addr_to_offset(mr.end()); + BitMap::idx_t offset = _bm.get_next_one_offset(addr_to_offset(mr.start()), end_offset); - start_offset = _bm.get_next_one_offset(start_offset, end_offset); - while (start_offset < end_offset) { - start_addr = offset_to_addr(start_offset); - if (!cl->do_addr(start_addr)) { - return false; - } - HeapWord* next_addr = MIN2(addr_after_obj(start_addr), end_addr); - BitMap::idx_t const next_offset = addr_to_offset(next_addr); - start_offset = _bm.get_next_one_offset(next_offset, end_offset); + while (offset < end_offset) { + HeapWord* const addr = offset_to_addr(offset); + if (!cl->do_addr(addr)) { + return false; } + size_t const obj_size = (size_t)((oop)addr)->size(); + offset = _bm.get_next_one_offset(offset + (obj_size >> _shifter), end_offset); } return true; } inline HeapWord* G1CMBitMap::get_next_marked_addr(const HeapWord* addr, const HeapWord* limit) const { - // First we must round addr *up* to a possible object boundary. - addr = (HeapWord*)align_up(addr, HeapWordSize << _shifter); - size_t addrOffset = addr_to_offset(addr); assert(limit != NULL, "limit must not be NULL"); - size_t limitOffset = addr_to_offset(limit); - size_t nextOffset = _bm.get_next_one_offset(addrOffset, limitOffset); - HeapWord* nextAddr = offset_to_addr(nextOffset); - assert(nextAddr >= addr, "get_next_one postcondition"); - assert(nextAddr == limit || is_marked(nextAddr), - "get_next_one postcondition"); - return nextAddr; -} - -inline HeapWord* G1CMBitMap::addr_after_obj(HeapWord* addr) { - return addr + ((oop)addr)->size(); + // Round addr up to a possible object boundary to be safe. + size_t const addr_offset = addr_to_offset(align_up(addr, HeapWordSize << _shifter)); + size_t const limit_offset = addr_to_offset(limit); + size_t const nextOffset = _bm.get_next_one_offset(addr_offset, limit_offset); + return offset_to_addr(nextOffset); } #ifdef ASSERT