ART: Make GC Pause Listener more precise
Refactor code to call the listener in FlipThreadRoots, after all
threads have been suspended.
Bug: 37283268
Test: m test-art-host
Change-Id: I313db07e014e65a997d0b58c8a70e4505425def0
diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc
index a450a75..8b80f54 100644
--- a/runtime/gc/collector/concurrent_copying.cc
+++ b/runtime/gc/collector/concurrent_copying.cc
@@ -616,25 +616,8 @@
ThreadFlipVisitor thread_flip_visitor(this, heap_->use_tlab_);
FlipCallback flip_callback(this);
- // This is the point where Concurrent-Copying will pause all threads. We report a pause here, if
- // necessary. This is slightly over-reporting, as this includes the time to actually suspend
- // threads.
- {
- GcPauseListener* pause_listener = GetHeap()->GetGcPauseListener();
- if (pause_listener != nullptr) {
- pause_listener->StartPause();
- }
- }
-
- size_t barrier_count = Runtime::Current()->FlipThreadRoots(
- &thread_flip_visitor, &flip_callback, this);
-
- {
- GcPauseListener* pause_listener = GetHeap()->GetGcPauseListener();
- if (pause_listener != nullptr) {
- pause_listener->EndPause();
- }
- }
+ size_t barrier_count = Runtime::Current()->GetThreadList()->FlipThreadRoots(
+ &thread_flip_visitor, &flip_callback, this, GetHeap()->GetGcPauseListener());
{
ScopedThreadStateChange tsc(self, kWaitingForCheckPointsToRun);
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 60fa082..0bc0869 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1816,11 +1816,6 @@
thread_list_->VisitRoots(visitor, flags);
}
-size_t Runtime::FlipThreadRoots(Closure* thread_flip_visitor, Closure* flip_callback,
- gc::collector::GarbageCollector* collector) {
- return thread_list_->FlipThreadRoots(thread_flip_visitor, flip_callback, collector);
-}
-
void Runtime::VisitRoots(RootVisitor* visitor, VisitRootFlags flags) {
VisitNonConcurrentRoots(visitor, flags);
VisitConcurrentRoots(visitor, flags);
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 8d04777..4931382 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -48,9 +48,6 @@
namespace gc {
class AbstractSystemWeakHolder;
class Heap;
- namespace collector {
- class GarbageCollector;
- } // namespace collector
} // namespace gc
namespace jit {
@@ -79,7 +76,6 @@
class ArtMethod;
class ClassHierarchyAnalysis;
class ClassLinker;
-class Closure;
class CompilerCallbacks;
class DexFile;
class InternTable;
@@ -340,11 +336,6 @@
void VisitTransactionRoots(RootVisitor* visitor)
REQUIRES_SHARED(Locks::mutator_lock_);
- // Flip thread roots from from-space refs to to-space refs.
- size_t FlipThreadRoots(Closure* thread_flip_visitor, Closure* flip_callback,
- gc::collector::GarbageCollector* collector)
- REQUIRES(!Locks::mutator_lock_);
-
// Sweep system weaks, the system weak is deleted if the visitor return null. Otherwise, the
// system weak is updated to be the visitor's returned value.
void SweepSystemWeaks(IsMarkedVisitor* visitor)
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index b63eaa4..dc2af2a 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -34,6 +34,7 @@
#include "base/timing_logger.h"
#include "debugger.h"
#include "gc/collector/concurrent_copying.h"
+#include "gc/gc_pause_listener.h"
#include "gc/reference_processor.h"
#include "jni_internal.h"
#include "lock_word.h"
@@ -528,7 +529,8 @@
// invariant.
size_t ThreadList::FlipThreadRoots(Closure* thread_flip_visitor,
Closure* flip_callback,
- gc::collector::GarbageCollector* collector) {
+ gc::collector::GarbageCollector* collector,
+ gc::GcPauseListener* pause_listener) {
TimingLogger::ScopedTiming split("ThreadListFlip", collector->GetTimings());
Thread* self = Thread::Current();
Locks::mutator_lock_->AssertNotHeld(self);
@@ -542,6 +544,9 @@
// pause.
const uint64_t suspend_start_time = NanoTime();
SuspendAllInternal(self, self, nullptr);
+ if (pause_listener != nullptr) {
+ pause_listener->StartPause();
+ }
// Run the flip callback for the collector.
Locks::mutator_lock_->ExclusiveLock(self);
@@ -549,6 +554,9 @@
flip_callback->Run(self);
Locks::mutator_lock_->ExclusiveUnlock(self);
collector->RegisterPause(NanoTime() - suspend_start_time);
+ if (pause_listener != nullptr) {
+ pause_listener->EndPause();
+ }
// Resume runnable threads.
size_t runnable_thread_count = 0;
diff --git a/runtime/thread_list.h b/runtime/thread_list.h
index 14bef5e..3375746 100644
--- a/runtime/thread_list.h
+++ b/runtime/thread_list.h
@@ -35,6 +35,7 @@
namespace collector {
class GarbageCollector;
} // namespac collector
+ class GcPauseListener;
} // namespace gc
class Closure;
class Thread;
@@ -121,7 +122,8 @@
// the concurrent copying collector.
size_t FlipThreadRoots(Closure* thread_flip_visitor,
Closure* flip_callback,
- gc::collector::GarbageCollector* collector)
+ gc::collector::GarbageCollector* collector,
+ gc::GcPauseListener* pause_listener)
REQUIRES(!Locks::mutator_lock_,
!Locks::thread_list_lock_,
!Locks::thread_suspend_count_lock_);