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