8231197: Shenandoah: JVMTI heap walking cleanup crashes with NULL forwardee

Reviewed-by: zgu, rkennke
This commit is contained in:
Aleksey Shipilev 2019-09-19 20:26:51 +02:00
parent c52603204d
commit f925696a0c
2 changed files with 21 additions and 2 deletions
src/hotspot/share/gc/shenandoah

@ -316,7 +316,11 @@ void ShenandoahNMethod::assert_alive_and_correct() {
oop *loc = _oops[c];
assert(_nm->code_contains((address) loc) || _nm->oops_contains(loc), "nmethod should contain the oop*");
oop o = RawAccess<>::oop_load(loc);
shenandoah_assert_correct_except(loc, o, o == NULL || heap->is_full_gc_move_in_progress());
shenandoah_assert_correct_except(loc, o,
o == NULL ||
heap->is_full_gc_move_in_progress() ||
(VMThread::vm_operation() != NULL) && (VMThread::vm_operation()->type() == VM_Operation::VMOp_HeapWalkOperation)
);
}
}

@ -1225,7 +1225,22 @@ private:
T o = RawAccess<>::oop_load(p);
if (!CompressedOops::is_null(o)) {
oop obj = CompressedOops::decode_not_null(o);
obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
oop fwd = (oop) ShenandoahForwarding::get_forwardee_raw_unchecked(obj);
if (fwd == NULL) {
// There is an odd interaction with VM_HeapWalkOperation, see jvmtiTagMap.cpp.
//
// That operation walks the reachable objects on its own, storing the marking
// wavefront in the object marks. When it is done, it calls the CollectedHeap
// to iterate over all objects to clean up the mess. When it reaches here,
// the Shenandoah fwdptr resolution code encounters the marked objects with
// NULL forwardee. Trying to act on that would crash the VM. Or fail the
// asserts, should we go for resolve_forwarded_pointer(obj).
//
// Therefore, we have to dodge it by doing the raw access to forwardee, and
// assuming the object had no forwardee, if that thing is NULL.
} else {
obj = fwd;
}
assert(oopDesc::is_oop(obj), "must be a valid oop");
if (!_bitmap->is_marked((HeapWord*) obj)) {
_bitmap->mark((HeapWord*) obj);