Bug 1572337: Remove old responsiveness profiler measurement r=gerald

Differential Revision: https://phabricator.services.mozilla.com/D44060

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Randell Jesup 2019-11-07 12:53:35 +00:00
parent 1cca5fd890
commit 95be6cffe0
9 changed files with 29 additions and 259 deletions

View File

@ -173,7 +173,6 @@ static uint32_t AvailableFeatures() {
// Now remove features not supported on this platform/configuration.
ProfilerFeature::ClearJava(features);
ProfilerFeature::ClearJS(features);
ProfilerFeature::ClearResponsiveness(features);
ProfilerFeature::ClearScreenshots(features);
# if !defined(HAVE_NATIVE_UNWIND)
ProfilerFeature::ClearStackWalk(features);
@ -188,8 +187,7 @@ static uint32_t AvailableFeatures() {
// Default features common to all contexts (even if not available).
static uint32_t DefaultFeatures() {
return ProfilerFeature::Java | ProfilerFeature::JS | ProfilerFeature::Leaf |
ProfilerFeature::StackWalk | ProfilerFeature::Threads |
ProfilerFeature::Responsiveness;
ProfilerFeature::StackWalk | ProfilerFeature::Threads;
}
// Extra default features when MOZ_BASE_PROFILER_STARTUP is set (even if not

View File

@ -134,27 +134,24 @@ class SpliceableJSONWriter;
MACRO(4, "privacy", Privacy, \
"Do not include user-identifiable information") \
\
MACRO(5, "responsiveness", Responsiveness, \
"Collect thread responsiveness information") \
\
MACRO(6, "screenshots", Screenshots, \
MACRO(5, "screenshots", Screenshots, \
"Take a snapshot of the window on every composition") \
\
MACRO(7, "seqstyle", SequentialStyle, \
MACRO(6, "seqstyle", SequentialStyle, \
"Disable parallel traversal in styling") \
\
MACRO(8, "stackwalk", StackWalk, \
MACRO(7, "stackwalk", StackWalk, \
"Walk the C++ stack, not available on all platforms") \
\
MACRO(9, "tasktracer", TaskTracer, \
MACRO(8, "tasktracer", TaskTracer, \
"Start profiling with feature TaskTracer") \
\
MACRO(10, "threads", Threads, "Profile the registered secondary threads") \
MACRO(9, "threads", Threads, "Profile the registered secondary threads") \
\
MACRO(11, "trackopts", TrackOptimizations, \
MACRO(10, "trackopts", TrackOptimizations, \
"Have the JavaScript engine track JIT optimizations") \
\
MACRO(12, "jstracer", JSTracer, "Enable tracing of the JavaScript engine") \
MACRO(11, "jstracer", JSTracer, "Enable tracing of the JavaScript engine") \
\
MACRO(14, "nostacksampling", NoStackSampling, \
"Disable all stack sampling: Cancels \"js\", \"leaf\", " \

View File

@ -17,13 +17,9 @@
#endif
ProfiledThreadData::ProfiledThreadData(ThreadInfo* aThreadInfo,
nsIEventTarget* aEventTarget,
bool aIncludeResponsiveness)
nsIEventTarget* aEventTarget)
: mThreadInfo(aThreadInfo) {
MOZ_COUNT_CTOR(ProfiledThreadData);
if (aIncludeResponsiveness) {
mResponsiveness.emplace(aEventTarget, aThreadInfo->IsMainThread());
}
}
ProfiledThreadData::~ProfiledThreadData() {

View File

@ -10,7 +10,6 @@
#include "platform.h"
#include "ProfileBufferEntry.h"
#include "ThreadInfo.h"
#include "ThreadResponsiveness.h"
#include "js/ProfilingStack.h"
#include "mozilla/TimeStamp.h"
@ -43,12 +42,10 @@ class ProfileBuffer;
// when the profiler is stopped.
class ProfiledThreadData final {
public:
ProfiledThreadData(ThreadInfo* aThreadInfo, nsIEventTarget* aEventTarget,
bool aIncludeResponsiveness);
ProfiledThreadData(ThreadInfo* aThreadInfo, nsIEventTarget* aEventTarget);
~ProfiledThreadData();
void NotifyUnregistered(uint64_t aBufferPosition) {
mResponsiveness.reset();
mLastSample = mozilla::Nothing();
MOZ_ASSERT(!mBufferPositionWhenReceivedJSContext,
"JSContext should have been cleared before the thread was "
@ -71,13 +68,6 @@ class ProfiledThreadData final {
void StreamTraceLoggerJSON(JSContext* aCx, SpliceableJSONWriter& aWriter,
const mozilla::TimeStamp& aProcessStartTime);
// Returns nullptr if this is not the main thread, the responsiveness
// feature is not turned on, or if this thread is not being profiled.
ThreadResponsiveness* GetThreadResponsiveness() {
ThreadResponsiveness* responsiveness = mResponsiveness.ptrOr(nullptr);
return responsiveness;
}
const RefPtr<ThreadInfo> Info() const { return mThreadInfo; }
void NotifyReceivedJSContext(uint64_t aCurrentBufferPosition) {
@ -109,10 +99,6 @@ class ProfiledThreadData final {
// The following fields are only used while this thread is alive and
// registered. They become Nothing() once the thread is unregistered.
// A helper object that instruments nsIThreads to obtain responsiveness
// information about their event loop.
mozilla::Maybe<ThreadResponsiveness> mResponsiveness;
// When sampling, this holds the position in ActivePS::mBuffer of the most
// recent sample for this thread, or Nothing() if there is no sample for this
// thread in the buffer.

View File

@ -225,8 +225,7 @@ static uint32_t AvailableFeatures() {
// Default features common to all contexts (even if not available).
static uint32_t DefaultFeatures() {
return ProfilerFeature::Java | ProfilerFeature::JS | ProfilerFeature::Leaf |
ProfilerFeature::StackWalk | ProfilerFeature::Threads |
ProfilerFeature::Responsiveness;
ProfilerFeature::StackWalk | ProfilerFeature::Threads;
}
// Extra default features when MOZ_PROFILER_STARTUP is set (even if not
@ -2348,8 +2347,7 @@ static void locked_profiler_stream_json_for_this_process(
// java thread, we have to get thread id and name via JNI.
RefPtr<ThreadInfo> threadInfo = new ThreadInfo(
"Java Main Thread", 0, false, CorePS::ProcessStartTime());
ProfiledThreadData profiledThreadData(
threadInfo, nullptr, ActivePS::FeatureResponsiveness(aLock));
ProfiledThreadData profiledThreadData(threadInfo, nullptr);
profiledThreadData.StreamJSON(*javaBuffer.get(), nullptr, aWriter,
CorePS::ProcessName(aLock),
CorePS::ProcessStartTime(), aSinceTime,
@ -2439,6 +2437,7 @@ static char FeatureCategory(uint32_t aFeature) {
return 'x';
}
// Doesn't exist if aExitCode is 0
static void PrintUsageThenExit(int aExitCode) {
MOZ_RELEASE_ASSERT(NS_IsMainThread());
@ -2538,7 +2537,9 @@ static void PrintUsageThenExit(int aExitCode) {
#endif
);
exit(aExitCode);
if (aExitCode != 0) {
exit(aExitCode);
}
}
////////////////////////////////////////////////////////////////////////
@ -3236,7 +3237,8 @@ static uint32_t ParseFeature(const char* aFeature, bool aIsStartup) {
#undef PARSE_FEATURE_BIT
printf("\nUnrecognized feature \"%s\".\n\n", aFeature);
PrintUsageThenExit(1);
// Since we may have an old feature we don't implement anymore, don't exit
PrintUsageThenExit(0);
return 0;
}
@ -3290,8 +3292,7 @@ static ProfilingStack* locked_register_thread(PSLockRef aLock,
nsCOMPtr<nsIEventTarget> eventTarget = registeredThread->GetEventTarget();
ProfiledThreadData* profiledThreadData = ActivePS::AddLiveProfiledThread(
aLock, registeredThread.get(),
MakeUnique<ProfiledThreadData>(info, eventTarget,
ActivePS::FeatureResponsiveness(aLock)));
MakeUnique<ProfiledThreadData>(info, eventTarget));
if (ActivePS::FeatureJS(aLock)) {
// This StartJSSampling() call is on-thread, so we can poll manually to
@ -3416,7 +3417,7 @@ void profiler_init(void* aStackTop) {
MOZ_RELEASE_ASSERT(!CorePS::Exists());
if (getenv("MOZ_PROFILER_HELP")) {
PrintUsageThenExit(0); // terminates execution
PrintUsageThenExit(1); // terminates execution
}
SharedLibraryInfo::Initialize();
@ -3985,8 +3986,7 @@ static void locked_profiler_start(PSLockRef aLock, PowerOfTwo32 aCapacity,
nsCOMPtr<nsIEventTarget> eventTarget = registeredThread->GetEventTarget();
ProfiledThreadData* profiledThreadData = ActivePS::AddLiveProfiledThread(
aLock, registeredThread.get(),
MakeUnique<ProfiledThreadData>(
info, eventTarget, ActivePS::FeatureResponsiveness(aLock)));
MakeUnique<ProfiledThreadData>(info, eventTarget));
if (ActivePS::FeatureJS(aLock)) {
registeredThread->StartJSSampling(ActivePS::JSFlags(aLock));
if (info->ThreadId() == tid) {

View File

@ -1,162 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ThreadResponsiveness.h"
#include "platform.h"
#include "mozilla/Atomics.h"
#include "mozilla/SystemGroup.h"
#include "nsITimer.h"
using namespace mozilla;
class CheckResponsivenessTask : public CancelableRunnable,
public nsITimerCallback {
public:
explicit CheckResponsivenessTask(nsIEventTarget* aThread, bool aIsMainThread)
: CancelableRunnable("CheckResponsivenessTask"),
mStartToPrevTracer_us(uint64_t(profiler_time() * 1000.0)),
mStop(false),
mHasEverBeenSuccessfullyDispatched(false),
mThread(aThread),
mIsMainThread(aIsMainThread) {}
protected:
~CheckResponsivenessTask() {}
public:
// Must be called from the same thread every time. Call that the update
// thread, because it's the thread that ThreadResponsiveness::Update() is
// called on. In reality it's the profiler's sampler thread.
bool DoFirstDispatchIfNeeded() {
if (mHasEverBeenSuccessfullyDispatched) {
return true;
}
// The profiler for the main thread is set up before the thread manager is,
// meaning we can't get the nsIThread when the CheckResponsivenessTask is
// constructed. We _do_ know whether it is the main thread at that time,
// however, so here's the workaround. We can still hit this code before the
// thread manager is initted, in which case we won't try to record
// responsiveness, which is fine because there's no event queue to check
// responsiveness on anyway.
if (mIsMainThread) {
if (!mThread) {
nsCOMPtr<nsIThread> temp;
NS_GetMainThread(getter_AddRefs(temp));
mThread = temp.forget();
}
if (mThread) {
nsresult rv =
SystemGroup::Dispatch(TaskCategory::Other, do_AddRef(this));
if (NS_SUCCEEDED(rv)) {
mHasEverBeenSuccessfullyDispatched = true;
}
}
} else if (mThread) {
nsresult rv = mThread->Dispatch(this, nsIThread::NS_DISPATCH_NORMAL);
if (NS_SUCCEEDED(rv)) {
mHasEverBeenSuccessfullyDispatched = true;
}
}
return mHasEverBeenSuccessfullyDispatched;
}
nsresult Cancel() override {
// No special work needed.
return NS_OK;
}
// Only runs on the thread being profiled. Always called via a thread
// dispatch, so inherently functions as a responsiveness statistic.
NS_IMETHOD Run() override {
// This approach means that the 16ms delay in the timer below, _plus_ any
// additional delays in the TimerThread itself, become part of the
// responsiveness statistic for this thread. What we should probably be
// doing is recording responsiveness only when we have dispatched (but not
// executed) a call to this function, either because of a call to
// DoFirstDispatchIfNeeded, or a call to Notify.
mStartToPrevTracer_us = uint64_t(profiler_time() * 1000.0);
if (!mStop) {
if (!mTimer) {
if (mIsMainThread) {
mTimer =
NS_NewTimer(SystemGroup::EventTargetFor(TaskCategory::Other));
} else {
mTimer = NS_NewTimer();
}
}
mTimer->InitWithCallback(this, 16, nsITimer::TYPE_ONE_SHOT);
}
return NS_OK;
}
// Should always fire on the thread being profiled
NS_IMETHOD Notify(nsITimer* aTimer) final {
Run();
return NS_OK;
}
// Can be called on any thread.
void Terminate() { mStop = true; }
// Can be called on any thread.
double GetStartToPrevTracer_ms() const {
return mStartToPrevTracer_us / 1000.0;
}
NS_DECL_ISUPPORTS_INHERITED
private:
// The timer that's responsible for redispatching this event to the thread we
// are profiling (ie; mThread). Only touched on mThread.
nsCOMPtr<nsITimer> mTimer;
// The time (in integer microseconds since process startup) at which this
// event was last processed (Run() was last called).
// This field is written on mThread and read on the update thread.
// This is stored as integer microseconds instead of double milliseconds
// because Atomic<double> is not available.
Atomic<uint64_t> mStartToPrevTracer_us;
// Whether we should stop redispatching this event once the timer fires the
// next time. Set to true by any thread when the profiler is stopped; read on
// mThread.
Atomic<bool> mStop;
// Only accessed on the update thread.
bool mHasEverBeenSuccessfullyDispatched;
// The thread that we're profiling. Use nsIEventTarget to allow for checking
// responsiveness on non-nsIThreads someday.
nsCOMPtr<nsIEventTarget> mThread;
bool mIsMainThread;
};
NS_IMPL_ISUPPORTS_INHERITED(CheckResponsivenessTask, CancelableRunnable,
nsITimerCallback)
ThreadResponsiveness::ThreadResponsiveness(nsIEventTarget* aThread,
bool aIsMainThread)
: mActiveTracerEvent(new CheckResponsivenessTask(aThread, aIsMainThread)) {
MOZ_COUNT_CTOR(ThreadResponsiveness);
}
ThreadResponsiveness::~ThreadResponsiveness() {
MOZ_COUNT_DTOR(ThreadResponsiveness);
mActiveTracerEvent->Terminate();
}
void ThreadResponsiveness::Update() {
if (!mActiveTracerEvent->DoFirstDispatchIfNeeded()) {
return;
}
mStartToPrevTracer_ms = Some(mActiveTracerEvent->GetStartToPrevTracer_ms());
}

View File

@ -1,41 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ThreadResponsiveness_h
#define ThreadResponsiveness_h
#include "mozilla/Maybe.h"
#include "mozilla/RefPtr.h"
#include "mozilla/TimeStamp.h"
#include "nsISupports.h"
class CheckResponsivenessTask;
class nsIEventTarget;
// This class should only be used for the main thread.
class ThreadResponsiveness {
public:
explicit ThreadResponsiveness(nsIEventTarget* aThread, bool aIsMainThread);
~ThreadResponsiveness();
void Update();
// The number of milliseconds that elapsed since the last
// CheckResponsivenessTask was processed.
double GetUnresponsiveDuration(double aStartToNow_ms) const {
return aStartToNow_ms - *mStartToPrevTracer_ms;
}
bool HasData() const { return mStartToPrevTracer_ms.isSome(); }
private:
RefPtr<CheckResponsivenessTask> mActiveTracerEvent;
// The time at which the last CheckResponsivenessTask was processed, in
// milliseconds since process start (i.e. what you get from profiler_time()).
mozilla::Maybe<double> mStartToPrevTracer_ms;
};
#endif

View File

@ -36,7 +36,6 @@ if CONFIG['MOZ_GECKO_PROFILER']:
'gecko/ProfilerChild.cpp',
'gecko/ProfilerIOInterposeObserver.cpp',
'gecko/ProfilerParent.cpp',
'gecko/ThreadResponsiveness.cpp',
]
if CONFIG['MOZ_REPLACE_MALLOC'] and CONFIG['MOZ_PROFILER_MEMORY']:
SOURCES += [

View File

@ -147,29 +147,26 @@ class Vector;
MACRO(4, "privacy", Privacy, \
"Do not include user-identifiable information") \
\
MACRO(5, "responsiveness", Responsiveness, \
"Collect thread responsiveness information") \
\
MACRO(6, "screenshots", Screenshots, \
MACRO(5, "screenshots", Screenshots, \
"Take a snapshot of the window on every composition") \
\
MACRO(7, "seqstyle", SequentialStyle, \
MACRO(6, "seqstyle", SequentialStyle, \
"Disable parallel traversal in styling") \
\
MACRO(8, "stackwalk", StackWalk, \
MACRO(7, "stackwalk", StackWalk, \
"Walk the C++ stack, not available on all platforms") \
\
MACRO(9, "tasktracer", TaskTracer, \
MACRO(8, "tasktracer", TaskTracer, \
"Start profiling with feature TaskTracer") \
\
MACRO(10, "threads", Threads, "Profile the registered secondary threads") \
MACRO(9, "threads", Threads, "Profile the registered secondary threads") \
\
MACRO(11, "trackopts", TrackOptimizations, \
MACRO(10, "trackopts", TrackOptimizations, \
"Have the JavaScript engine track JIT optimizations") \
\
MACRO(12, "jstracer", JSTracer, "Enable tracing of the JavaScript engine") \
MACRO(11, "jstracer", JSTracer, "Enable tracing of the JavaScript engine") \
\
MACRO(13, "jsallocations", JSAllocations, \
MACRO(12, "jsallocations", JSAllocations, \
"Have the JavaScript engine track allocations") \
\
MACRO(14, "nostacksampling", NoStackSampling, \