< prev index next >
src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
Print this page
rev 57589 : 8237632: Shenandoah fails some vmTestbase_nsk_jvmti tests with "Forwardee must point to a heap address"
*** 1225,1266 ****
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((HeapWord*) obj)) {
_bitmap->mark((HeapWord*) 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); }
};
/*
--- 1225,1265 ----
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);
!
! // In concurrent roots phase, there are dead oops in weak roots.
! if (_heap->is_concurrent_root_in_progress() &&
! !_marking_context->is_marked(obj)) {
! return;
}
+
+ // Only oops in collection set have forwarding pointers
+ if (_heap->in_collection_set(obj)) {
+ obj = (oop) ShenandoahForwarding::get_forwardee_raw_unchecked(obj);
+ }
+
assert(oopDesc::is_oop(obj), "must be a valid oop");
if (!_bitmap->is_marked((HeapWord*) obj)) {
_bitmap->mark((HeapWord*) 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(ShenandoahHeap::heap()->marking_context()) {}
void do_oop(oop* p) { do_oop_work(p); }
void do_oop(narrowOop* p) { do_oop_work(p); }
};
/*
*** 1301,1319 ****
Stack<oop,mtGC> oop_stack;
// 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);
-
- // If we are unloading classes right now, we should not touch weak roots,
- // on the off-chance we would evacuate them and make them live accidentally.
- // In other cases, we have to scan all roots.
- if (is_evacuation_in_progress() && unload_classes()) {
- 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");
--- 1300,1310 ----
*** 2078,2096 ****
ShenandoahPhaseTimings::purge_par;
// Cleanup weak roots
ShenandoahGCPhase phase(timing_phase);
if (has_forwarded_objects()) {
if (is_traversal_mode()) {
! ShenandoahForwardedIsAliveClosure is_alive;
ShenandoahTraversalUpdateRefsClosure keep_alive;
! ShenandoahParallelWeakRootsCleaningTask<ShenandoahForwardedIsAliveClosure, ShenandoahTraversalUpdateRefsClosure>
cleaning_task(&is_alive, &keep_alive, num_workers);
_workers->run_task(&cleaning_task);
} else {
! ShenandoahForwardedIsAliveClosure is_alive;
ShenandoahUpdateRefsClosure keep_alive;
! ShenandoahParallelWeakRootsCleaningTask<ShenandoahForwardedIsAliveClosure, ShenandoahUpdateRefsClosure>
cleaning_task(&is_alive, &keep_alive, num_workers);
_workers->run_task(&cleaning_task);
}
} else {
ShenandoahIsAliveClosure is_alive;
--- 2069,2087 ----
ShenandoahPhaseTimings::purge_par;
// Cleanup weak roots
ShenandoahGCPhase phase(timing_phase);
if (has_forwarded_objects()) {
if (is_traversal_mode()) {
! ShenandoahForwardedIsAliveNoCSetCheckClosure is_alive;
ShenandoahTraversalUpdateRefsClosure keep_alive;
! ShenandoahParallelWeakRootsCleaningTask<ShenandoahForwardedIsAliveNoCSetCheckClosure, ShenandoahTraversalUpdateRefsClosure>
cleaning_task(&is_alive, &keep_alive, num_workers);
_workers->run_task(&cleaning_task);
} else {
! ShenandoahForwardedIsAliveNoCSetCheckClosure is_alive;
ShenandoahUpdateRefsClosure keep_alive;
! ShenandoahParallelWeakRootsCleaningTask<ShenandoahForwardedIsAliveNoCSetCheckClosure, ShenandoahUpdateRefsClosure>
cleaning_task(&is_alive, &keep_alive, num_workers);
_workers->run_task(&cleaning_task);
}
} else {
ShenandoahIsAliveClosure is_alive;
< prev index next >