diff --git a/src/hotspot/share/gc/z/zDriver.cpp b/src/hotspot/share/gc/z/zDriver.cpp index a4353f6..e5dbf5e 100644 --- a/src/hotspot/share/gc/z/zDriver.cpp +++ b/src/hotspot/share/gc/z/zDriver.cpp @@ -336,6 +336,7 @@ void ZDriver::run_gc_cycle(GCCause::Cause cause) { // Phase 2: Concurrent Mark { ZStatTimer timer(ZPhaseConcurrentMark); + ZHeap::heap()->mark_concurrent_roots(); ZHeap::heap()->mark(); } diff --git a/src/hotspot/share/gc/z/zHeap.cpp b/src/hotspot/share/gc/z/zHeap.cpp index e6d9f19..9b517d8 100644 --- a/src/hotspot/share/gc/z/zHeap.cpp +++ b/src/hotspot/share/gc/z/zHeap.cpp @@ -296,6 +296,10 @@ void ZHeap::mark_start() { ZStatHeap::set_at_mark_start(capacity(), used()); } +void ZHeap::mark_concurrent_roots() { + _mark.mark_concurrent_roots(); +} + void ZHeap::mark() { _mark.mark(); } diff --git a/src/hotspot/share/gc/z/zHeap.hpp b/src/hotspot/share/gc/z/zHeap.hpp index 5ea4b36..7ec02fb 100644 --- a/src/hotspot/share/gc/z/zHeap.hpp +++ b/src/hotspot/share/gc/z/zHeap.hpp @@ -133,6 +133,7 @@ public: bool is_object_strongly_live(uintptr_t addr) const; template void mark_object(uintptr_t addr); void mark_start(); + void mark_concurrent_roots(); void mark(); void mark_flush_and_free(Thread* thread); bool mark_end(); diff --git a/src/hotspot/share/gc/z/zHeapIterator.cpp b/src/hotspot/share/gc/z/zHeapIterator.cpp index 241f5f8..932e0af 100644 --- a/src/hotspot/share/gc/z/zHeapIterator.cpp +++ b/src/hotspot/share/gc/z/zHeapIterator.cpp @@ -185,6 +185,7 @@ bool ZHeapIterator::visit_referents() const { void ZHeapIterator::objects_do(ObjectClosure* cl) { ZHeapIteratorRootOopClosure root_cl(this, cl); ZRootsIterator roots; + ZConcurrentRootsIterator concurrent_roots; // Follow roots. Note that we also visit the JVMTI weak tag map // as if they were strong roots to make sure we visit all tagged @@ -192,4 +193,5 @@ void ZHeapIterator::objects_do(ObjectClosure* cl) { // If we didn't do this the user would have expected to see // ObjectFree events for unreachable objects in the tag map. roots.oops_do(&root_cl, true /* visit_jvmti_weak_export */); + concurrent_roots.oops_do(&root_cl); } diff --git a/src/hotspot/share/gc/z/zMark.cpp b/src/hotspot/share/gc/z/zMark.cpp index 4f19fc4..d93fdad 100644 --- a/src/hotspot/share/gc/z/zMark.cpp +++ b/src/hotspot/share/gc/z/zMark.cpp @@ -140,6 +140,24 @@ public: } }; +class ZMarkConcurrentRootsTask : public ZTask { +private: + ZMark* const _mark; + ZConcurrentRootsIterator _roots; + +public: + ZMarkConcurrentRootsTask(ZMark* mark) : + ZTask("ZMarkConcurrentRootsTask"), + _mark(mark), + _roots() {} + + virtual void work() { + ZMarkBarrierOopClosure cl; + _roots.oops_do(&cl); + } +}; + + void ZMark::start() { // Verification if (ZVerifyMarking) { @@ -154,6 +172,11 @@ void ZMark::start() { _workers->run_parallel(&task); } +void ZMark::mark_concurrent_roots() { + ZMarkConcurrentRootsTask task(this); + _workers->run_concurrent(&task); +} + void ZMark::prepare_work() { assert(_nworkers == _workers->nconcurrent(), "Invalid number of workers"); diff --git a/src/hotspot/share/gc/z/zMark.hpp b/src/hotspot/share/gc/z/zMark.hpp index 727d9d9..262088a 100644 --- a/src/hotspot/share/gc/z/zMark.hpp +++ b/src/hotspot/share/gc/z/zMark.hpp @@ -108,6 +108,7 @@ public: template void mark_object(uintptr_t addr); void start(); + void mark_concurrent_roots(); void mark(); bool end(); diff --git a/src/hotspot/share/gc/z/zRootsIterator.cpp b/src/hotspot/share/gc/z/zRootsIterator.cpp index 751d268..93574bd 100644 --- a/src/hotspot/share/gc/z/zRootsIterator.cpp +++ b/src/hotspot/share/gc/z/zRootsIterator.cpp @@ -52,16 +52,20 @@ static const ZStatSubPhase ZSubPhasePauseRootsSetup("Pause Roots Setup"); static const ZStatSubPhase ZSubPhasePauseRoots("Pause Roots"); static const ZStatSubPhase ZSubPhasePauseRootsTeardown("Pause Roots Teardown"); static const ZStatSubPhase ZSubPhasePauseRootsUniverse("Pause Roots Universe"); -static const ZStatSubPhase ZSubPhasePauseRootsJNIHandles("Pause Roots JNIHandles"); static const ZStatSubPhase ZSubPhasePauseRootsObjectSynchronizer("Pause Roots ObjectSynchronizer"); static const ZStatSubPhase ZSubPhasePauseRootsManagement("Pause Roots Management"); static const ZStatSubPhase ZSubPhasePauseRootsJVMTIExport("Pause Roots JVMTIExport"); static const ZStatSubPhase ZSubPhasePauseRootsJVMTIWeakExport("Pause Roots JVMTIWeakExport"); static const ZStatSubPhase ZSubPhasePauseRootsSystemDictionary("Pause Roots SystemDictionary"); -static const ZStatSubPhase ZSubPhasePauseRootsClassLoaderDataGraph("Pause Roots ClassLoaderDataGraph"); static const ZStatSubPhase ZSubPhasePauseRootsThreads("Pause Roots Threads"); static const ZStatSubPhase ZSubPhasePauseRootsCodeCache("Pause Roots CodeCache"); +static const ZStatSubPhase ZSubPhaseConcurrentRootsSetup("Concurrent Roots Setup"); +static const ZStatSubPhase ZSubPhaseConcurrentRoots("Concurrent Roots"); +static const ZStatSubPhase ZSubPhaseConcurrentRootsTeardown("Concurrent Roots Teardown"); +static const ZStatSubPhase ZSubPhaseConcurrentRootsJNIHandles("Concurrent Roots JNIHandles"); +static const ZStatSubPhase ZSubPhaseConcurrentRootsClassLoaderDataGraph("Concurrent Roots ClassLoaderDataGraph"); + static const ZStatSubPhase ZSubPhasePauseWeakRootsSetup("Pause Weak Roots Setup"); static const ZStatSubPhase ZSubPhasePauseWeakRoots("Pause Weak Roots"); static const ZStatSubPhase ZSubPhasePauseWeakRootsTeardown("Pause Weak Roots Teardown"); @@ -128,15 +132,12 @@ void ZParallelWeakOopsDo::weak_oops_do(BoolObjectClosure* is_alive, OopClo } ZRootsIterator::ZRootsIterator() : - _jni_handles_iter(JNIHandles::global_handles()), _universe(this), _object_synchronizer(this), _management(this), _jvmti_export(this), _jvmti_weak_export(this), _system_dictionary(this), - _jni_handles(this), - _class_loader_data_graph(this), _threads(this), _code_cache(this) { assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint"); @@ -163,11 +164,6 @@ void ZRootsIterator::do_universe(OopClosure* cl) { Universe::oops_do(cl); } -void ZRootsIterator::do_jni_handles(OopClosure* cl) { - ZStatTimer timer(ZSubPhasePauseRootsJNIHandles); - _jni_handles_iter.oops_do(cl); -} - void ZRootsIterator::do_object_synchronizer(OopClosure* cl) { ZStatTimer timer(ZSubPhasePauseRootsObjectSynchronizer); ObjectSynchronizer::oops_do(cl); @@ -194,12 +190,6 @@ void ZRootsIterator::do_system_dictionary(OopClosure* cl) { SystemDictionary::oops_do(cl); } -void ZRootsIterator::do_class_loader_data_graph(OopClosure* cl) { - ZStatTimer timer(ZSubPhasePauseRootsClassLoaderDataGraph); - CLDToOopClosure cld_cl(cl); - ClassLoaderDataGraph::cld_do(&cld_cl); -} - class ZRootsIteratorThreadClosure : public ThreadClosure { private: OopClosure* const _cl; @@ -238,8 +228,6 @@ void ZRootsIterator::oops_do(OopClosure* cl, bool visit_jvmti_weak_export) { _management.oops_do(cl); _jvmti_export.oops_do(cl); _system_dictionary.oops_do(cl); - _jni_handles.oops_do(cl); - _class_loader_data_graph.oops_do(cl); _threads.oops_do(cl); _code_cache.oops_do(cl); if (visit_jvmti_weak_export) { @@ -247,6 +235,34 @@ void ZRootsIterator::oops_do(OopClosure* cl, bool visit_jvmti_weak_export) { } } +ZConcurrentRootsIterator::ZConcurrentRootsIterator() + : _jni_handles_iter(JNIHandles::global_handles()), + _jni_handles(this), + _class_loader_data_graph(this) { + ZStatTimer timer(ZSubPhaseConcurrentRootsSetup); +} + +ZConcurrentRootsIterator::~ZConcurrentRootsIterator() { + ZStatTimer timer(ZSubPhaseConcurrentRootsTeardown); +} + +void ZConcurrentRootsIterator::do_jni_handles(OopClosure* cl) { + ZStatTimer timer(ZSubPhaseConcurrentRootsJNIHandles); + _jni_handles_iter.oops_do(cl); +} + +void ZConcurrentRootsIterator::do_class_loader_data_graph(OopClosure* cl) { + ZStatTimer timer(ZSubPhaseConcurrentRootsClassLoaderDataGraph); + CLDToOopClosure cld_cl(cl); + ClassLoaderDataGraph::cld_do(&cld_cl); +} + +void ZConcurrentRootsIterator::oops_do(OopClosure* cl) { + ZStatTimer timer(ZSubPhaseConcurrentRoots); + _jni_handles.oops_do(cl); + _class_loader_data_graph.oops_do(cl); +} + ZWeakRootsIterator::ZWeakRootsIterator() : _jvmti_weak_export(this), _jfr_weak(this) { diff --git a/src/hotspot/share/gc/z/zRootsIterator.hpp b/src/hotspot/share/gc/z/zRootsIterator.hpp index 9a759a8..8fcd48f 100644 --- a/src/hotspot/share/gc/z/zRootsIterator.hpp +++ b/src/hotspot/share/gc/z/zRootsIterator.hpp @@ -78,16 +78,12 @@ public: class ZRootsIterator { private: - ZOopStorageIterator _jni_handles_iter; - void do_universe(OopClosure* cl); - void do_jni_handles(OopClosure* cl); void do_object_synchronizer(OopClosure* cl); void do_management(OopClosure* cl); void do_jvmti_export(OopClosure* cl); void do_jvmti_weak_export(OopClosure* cl); void do_system_dictionary(OopClosure* cl); - void do_class_loader_data_graph(OopClosure* cl); void do_threads(OopClosure* cl); void do_code_cache(OopClosure* cl); @@ -97,8 +93,6 @@ private: ZSerialOopsDo _jvmti_export; ZSerialOopsDo _jvmti_weak_export; ZSerialOopsDo _system_dictionary; - ZParallelOopsDo _jni_handles; - ZParallelOopsDo _class_loader_data_graph; ZParallelOopsDo _threads; ZParallelOopsDo _code_cache; @@ -109,6 +103,23 @@ public: void oops_do(OopClosure* cl, bool visit_jvmti_weak_export = false); }; +class ZConcurrentRootsIterator { +private: + ZConcurrentOopStorageIterator _jni_handles_iter; + + void do_jni_handles(OopClosure* cl); + void do_class_loader_data_graph(OopClosure* cl); + + ZParallelOopsDo _jni_handles; + ZParallelOopsDo _class_loader_data_graph; + +public: + ZConcurrentRootsIterator(); + ~ZConcurrentRootsIterator(); + + void oops_do(OopClosure* cl); +}; + class ZWeakRootsIterator { private: void do_jvmti_weak_export(BoolObjectClosure* is_alive, OopClosure* cl);