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