--- old/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp 2019-12-11 23:05:19.893009903 +0100 +++ new/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp 2019-12-11 23:05:19.785009899 +0100 @@ -265,7 +265,12 @@ ShenandoahMarkingContext* const marking_context = _heap->marking_context(); if (_heap->is_concurrent_root_in_progress() && !marking_context->is_marked(obj)) { - return NULL; + Thread* thr = Thread::current(); + if (thr->is_Java_thread()) { + return NULL; + } else { + return obj; + } } oop fwd = load_reference_barrier_not_null(obj); --- old/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp 2019-12-11 23:05:20.489009925 +0100 +++ new/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetNMethod.cpp 2019-12-11 23:05:20.381009921 +0100 @@ -57,10 +57,8 @@ } // Heal oops and disarm - if (ShenandoahHeap::heap()->is_evacuation_in_progress()) { - ShenandoahEvacOOMScope scope; - ShenandoahNMethod::heal_nmethod(nm); - } + ShenandoahEvacOOMScope scope; + ShenandoahNMethod::heal_nmethod(nm); ShenandoahNMethod::disarm_nmethod(nm); return true; } --- old/src/hotspot/share/gc/shenandoah/shenandoahClosures.hpp 2019-12-11 23:05:21.076009947 +0100 +++ new/src/hotspot/share/gc/shenandoah/shenandoahClosures.hpp 2019-12-11 23:05:20.968009943 +0100 @@ -94,12 +94,13 @@ inline void do_oop_work(T* p); }; -class ShenandoahEvacUpdateOopStorageRootsClosure : public BasicOopIterateClosure { +class ShenandoahEvacUpdateCleanupRootsClosure : public BasicOopIterateClosure { private: ShenandoahHeap* _heap; Thread* _thread; + const ShenandoahMarkingContext* const _context; public: - inline ShenandoahEvacUpdateOopStorageRootsClosure(); + inline ShenandoahEvacUpdateCleanupRootsClosure(); inline void do_oop(oop* p); inline void do_oop(narrowOop* p); }; --- old/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp 2019-12-11 23:05:21.667009969 +0100 +++ new/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp 2019-12-11 23:05:21.562009965 +0100 @@ -135,29 +135,30 @@ do_oop_work(p); } -ShenandoahEvacUpdateOopStorageRootsClosure::ShenandoahEvacUpdateOopStorageRootsClosure() : - _heap(ShenandoahHeap::heap()), _thread(Thread::current()) { +ShenandoahEvacUpdateCleanupRootsClosure::ShenandoahEvacUpdateCleanupRootsClosure() : + _heap(ShenandoahHeap::heap()), _thread(Thread::current()), _context(_heap->complete_marking_context()) { } -void ShenandoahEvacUpdateOopStorageRootsClosure::do_oop(oop* p) { +void ShenandoahEvacUpdateCleanupRootsClosure::do_oop(oop* p) { assert(_heap->is_concurrent_root_in_progress(), "Only do this when evacuation is in progress"); oop obj = RawAccess<>::oop_load(p); if (! CompressedOops::is_null(obj)) { - if (_heap->in_collection_set(obj)) { + if (!_context->is_marked(obj)) { + Atomic::cmpxchg(p, obj, (oop)NULL); + } else if (_heap->in_collection_set(obj)) { assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress"); shenandoah_assert_marked(p, obj); oop resolved = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); if (resolved == obj) { resolved = _heap->evacuate_object(obj, _thread); } - Atomic::cmpxchg(p, obj, resolved); } } } -void ShenandoahEvacUpdateOopStorageRootsClosure::do_oop(narrowOop* p) { +void ShenandoahEvacUpdateCleanupRootsClosure::do_oop(narrowOop* p) { ShouldNotReachHere(); } --- old/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2019-12-11 23:05:22.263009992 +0100 +++ new/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2019-12-11 23:05:22.152009987 +0100 @@ -1555,6 +1555,10 @@ verifier()->verify_before_evacuation(); } + if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { + ShenandoahCodeRoots::prepare_concurrent_unloading(); + } + set_evacuation_in_progress(true); // From here on, we need to update references. set_has_forwarded_objects(true); @@ -1656,16 +1660,10 @@ void work(uint worker_id) { ShenandoahEvacOOMScope oom; + ShenandoahEvacUpdateCleanupRootsClosure cl; { - // jni_roots and weak_roots are OopStorage backed roots, concurrent iteration - // may race against OopStorage::release() calls. - ShenandoahEvacUpdateOopStorageRootsClosure cl; - _vm_roots.oops_do(&cl); - _weak_roots.oops_do(&cl); - } - - { - ShenandoahEvacuateUpdateRootsClosure cl; + _vm_roots.oops_do<>(&cl); + _weak_roots.oops_do<>(&cl); CLDToOopClosure clds(&cl, ClassLoaderData::_claim_strong); _cld_roots.cld_do(&clds); } @@ -1674,14 +1672,13 @@ void ShenandoahHeap::op_roots() { if (is_concurrent_root_in_progress()) { - if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { - _unloader.unload(); - } - - if (ShenandoahConcurrentRoots::should_do_concurrent_roots() && is_concurrent_root_in_progress()) { + if (ShenandoahConcurrentRoots::should_do_concurrent_roots()) { ShenandoahConcurrentRootsEvacUpdateTask task; workers()->run_task(&task); } + if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { + _unloader.unload(); + } } set_concurrent_root_in_progress(false); @@ -2239,7 +2236,6 @@ void ShenandoahHeap::prepare_concurrent_unloading() { assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { - ShenandoahCodeRoots::prepare_concurrent_unloading(); _unloader.prepare(); } }