--- old/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 2014-02-19 15:35:14.452888910 +0100 +++ new/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 2014-02-19 15:35:14.344888912 +0100 @@ -4789,40 +4789,45 @@ template template void G1ParCopyClosure::do_oop_work(T* p) { - oop obj = oopDesc::load_decode_heap_oop(p); + T heap_oop = oopDesc::load_heap_oop(p); - assert(_worker_id == _par_scan_state->queue_num(), "sanity"); + if (!oopDesc::is_null(heap_oop)) { + oop obj = oopDesc::load_decode_heap_oop_not_null(p); - // here the null check is implicit in the cset_fast_test() test - if (_g1->in_cset_fast_test(obj)) { - oop forwardee; - if (obj->is_forwarded()) { - forwardee = obj->forwardee(); + assert(_worker_id == _par_scan_state->queue_num(), "sanity"); + + if (_g1->in_cset_fast_test(obj)) { + oop forwardee; + if (obj->is_forwarded()) { + forwardee = obj->forwardee(); + } else { + forwardee = copy_to_survivor_space(obj); + } + assert(forwardee != NULL, "forwardee should not be NULL"); + oopDesc::encode_store_heap_oop(p, forwardee); + if (do_mark_object && forwardee != obj) { + // If the object is self-forwarded we don't need to explicitly + // mark it, the evacuation failure protocol will do so. + mark_forwarded_object(obj, forwardee); + } + + if (barrier == G1BarrierKlass) { + do_klass_barrier(p, forwardee); + } } else { - forwardee = copy_to_survivor_space(obj); - } - assert(forwardee != NULL, "forwardee should not be NULL"); - oopDesc::encode_store_heap_oop(p, forwardee); - if (do_mark_object && forwardee != obj) { - // If the object is self-forwarded we don't need to explicitly - // mark it, the evacuation failure protocol will do so. - mark_forwarded_object(obj, forwardee); + // The object is not in collection set. If we're a root scanning + // closure during an initial mark pause (i.e. do_mark_object will + // be true) then attempt to mark the object. + if (do_mark_object) { + assert(_g1->is_in_g1_reserved(obj), "Must reference an object within the heap"); + mark_object(obj); + } } - if (barrier == G1BarrierKlass) { - do_klass_barrier(p, forwardee); + if (barrier == G1BarrierEvac) { + assert(obj != NULL, "must be"); + _par_scan_state->update_rs(_from, p, _worker_id); } - } else { - // The object is not in collection set. If we're a root scanning - // closure during an initial mark pause (i.e. do_mark_object will - // be true) then attempt to mark the object. - if (do_mark_object && _g1->is_in_g1_reserved(obj)) { - mark_object(obj); - } - } - - if (barrier == G1BarrierEvac && obj != NULL) { - _par_scan_state->update_rs(_from, p, _worker_id); } } --- old/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp 2014-02-19 15:35:15.088888897 +0100 +++ new/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp 2014-02-19 15:35:14.984888899 +0100 @@ -698,23 +698,20 @@ } // This is a fast test on whether a reference points into the - // collection set or not. It does not assume that the reference - // points into the heap; if it doesn't, it will return false. + // collection set or not. Assume that the reference + // points into the heap. bool in_cset_fast_test(oop obj) { assert(_in_cset_fast_test != NULL, "sanity"); - if (_g1_committed.contains((HeapWord*) obj)) { - // no need to subtract the bottom of the heap from obj, - // _in_cset_fast_test is biased - uintx index = cast_from_oop(obj) >> HeapRegion::LogOfHRGrainBytes; - bool ret = _in_cset_fast_test[index]; - // let's make sure the result is consistent with what the slower - // test returns - assert( ret || !obj_in_cs(obj), "sanity"); - assert(!ret || obj_in_cs(obj), "sanity"); - return ret; - } else { - return false; - } + assert(_g1_committed.contains((HeapWord*) obj), ""); + // no need to subtract the bottom of the heap from obj, + // _in_cset_fast_test is biased + uintx index = cast_from_oop(obj) >> HeapRegion::LogOfHRGrainBytes; + bool ret = _in_cset_fast_test[index]; + // let's make sure the result is consistent with what the slower + // test returns + assert( ret || !obj_in_cs(obj), "sanity"); + assert(!ret || obj_in_cs(obj), "sanity"); + return ret; } void clear_cset_fast_test() {