< prev index next >
src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
Print this page
rev 58162 : 8237632: Shenandoah fails some vmTestbase_nsk_jvmti tests with "Forwardee must point to a heap address"
*** 1228,1269 ****
class ObjectIterateScanRootClosure : public BasicOopIterateClosure {
private:
MarkBitMap* _bitmap;
Stack<oop,mtGC>* _oop_stack;
template <class T>
void do_oop_work(T* p) {
T o = RawAccess<>::oop_load(p);
if (!CompressedOops::is_null(o)) {
oop obj = CompressedOops::decode_not_null(o);
! 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(obj)) {
_bitmap->mark(obj);
_oop_stack->push(obj);
}
}
}
public:
ObjectIterateScanRootClosure(MarkBitMap* bitmap, Stack<oop,mtGC>* oop_stack) :
! _bitmap(bitmap), _oop_stack(oop_stack) {}
void do_oop(oop* p) { do_oop_work(p); }
void do_oop(narrowOop* p) { do_oop_work(p); }
};
/*
--- 1228,1262 ----
class ObjectIterateScanRootClosure : public BasicOopIterateClosure {
private:
MarkBitMap* _bitmap;
Stack<oop,mtGC>* _oop_stack;
+ ShenandoahHeap* const _heap;
+ ShenandoahMarkingContext* const _marking_context;
template <class T>
void do_oop_work(T* p) {
T o = RawAccess<>::oop_load(p);
if (!CompressedOops::is_null(o)) {
oop obj = CompressedOops::decode_not_null(o);
! if (_heap->is_concurrent_root_in_progress() && !_marking_context->is_marked(obj)) {
! // There may be dead oops in weak roots in concurrent root phase, do not touch them.
! return;
}
+ obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
+
assert(oopDesc::is_oop(obj), "must be a valid oop");
if (!_bitmap->is_marked(obj)) {
_bitmap->mark(obj);
_oop_stack->push(obj);
}
}
}
public:
ObjectIterateScanRootClosure(MarkBitMap* bitmap, Stack<oop,mtGC>* oop_stack) :
! _bitmap(bitmap), _oop_stack(oop_stack), _heap(ShenandoahHeap::heap()),
! _marking_context(_heap->marking_context()) {}
void do_oop(oop* p) { do_oop_work(p); }
void do_oop(narrowOop* p) { do_oop_work(p); }
};
/*
*** 1305,1321 ****
// First, we process GC roots according to current GC cycle. This populates the work stack with initial objects.
ShenandoahHeapIterationRootScanner rp;
ObjectIterateScanRootClosure oops(&_aux_bit_map, &oop_stack);
- // When concurrent root is in progress, weak roots may contain dead oops, they should not be used
- // for root scanning.
- if (is_concurrent_root_in_progress()) {
- rp.strong_roots_do(&oops);
- } else {
rp.roots_do(&oops);
- }
// Work through the oop stack to traverse heap.
while (! oop_stack.is_empty()) {
oop obj = oop_stack.pop();
assert(oopDesc::is_oop(obj), "must be a valid oop");
--- 1298,1308 ----
< prev index next >