Skip to content

Commit f925696

Browse files
committed
8231197: Shenandoah: JVMTI heap walking cleanup crashes with NULL forwardee
Reviewed-by: zgu, rkennke
1 parent c526032 commit f925696

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,11 @@ void ShenandoahNMethod::assert_alive_and_correct() {
316316
oop *loc = _oops[c];
317317
assert(_nm->code_contains((address) loc) || _nm->oops_contains(loc), "nmethod should contain the oop*");
318318
oop o = RawAccess<>::oop_load(loc);
319-
shenandoah_assert_correct_except(loc, o, o == NULL || heap->is_full_gc_move_in_progress());
319+
shenandoah_assert_correct_except(loc, o,
320+
o == NULL ||
321+
heap->is_full_gc_move_in_progress() ||
322+
(VMThread::vm_operation() != NULL) && (VMThread::vm_operation()->type() == VM_Operation::VMOp_HeapWalkOperation)
323+
);
320324
}
321325
}
322326

src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1225,7 +1225,22 @@ class ObjectIterateScanRootClosure : public BasicOopIterateClosure {
12251225
T o = RawAccess<>::oop_load(p);
12261226
if (!CompressedOops::is_null(o)) {
12271227
oop obj = CompressedOops::decode_not_null(o);
1228-
obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
1228+
oop fwd = (oop) ShenandoahForwarding::get_forwardee_raw_unchecked(obj);
1229+
if (fwd == NULL) {
1230+
// There is an odd interaction with VM_HeapWalkOperation, see jvmtiTagMap.cpp.
1231+
//
1232+
// That operation walks the reachable objects on its own, storing the marking
1233+
// wavefront in the object marks. When it is done, it calls the CollectedHeap
1234+
// to iterate over all objects to clean up the mess. When it reaches here,
1235+
// the Shenandoah fwdptr resolution code encounters the marked objects with
1236+
// NULL forwardee. Trying to act on that would crash the VM. Or fail the
1237+
// asserts, should we go for resolve_forwarded_pointer(obj).
1238+
//
1239+
// Therefore, we have to dodge it by doing the raw access to forwardee, and
1240+
// assuming the object had no forwardee, if that thing is NULL.
1241+
} else {
1242+
obj = fwd;
1243+
}
12291244
assert(oopDesc::is_oop(obj), "must be a valid oop");
12301245
if (!_bitmap->is_marked((HeapWord*) obj)) {
12311246
_bitmap->mark((HeapWord*) obj);

0 commit comments

Comments
 (0)