# HG changeset patch # User rkennke # Date 1576161570 -3600 # Thu Dec 12 15:39:30 2019 +0100 # Node ID 991fd3849b3283bbfa479d11c7f45a0ffedf0fb7 # Parent 0acd96e392e34eb7a7adc64067e5caec646e6ee3 8234974: Shenandoah: Do concurrent roots even when no evacuation is necessary diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp @@ -264,7 +264,7 @@ } ShenandoahMarkingContext* const marking_context = _heap->marking_context(); - if (_heap->is_evacuation_in_progress() && !marking_context->is_marked(obj)) { + if (_heap->is_concurrent_root_in_progress() && !marking_context->is_marked(obj)) { Thread* thr = Thread::current(); if (thr->is_Java_thread()) { return NULL; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp --- a/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp @@ -111,12 +111,13 @@ template void ShenandoahEvacuateUpdateRootsClosure::do_oop_work(T* p) { - assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress"); + assert(_heap->is_concurrent_root_in_progress(), "Only do this when evacuation is in progress"); T o = RawAccess<>::oop_load(p); if (! CompressedOops::is_null(o)) { oop obj = CompressedOops::decode_not_null(o); 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) { @@ -139,11 +140,12 @@ } void ShenandoahEvacUpdateOopStorageRootsClosure::do_oop(oop* p) { - assert(_heap->is_evacuation_in_progress(), "Only do this when evacuation is in progress"); + 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)) { + 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) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.cpp @@ -155,7 +155,7 @@ } } -void ShenandoahCodeRoots::prepare_concurrent_unloading() { +void ShenandoahCodeRoots::arm_nmethods() { assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint"); _disarmed_value ++; // 0 is reserved for new nmethod @@ -224,7 +224,9 @@ // Heal oops and disarm ShenandoahEvacOOMScope evac_scope; - ShenandoahNMethod::heal_nmethod(nm); + if (_heap->is_evacuation_in_progress()) { + ShenandoahNMethod::heal_nmethod(nm); + } ShenandoahNMethod::disarm_nmethod(nm); // Clear compiled ICs and exception caches diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp --- a/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCodeRoots.hpp @@ -109,7 +109,7 @@ // Concurrent nmethod unloading support static void unlink(WorkGang* workers, bool unloading_occurred); static void purge(WorkGang* workers); - static void prepare_concurrent_unloading(); + static void arm_nmethods(); static int disarmed_value() { return _disarmed_value; } static int* disarmed_value_address() { return &_disarmed_value; } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -542,6 +542,7 @@ if (is_degenerated_gc_in_progress()) st->print("degenerated gc, "); if (is_full_gc_in_progress()) st->print("full gc, "); if (is_full_gc_move_in_progress()) st->print("full gc move, "); + if (is_concurrent_root_in_progress()) st->print("concurrent roots, "); if (cancelled_gc()) { st->print("cancelled"); @@ -1540,6 +1541,11 @@ _free_set->rebuild(); } + if (!is_degenerated_gc_in_progress()) { + prepare_concurrent_roots(); + prepare_concurrent_unloading(); + } + // If collection set has candidates, start evacuation. // Otherwise, bypass the rest of the cycle. if (!collection_set()->is_empty()) { @@ -1554,8 +1560,9 @@ set_has_forwarded_objects(true); if (!is_degenerated_gc_in_progress()) { - prepare_concurrent_roots(); - prepare_concurrent_unloading(); + if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { + ShenandoahCodeRoots::arm_nmethods(); + } evacuate_and_update_roots(); } @@ -1669,7 +1676,7 @@ }; void ShenandoahHeap::op_roots() { - if (is_evacuation_in_progress()) { + if (is_concurrent_root_in_progress()) { if (ShenandoahConcurrentRoots::should_do_concurrent_class_unloading()) { _unloader.unload(); } @@ -2235,7 +2242,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(); } } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahUnload.cpp @@ -79,7 +79,7 @@ public: virtual bool is_unloading(CompiledMethod* method) const { nmethod* const nm = method->as_nmethod(); - guarantee(ShenandoahHeap::heap()->is_evacuation_in_progress(), "Only this phase"); + guarantee(ShenandoahHeap::heap()->is_concurrent_root_in_progress(), "Only this phase"); ShenandoahNMethod* data = ShenandoahNMethod::gc_data(nm); ShenandoahReentrantLocker locker(data->lock()); ShenandoahIsUnloadingOopClosure cl; @@ -166,7 +166,7 @@ void ShenandoahUnload::unload() { assert(ShenandoahConcurrentRoots::can_do_concurrent_class_unloading(), "Why we here?"); - if (!ShenandoahHeap::heap()->is_evacuation_in_progress()) { + if (!ShenandoahHeap::heap()->is_concurrent_root_in_progress()) { return; }