OpenJDK / jdk / jdk
changeset 56315:13e041be4e5c
8231197: Shenandoah: JVMTI heap walking cleanup crashes with NULL forwardee
Reviewed-by: zgu, rkennke
author | shade |
---|---|
date | Thu, 19 Sep 2019 20:26:51 +0200 |
parents | 0ff1aeedc338 |
children | de9d23469c68 |
files | src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp |
diffstat | 2 files changed, 21 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp Thu Sep 19 16:53:17 2019 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp Thu Sep 19 20:26:51 2019 +0200 @@ -316,7 +316,11 @@ 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) + ); } }
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Thu Sep 19 16:53:17 2019 +0000 +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Thu Sep 19 20:26:51 2019 +0200 @@ -1225,7 +1225,22 @@ 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);