# HG changeset patch # User rkennke # Date 1537535984 -7200 # Fri Sep 21 15:19:44 2018 +0200 # Node ID 7075300b6c8f3662bfecbcec6bff660b41358f50 # Parent 1ecc914fb707f18988e873dbee8bd79f1261b4b6 imported patch nmethod-marking.patch diff --git a/src/hotspot/share/runtime/safepoint.cpp b/src/hotspot/share/runtime/safepoint.cpp --- a/src/hotspot/share/runtime/safepoint.cpp +++ b/src/hotspot/share/runtime/safepoint.cpp @@ -598,7 +598,8 @@ public: ParallelSPCleanupThreadClosure(DeflateMonitorCounters* counters) : - _nmethod_cl(NMethodSweeper::prepare_mark_active_nmethods()), _counters(counters) {} + _nmethod_cl(ThreadLocalHandshakes ? NULL : NMethodSweeper::prepare_mark_active_nmethods()), + _counters(counters) {} void do_thread(Thread* thread) { ObjectSynchronizer::deflate_thread_local_monitors(thread, _counters); diff --git a/src/hotspot/share/runtime/sweeper.cpp b/src/hotspot/share/runtime/sweeper.cpp --- a/src/hotspot/share/runtime/sweeper.cpp +++ b/src/hotspot/share/runtime/sweeper.cpp @@ -251,6 +251,18 @@ } +class ThreadToCodeBlobClosure : public ThreadClosure { +private: + CodeBlobClosure* _cl; +public: + void do_thread(Thread* thread) { + if (thread->is_Java_thread() && + ! thread->is_Code_cache_sweeper_thread()) { + JavaThread* jt = (JavaThread*) thread; + jt->nmethods_do(_cl); + } +}; + /** * This function triggers a VM operation that does stack scanning of active * methods. Stack scanning is mandatory for the sweeper to make progress. @@ -258,8 +270,16 @@ void NMethodSweeper::do_stack_scanning() { assert(!CodeCache_lock->owned_by_self(), "just checking"); if (wait_for_stack_scanning()) { - VM_MarkActiveNMethods op; - VMThread::execute(&op); + if (ThreadLocalHandshakes) { + CodeBlobClosure code_cl = prepare_mark_active_nmethods(); + if (code_cl != NULL) { + ThreadToCodeBlobClosure tcl(&cl); + Handshake::execute(&tcl); + } + } else { + VM_MarkActiveNMethods op; + VMThread::execute(&op); + } _should_sweep = true; } } # HG changeset patch # User rkennke # Date 1537537831 -7200 # Fri Sep 21 15:50:31 2018 +0200 # Node ID c64801c6719446cdc7d64f8cdc962211f9db2f2e # Parent 7075300b6c8f3662bfecbcec6bff660b41358f50 8132849: Increased stop time in cleanup phase because of single-threaded walk of thread stacks in NMethodSweeper::mark_active_nmethods() diff --git a/src/hotspot/share/runtime/sweeper.cpp b/src/hotspot/share/runtime/sweeper.cpp --- a/src/hotspot/share/runtime/sweeper.cpp +++ b/src/hotspot/share/runtime/sweeper.cpp @@ -28,15 +28,19 @@ #include "code/icBuffer.hpp" #include "code/nmethod.hpp" #include "compiler/compileBroker.hpp" +#include "gc/shared/collectedHeap.hpp" +#include "gc/shared/workgroup.hpp" #include "jfr/jfrEvents.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" +#include "memory/universe.hpp" #include "oops/method.hpp" #include "runtime/atomic.hpp" #include "runtime/compilationPolicy.hpp" #include "runtime/interfaceSupport.inline.hpp" +#include "runtime/handshake.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/orderAccess.hpp" #include "runtime/os.hpp" @@ -197,6 +201,32 @@ return _current.end(); } +class ThreadToCodeBlobClosure : public ThreadClosure { +private: + CodeBlobClosure* _cl; +public: + ThreadToCodeBlobClosure(CodeBlobClosure* cl) : _cl(cl) {} + void do_thread(Thread* thread) { + if (thread->is_Java_thread() && + ! thread->is_Code_cache_sweeper_thread()) { + JavaThread* jt = (JavaThread*) thread; + jt->nmethods_do(_cl); + } + } +}; + +class NMethodMarkingTask : public AbstractGangTask { +private: + ThreadToCodeBlobClosure* _cl; +public: + NMethodMarkingTask(ThreadToCodeBlobClosure* cl) : + AbstractGangTask("Parallel NMethod Marking"), + _cl(cl) {} + void work(uint worker_id) { + Threads::possibly_parallel_threads_do(true, _cl); + } +}; + /** * Scans the stacks of all Java threads and marks activations of not-entrant methods. * No need to synchronize access, since 'mark_active_nmethods' is always executed at a @@ -205,12 +235,18 @@ void NMethodSweeper::mark_active_nmethods() { CodeBlobClosure* cl = prepare_mark_active_nmethods(); if (cl != NULL) { - Threads::nmethods_do(cl); + WorkGang* workers = Universe::heap()->get_safepoint_workers(); + if (workers != NULL) { + ThreadToCodeBlobClosure tcl(cl); + NMethodMarkingTask task(&tcl); + workers->run_task(&task); + } else { + Threads::nmethods_do(cl); + } } } CodeBlobClosure* NMethodSweeper::prepare_mark_active_nmethods() { - assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint"); // If we do not want to reclaim not-entrant or zombie methods there is no need // to scan stacks if (!MethodFlushing) { @@ -251,18 +287,6 @@ } -class ThreadToCodeBlobClosure : public ThreadClosure { -private: - CodeBlobClosure* _cl; -public: - void do_thread(Thread* thread) { - if (thread->is_Java_thread() && - ! thread->is_Code_cache_sweeper_thread()) { - JavaThread* jt = (JavaThread*) thread; - jt->nmethods_do(_cl); - } -}; - /** * This function triggers a VM operation that does stack scanning of active * methods. Stack scanning is mandatory for the sweeper to make progress. @@ -271,9 +295,9 @@ assert(!CodeCache_lock->owned_by_self(), "just checking"); if (wait_for_stack_scanning()) { if (ThreadLocalHandshakes) { - CodeBlobClosure code_cl = prepare_mark_active_nmethods(); + CodeBlobClosure* code_cl = prepare_mark_active_nmethods(); if (code_cl != NULL) { - ThreadToCodeBlobClosure tcl(&cl); + ThreadToCodeBlobClosure tcl(code_cl); Handshake::execute(&tcl); } } else { # HG changeset patch # User rkennke # Date 1537726990 -7200 # Sun Sep 23 20:23:10 2018 +0200 # Node ID fedd26b6eace9c4b5332f4deda1ce9e0858e69ea # Parent c64801c6719446cdc7d64f8cdc962211f9db2f2e [mq]: JDK-8132849-01.patch diff --git a/src/hotspot/share/runtime/sweeper.cpp b/src/hotspot/share/runtime/sweeper.cpp --- a/src/hotspot/share/runtime/sweeper.cpp +++ b/src/hotspot/share/runtime/sweeper.cpp @@ -247,6 +247,8 @@ } CodeBlobClosure* NMethodSweeper::prepare_mark_active_nmethods() { + assert(SafepointSynchronize::is_at_safepoint() || + Thread::current()->is_Code_cache_sweeper_thread(), "must be executed at a safepoint"); // If we do not want to reclaim not-entrant or zombie methods there is no need // to scan stacks if (!MethodFlushing) {