diff --git a/src/hotspot/share/gc/z/zBarrier.cpp b/src/hotspot/share/gc/z/zBarrier.cpp index 970a3979a2763..93700cc28da1a 100644 --- a/src/hotspot/share/gc/z/zBarrier.cpp +++ b/src/hotspot/share/gc/z/zBarrier.cpp @@ -25,7 +25,6 @@ #include "gc/z/zBarrier.inline.hpp" #include "gc/z/zHeap.inline.hpp" #include "gc/z/zOop.inline.hpp" -#include "gc/z/zOopClosures.inline.hpp" #include "memory/iterator.inline.hpp" #include "oops/oop.inline.hpp" #include "runtime/safepoint.hpp" @@ -239,3 +238,11 @@ oop ZBarrier::weak_load_barrier_on_phantom_oop_field_preloaded(volatile narrowOo ShouldNotReachHere(); return NULL; } + +void ZLoadBarrierOopClosure::do_oop(oop* p) { + ZBarrier::load_barrier_on_oop_field(p); +} + +void ZLoadBarrierOopClosure::do_oop(narrowOop* p) { + ShouldNotReachHere(); +} diff --git a/src/hotspot/share/gc/z/zBarrier.hpp b/src/hotspot/share/gc/z/zBarrier.hpp index 0043f87988e5b..48f652b3c5de4 100644 --- a/src/hotspot/share/gc/z/zBarrier.hpp +++ b/src/hotspot/share/gc/z/zBarrier.hpp @@ -25,6 +25,7 @@ #define SHARE_GC_Z_ZBARRIER_HPP #include "memory/allocation.hpp" +#include "memory/iterator.hpp" #include "oops/oop.hpp" typedef bool (*ZBarrierFastPath)(uintptr_t); @@ -122,4 +123,10 @@ class ZBarrier : public AllStatic { static oop weak_load_barrier_on_phantom_oop_field_preloaded(volatile narrowOop* p, oop o); }; +class ZLoadBarrierOopClosure : public BasicOopIterateClosure { +public: + virtual void do_oop(oop* p); + virtual void do_oop(narrowOop* p); +}; + #endif // SHARE_GC_Z_ZBARRIER_HPP diff --git a/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp b/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp index bfb8a17e87256..7047830305ec8 100644 --- a/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp +++ b/src/hotspot/share/gc/z/zBarrierSetNMethod.cpp @@ -26,7 +26,6 @@ #include "gc/z/zBarrierSetNMethod.hpp" #include "gc/z/zGlobals.hpp" #include "gc/z/zLock.inline.hpp" -#include "gc/z/zOopClosures.hpp" #include "gc/z/zNMethod.hpp" #include "gc/z/zThreadLocalData.hpp" #include "logging/log.hpp" @@ -53,9 +52,10 @@ bool ZBarrierSetNMethod::nmethod_entry_barrier(nmethod* nm) { return false; } - // Heal oops and disarm - ZNMethodOopClosure cl; - ZNMethod::nmethod_oops_do_inner(nm, &cl); + // Heal oops + ZNMethod::nmethod_oops_barrier(nm); + + // Disarm disarm(nm); return true; diff --git a/src/hotspot/share/gc/z/zMark.cpp b/src/hotspot/share/gc/z/zMark.cpp index d4c4bbdfde50f..2519a4222407d 100644 --- a/src/hotspot/share/gc/z/zMark.cpp +++ b/src/hotspot/share/gc/z/zMark.cpp @@ -22,17 +22,19 @@ */ #include "precompiled.hpp" +#include "classfile/classLoaderData.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "code/nmethod.hpp" #include "gc/shared/suspendibleThreadSet.hpp" #include "gc/z/zBarrier.inline.hpp" +#include "gc/z/zHeap.inline.hpp" #include "gc/z/zLock.inline.hpp" #include "gc/z/zMark.inline.hpp" #include "gc/z/zMarkCache.inline.hpp" #include "gc/z/zMarkStack.inline.hpp" #include "gc/z/zMarkTerminate.inline.hpp" #include "gc/z/zNMethod.hpp" -#include "gc/z/zOopClosures.inline.hpp" +#include "gc/z/zOop.inline.hpp" #include "gc/z/zPage.hpp" #include "gc/z/zPageTable.inline.hpp" #include "gc/z/zRootsIterator.hpp" @@ -236,6 +238,26 @@ void ZMark::follow_partial_array(ZMarkStackEntry entry, bool finalizable) { follow_array(addr, size, finalizable); } +template +class ZMarkBarrierOopClosure : public ClaimMetadataVisitingOopIterateClosure { +public: + ZMarkBarrierOopClosure() : + ClaimMetadataVisitingOopIterateClosure(finalizable + ? ClassLoaderData::_claim_finalizable + : ClassLoaderData::_claim_strong, + finalizable + ? NULL + : ZHeap::heap()->reference_discoverer()) {} + + virtual void do_oop(oop* p) { + ZBarrier::mark_barrier_on_oop_field(p, finalizable); + } + + virtual void do_oop(narrowOop* p) { + ShouldNotReachHere(); + } +}; + void ZMark::follow_array_object(objArrayOop obj, bool finalizable) { if (finalizable) { ZMarkBarrierOopClosure cl; diff --git a/src/hotspot/share/gc/z/zNMethod.cpp b/src/hotspot/share/gc/z/zNMethod.cpp index ec3040e0f49ee..af657b46ee002 100644 --- a/src/hotspot/share/gc/z/zNMethod.cpp +++ b/src/hotspot/share/gc/z/zNMethod.cpp @@ -28,12 +28,12 @@ #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetNMethod.hpp" #include "gc/shared/suspendibleThreadSet.hpp" +#include "gc/z/zBarrier.inline.hpp" #include "gc/z/zGlobals.hpp" #include "gc/z/zLock.inline.hpp" #include "gc/z/zNMethod.hpp" #include "gc/z/zNMethodData.hpp" #include "gc/z/zNMethodTable.hpp" -#include "gc/z/zOopClosures.inline.hpp" #include "gc/z/zTask.hpp" #include "gc/z/zWorkers.hpp" #include "logging/log.hpp" @@ -41,6 +41,7 @@ #include "memory/iterator.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" +#include "oops/oop.inline.hpp" #include "runtime/atomic.hpp" #include "utilities/debug.hpp" @@ -243,6 +244,26 @@ void ZNMethod::nmethod_oops_do_inner(nmethod* nm, OopClosure* cl) { } } +class ZNMethodOopClosure : public OopClosure { +public: + virtual void do_oop(oop* p) { + if (ZResurrection::is_blocked()) { + ZBarrier::keep_alive_barrier_on_phantom_root_oop_field(p); + } else { + ZBarrier::load_barrier_on_root_oop_field(p); + } + } + + virtual void do_oop(narrowOop* p) { + ShouldNotReachHere(); + } +}; + +void ZNMethod::nmethod_oops_barrier(nmethod* nm) { + ZNMethodOopClosure cl; + nmethod_oops_do_inner(nm, &cl); +} + void ZNMethod::nmethods_do_begin() { ZNMethodTable::nmethods_do_begin(); } @@ -307,8 +328,7 @@ class ZNMethodUnlinkClosure : public NMethodClosure { if (ZNMethod::is_armed(nm)) { // Heal oops and disarm - ZNMethodOopClosure cl; - ZNMethod::nmethod_oops_do(nm, &cl); + ZNMethod::nmethod_oops_barrier(nm); ZNMethod::disarm(nm); } diff --git a/src/hotspot/share/gc/z/zNMethod.hpp b/src/hotspot/share/gc/z/zNMethod.hpp index ec05389b7f4d6..40ac93adb8e12 100644 --- a/src/hotspot/share/gc/z/zNMethod.hpp +++ b/src/hotspot/share/gc/z/zNMethod.hpp @@ -51,6 +51,8 @@ class ZNMethod : public AllStatic { static void nmethod_oops_do(nmethod* nm, OopClosure* cl); static void nmethod_oops_do_inner(nmethod* nm, OopClosure* cl); + static void nmethod_oops_barrier(nmethod* nm); + static void nmethods_do_begin(); static void nmethods_do_end(); static void nmethods_do(NMethodClosure* cl); diff --git a/src/hotspot/share/gc/z/zNMethodTable.cpp b/src/hotspot/share/gc/z/zNMethodTable.cpp index 2f8ccafa20138..de1d48bed17b1 100644 --- a/src/hotspot/share/gc/z/zNMethodTable.cpp +++ b/src/hotspot/share/gc/z/zNMethodTable.cpp @@ -34,7 +34,6 @@ #include "gc/z/zNMethodTable.hpp" #include "gc/z/zNMethodTableEntry.hpp" #include "gc/z/zNMethodTableIteration.hpp" -#include "gc/z/zOopClosures.inline.hpp" #include "gc/z/zSafeDelete.inline.hpp" #include "gc/z/zTask.hpp" #include "gc/z/zWorkers.hpp" diff --git a/src/hotspot/share/gc/z/zOopClosures.hpp b/src/hotspot/share/gc/z/zOopClosures.hpp deleted file mode 100644 index 32aa98a8a95f2..0000000000000 --- a/src/hotspot/share/gc/z/zOopClosures.hpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#ifndef SHARE_GC_Z_ZOOPCLOSURES_HPP -#define SHARE_GC_Z_ZOOPCLOSURES_HPP - -#include "memory/iterator.hpp" - -class ZLoadBarrierOopClosure : public BasicOopIterateClosure { -public: - virtual void do_oop(oop* p); - virtual void do_oop(narrowOop* p); -}; - -class ZNMethodOopClosure : public OopClosure { -public: - virtual void do_oop(oop* p); - virtual void do_oop(narrowOop* p); -}; - -template -class ZMarkBarrierOopClosure : public ClaimMetadataVisitingOopIterateClosure { -public: - ZMarkBarrierOopClosure(); - - virtual void do_oop(oop* p); - virtual void do_oop(narrowOop* p); -}; - -class ZPhantomIsAliveObjectClosure : public BoolObjectClosure { -public: - virtual bool do_object_b(oop o); -}; - -class ZPhantomCleanOopClosure : public OopClosure { -public: - virtual void do_oop(oop* p); - virtual void do_oop(narrowOop* p); -}; - -#endif // SHARE_GC_Z_ZOOPCLOSURES_HPP diff --git a/src/hotspot/share/gc/z/zOopClosures.inline.hpp b/src/hotspot/share/gc/z/zOopClosures.inline.hpp deleted file mode 100644 index 693e3da5e1b8a..0000000000000 --- a/src/hotspot/share/gc/z/zOopClosures.inline.hpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -#ifndef SHARE_GC_Z_ZOOPCLOSURES_INLINE_HPP -#define SHARE_GC_Z_ZOOPCLOSURES_INLINE_HPP - -#include "classfile/classLoaderData.hpp" -#include "gc/z/zBarrier.inline.hpp" -#include "gc/z/zHeap.inline.hpp" -#include "gc/z/zOop.inline.hpp" -#include "gc/z/zOopClosures.hpp" -#include "oops/oop.inline.hpp" -#include "runtime/atomic.hpp" -#include "utilities/debug.hpp" - -inline void ZLoadBarrierOopClosure::do_oop(oop* p) { - ZBarrier::load_barrier_on_oop_field(p); -} - -inline void ZLoadBarrierOopClosure::do_oop(narrowOop* p) { - ShouldNotReachHere(); -} - -inline void ZNMethodOopClosure::do_oop(oop* p) { - if (ZResurrection::is_blocked()) { - ZBarrier::keep_alive_barrier_on_phantom_root_oop_field(p); - } else { - ZBarrier::load_barrier_on_root_oop_field(p); - } -} - -inline void ZNMethodOopClosure::do_oop(narrowOop* p) { - ShouldNotReachHere(); -} - -template -inline ZMarkBarrierOopClosure::ZMarkBarrierOopClosure() : - ClaimMetadataVisitingOopIterateClosure(finalizable - ? ClassLoaderData::_claim_finalizable - : ClassLoaderData::_claim_strong, - finalizable - ? NULL - : ZHeap::heap()->reference_discoverer()) {} - -template -inline void ZMarkBarrierOopClosure::do_oop(oop* p) { - ZBarrier::mark_barrier_on_oop_field(p, finalizable); -} - -template -inline void ZMarkBarrierOopClosure::do_oop(narrowOop* p) { - ShouldNotReachHere(); -} - -inline bool ZPhantomIsAliveObjectClosure::do_object_b(oop o) { - return ZBarrier::is_alive_barrier_on_phantom_oop(o); -} - -inline void ZPhantomCleanOopClosure::do_oop(oop* p) { - // Read the oop once, to make sure the liveness check - // and the later clearing uses the same value. - const oop obj = Atomic::load(p); - if (ZBarrier::is_alive_barrier_on_phantom_oop(obj)) { - ZBarrier::keep_alive_barrier_on_phantom_oop_field(p); - } else { - // The destination could have been modified/reused, in which case - // we don't want to clear it. However, no one could write the same - // oop here again (the object would be strongly live and we would - // not consider clearing such oops), so therefore we don't have an - // ABA problem here. - Atomic::cmpxchg(p, obj, oop(NULL)); - } -} - -inline void ZPhantomCleanOopClosure::do_oop(narrowOop* p) { - ShouldNotReachHere(); -} - -#endif // SHARE_GC_Z_ZOOPCLOSURES_INLINE_HPP diff --git a/src/hotspot/share/gc/z/zReferenceProcessor.cpp b/src/hotspot/share/gc/z/zReferenceProcessor.cpp index 0a2cedd2110af..d8b65b119b6d6 100644 --- a/src/hotspot/share/gc/z/zReferenceProcessor.cpp +++ b/src/hotspot/share/gc/z/zReferenceProcessor.cpp @@ -26,7 +26,6 @@ #include "gc/shared/referencePolicy.hpp" #include "gc/shared/referenceProcessorStats.hpp" #include "gc/z/zHeap.inline.hpp" -#include "gc/z/zOopClosures.inline.hpp" #include "gc/z/zReferenceProcessor.hpp" #include "gc/z/zStat.hpp" #include "gc/z/zTask.hpp" diff --git a/src/hotspot/share/gc/z/zStackWatermark.cpp b/src/hotspot/share/gc/z/zStackWatermark.cpp index eb154fe933cd0..7280f350e8000 100644 --- a/src/hotspot/share/gc/z/zStackWatermark.cpp +++ b/src/hotspot/share/gc/z/zStackWatermark.cpp @@ -24,7 +24,6 @@ #include "precompiled.hpp" #include "gc/z/zAddress.hpp" #include "gc/z/zBarrier.inline.hpp" -#include "gc/z/zOopClosures.inline.hpp" #include "gc/z/zStackWatermark.hpp" #include "gc/z/zThread.inline.hpp" #include "gc/z/zThreadLocalAllocBuffer.hpp" diff --git a/src/hotspot/share/gc/z/zStackWatermark.hpp b/src/hotspot/share/gc/z/zStackWatermark.hpp index 43d1cf57d2a50..e40b24f4623a4 100644 --- a/src/hotspot/share/gc/z/zStackWatermark.hpp +++ b/src/hotspot/share/gc/z/zStackWatermark.hpp @@ -27,7 +27,7 @@ #include "gc/shared/barrierSet.hpp" #include "gc/shared/barrierSetNMethod.hpp" #include "gc/shared/threadLocalAllocBuffer.hpp" -#include "gc/z/zOopClosures.hpp" +#include "gc/z/zBarrier.hpp" #include "memory/allocation.hpp" #include "memory/iterator.hpp" #include "oops/oopsHierarchy.hpp" diff --git a/src/hotspot/share/gc/z/zUnload.cpp b/src/hotspot/share/gc/z/zUnload.cpp index 4bd397d006c45..072530a6c2343 100644 --- a/src/hotspot/share/gc/z/zUnload.cpp +++ b/src/hotspot/share/gc/z/zUnload.cpp @@ -29,9 +29,9 @@ #include "code/dependencyContext.hpp" #include "gc/shared/gcBehaviours.hpp" #include "gc/shared/suspendibleThreadSet.hpp" +#include "gc/z/zBarrier.inline.hpp" #include "gc/z/zLock.inline.hpp" #include "gc/z/zNMethod.hpp" -#include "gc/z/zOopClosures.inline.hpp" #include "gc/z/zStat.hpp" #include "gc/z/zUnload.hpp" #include "oops/access.inline.hpp" @@ -39,6 +39,13 @@ static const ZStatSubPhase ZSubPhaseConcurrentClassesUnlink("Concurrent Classes Unlink"); static const ZStatSubPhase ZSubPhaseConcurrentClassesPurge("Concurrent Classes Purge"); +class ZPhantomIsAliveObjectClosure : public BoolObjectClosure { +public: + virtual bool do_object_b(oop o) { + return ZBarrier::is_alive_barrier_on_phantom_oop(o); + } +}; + class ZIsUnloadingOopClosure : public OopClosure { private: ZPhantomIsAliveObjectClosure _is_alive; diff --git a/src/hotspot/share/gc/z/zWeakRootsProcessor.cpp b/src/hotspot/share/gc/z/zWeakRootsProcessor.cpp index f0a47cf8befec..21f16df39856e 100644 --- a/src/hotspot/share/gc/z/zWeakRootsProcessor.cpp +++ b/src/hotspot/share/gc/z/zWeakRootsProcessor.cpp @@ -22,11 +22,35 @@ */ #include "precompiled.hpp" -#include "gc/z/zOopClosures.inline.hpp" +#include "gc/z/zBarrier.inline.hpp" #include "gc/z/zRootsIterator.hpp" #include "gc/z/zTask.hpp" +#include "gc/z/zWeakRootsProcessor.hpp" #include "gc/z/zWorkers.hpp" +class ZPhantomCleanOopClosure : public OopClosure { +public: + virtual void do_oop(oop* p) { + // Read the oop once, to make sure the liveness check + // and the later clearing uses the same value. + const oop obj = Atomic::load(p); + if (ZBarrier::is_alive_barrier_on_phantom_oop(obj)) { + ZBarrier::keep_alive_barrier_on_phantom_oop_field(p); + } else { + // The destination could have been modified/reused, in which case + // we don't want to clear it. However, no one could write the same + // oop here again (the object would be strongly live and we would + // not consider clearing such oops), so therefore we don't have an + // ABA problem here. + Atomic::cmpxchg(p, obj, oop(NULL)); + } + } + + virtual void do_oop(narrowOop* p) { + ShouldNotReachHere(); + } +}; + ZWeakRootsProcessor::ZWeakRootsProcessor(ZWorkers* workers) : _workers(workers) {}