Bug 1403868 (part 4) - Reduce tools/profiler/public/*.h to almost nothing in non-MOZ_GECKO_PROFILER builds. r=mstange.

Currently the Gecko Profiler defines a moderate amount of stuff when
MOZ_GECKO_PROFILER is undefined. It also #includes various headers, including
JS ones. This is making it difficult to separate Gecko's media stack for
inclusion in Servo.

This patch greatly simplifies how things are exposed. The starting point is:

- GeckoProfiler.h can be #included unconditionally;

- everything else from the profiler must be guarded by MOZ_GECKO_PROFILER.

In practice this introduces way too many #ifdefs, so the patch loosens it by
adding no-op macros for a number of the most common operations.

The net result is that #ifdefs and macros are used a bit more, but almost
nothing is exposed in non-MOZ_GECKO_PROFILER builds (including
ProfilerMarkerPayload.h and GeckoProfiler.h), and understanding what is exposed
is much simpler than before.

Note also that in BHR, ThreadStackHelper is now entirely absent in
non-MOZ_GECKO_PROFILER builds.
This commit is contained in:
Nicholas Nethercote 2017-10-04 09:11:18 +11:00
Родитель 74e64bcaa2
Коммит 8a68e6fb83
85 изменённых файлов: 396 добавлений и 272 удалений

Просмотреть файл

@ -845,6 +845,7 @@ Accessible::HandleAccEvent(AccEvent* aEvent)
{
NS_ENSURE_ARG_POINTER(aEvent);
#ifdef MOZ_GECKO_PROFILER
if (profiler_is_active()) {
nsAutoCString strEventType;
GetAccService()->GetStringEventType(aEvent->GetEventType(), strEventType);
@ -853,6 +854,7 @@ Accessible::HandleAccEvent(AccEvent* aEvent)
strMarker.Append(strEventType);
profiler_add_marker(strMarker.get());
}
#endif
if (IPCAccessibilityActive() && Document()) {
DocAccessibleChild* ipcDoc = mDoc->IPCDoc();

Просмотреть файл

@ -69,7 +69,7 @@ nsDOMNavigationTiming::NotifyNavigationStart(DocShellState aDocShellState)
mNavigationStartHighRes = (double)PR_Now() / PR_USEC_PER_MSEC;
mNavigationStart = TimeStamp::Now();
mDocShellHasBeenActiveSinceNavigationStart = (aDocShellState == DocShellState::eActive);
profiler_add_marker("Navigation::Start");
PROFILER_ADD_MARKER("Navigation::Start");
}
void
@ -98,14 +98,14 @@ void
nsDOMNavigationTiming::NotifyUnloadEventStart()
{
mUnloadStart = TimeStamp::Now();
profiler_tracing("Navigation", "Unload", TRACING_INTERVAL_START);
PROFILER_TRACING("Navigation", "Unload", TRACING_INTERVAL_START);
}
void
nsDOMNavigationTiming::NotifyUnloadEventEnd()
{
mUnloadEnd = TimeStamp::Now();
profiler_tracing("Navigation", "Unload", TRACING_INTERVAL_END);
PROFILER_TRACING("Navigation", "Unload", TRACING_INTERVAL_END);
}
void
@ -116,7 +116,7 @@ nsDOMNavigationTiming::NotifyLoadEventStart()
}
mLoadEventStart = TimeStamp::Now();
profiler_tracing("Navigation", "Load", TRACING_INTERVAL_START);
PROFILER_TRACING("Navigation", "Load", TRACING_INTERVAL_START);
if (IsTopLevelContentDocumentInContentProcess()) {
Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_LOAD_EVENT_START_MS,
@ -132,7 +132,7 @@ nsDOMNavigationTiming::NotifyLoadEventEnd()
}
mLoadEventEnd = TimeStamp::Now();
profiler_tracing("Navigation", "Load", TRACING_INTERVAL_END);
PROFILER_TRACING("Navigation", "Load", TRACING_INTERVAL_END);
if (IsTopLevelContentDocumentInContentProcess()) {
Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_LOAD_EVENT_END_MS,
@ -159,7 +159,7 @@ nsDOMNavigationTiming::NotifyDOMLoading(nsIURI* aURI)
mLoadedURI = aURI;
mDOMLoading = TimeStamp::Now();
profiler_add_marker("Navigation::DOMLoading");
PROFILER_ADD_MARKER("Navigation::DOMLoading");
}
void
@ -171,7 +171,7 @@ nsDOMNavigationTiming::NotifyDOMInteractive(nsIURI* aURI)
mLoadedURI = aURI;
mDOMInteractive = TimeStamp::Now();
profiler_add_marker("Navigation::DOMInteractive");
PROFILER_ADD_MARKER("Navigation::DOMInteractive");
}
void
@ -183,7 +183,7 @@ nsDOMNavigationTiming::NotifyDOMComplete(nsIURI* aURI)
mLoadedURI = aURI;
mDOMComplete = TimeStamp::Now();
profiler_add_marker("Navigation::DOMComplete");
PROFILER_ADD_MARKER("Navigation::DOMComplete");
}
void
@ -196,7 +196,7 @@ nsDOMNavigationTiming::NotifyDOMContentLoadedStart(nsIURI* aURI)
mLoadedURI = aURI;
mDOMContentLoadedEventStart = TimeStamp::Now();
profiler_tracing("Navigation", "DOMContentLoaded", TRACING_INTERVAL_START);
PROFILER_TRACING("Navigation", "DOMContentLoaded", TRACING_INTERVAL_START);
if (IsTopLevelContentDocumentInContentProcess()) {
Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_DOM_CONTENT_LOADED_START_MS,
@ -214,7 +214,7 @@ nsDOMNavigationTiming::NotifyDOMContentLoadedEnd(nsIURI* aURI)
mLoadedURI = aURI;
mDOMContentLoadedEventEnd = TimeStamp::Now();
profiler_tracing("Navigation", "DOMContentLoaded", TRACING_INTERVAL_END);
PROFILER_TRACING("Navigation", "DOMContentLoaded", TRACING_INTERVAL_END);
if (IsTopLevelContentDocumentInContentProcess()) {
Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_DOM_CONTENT_LOADED_END_MS,
@ -233,9 +233,10 @@ nsDOMNavigationTiming::NotifyNonBlankPaintForRootContentDocument()
}
mNonBlankPaint = TimeStamp::Now();
TimeDuration elapsed = mNonBlankPaint - mNavigationStart;
#ifdef MOZ_GECKO_PROFILER
if (profiler_is_active()) {
TimeDuration elapsed = mNonBlankPaint - mNavigationStart;
nsAutoCString spec;
if (mLoadedURI) {
mLoadedURI->GetSpec(spec);
@ -245,6 +246,7 @@ nsDOMNavigationTiming::NotifyNonBlankPaintForRootContentDocument()
mDocShellHasBeenActiveSinceNavigationStart ? "foreground tab" : "this tab was inactive some of the time between navigation start and first non-blank paint");
profiler_add_marker(marker.get());
}
#endif
if (mDocShellHasBeenActiveSinceNavigationStart) {
Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_NON_BLANK_PAINT_MS,

Просмотреть файл

@ -3521,7 +3521,7 @@ PrepareForFullscreenChange(nsIPresShell* aPresShell, const nsSize& aSize,
NS_IMETHODIMP
nsDOMWindowUtils::HandleFullscreenRequests(bool* aRetVal)
{
profiler_add_marker("Enter fullscreen");
PROFILER_ADD_MARKER("Enter fullscreen");
nsCOMPtr<nsIDocument> doc = GetDocument();
NS_ENSURE_STATE(doc);
@ -3544,7 +3544,7 @@ nsDOMWindowUtils::HandleFullscreenRequests(bool* aRetVal)
nsresult
nsDOMWindowUtils::ExitFullscreen()
{
profiler_add_marker("Exit fullscreen");
PROFILER_ADD_MARKER("Exit fullscreen");
nsCOMPtr<nsIDocument> doc = GetDocument();
NS_ENSURE_STATE(doc);

Просмотреть файл

@ -600,11 +600,13 @@ nsFrameMessageManager::SendMessage(const nsAString& aMessageName,
JS::MutableHandle<JS::Value> aRetval,
bool aIsSync)
{
#ifdef MOZ_GECKO_PROFILER
if (profiler_is_active()) {
NS_LossyConvertUTF16toASCII messageNameCStr(aMessageName);
AUTO_PROFILER_LABEL_DYNAMIC("nsFrameMessageManager::SendMessage", EVENTS,
messageNameCStr.get());
}
#endif
NS_ASSERTION(!IsGlobal(), "Should not call SendSyncMessage in chrome");
NS_ASSERTION(!IsBroadcaster(), "Should not call SendSyncMessage in chrome");
@ -1539,12 +1541,14 @@ void
nsMessageManagerScriptExecutor::LoadScriptInternal(const nsAString& aURL,
bool aRunInGlobalScope)
{
#ifdef MOZ_GECKO_PROFILER
if (profiler_is_active()) {
NS_LossyConvertUTF16toASCII urlCStr(aURL);
AUTO_PROFILER_LABEL_DYNAMIC(
"nsMessageManagerScriptExecutor::LoadScriptInternal", OTHER,
urlCStr.get());
}
#endif
if (!mGlobal || !sCachedScripts) {
return;

Просмотреть файл

@ -7060,12 +7060,12 @@ FullscreenTransitionTask::Run()
return NS_OK;
}
if (stage == eBeforeToggle) {
profiler_add_marker("Fullscreen transition start");
PROFILER_ADD_MARKER("Fullscreen transition start");
mWidget->PerformFullscreenTransition(nsIWidget::eBeforeFullscreenToggle,
mDuration.mFadeIn, mTransitionData,
this);
} else if (stage == eToggleFullscreen) {
profiler_add_marker("Fullscreen toggle start");
PROFILER_ADD_MARKER("Fullscreen toggle start");
mFullscreenChangeStartTime = TimeStamp::Now();
if (MOZ_UNLIKELY(mWindow->mFullScreen != mFullscreen)) {
// This could happen in theory if several fullscreen requests in
@ -7109,7 +7109,7 @@ FullscreenTransitionTask::Run()
mDuration.mFadeOut, mTransitionData,
this);
} else if (stage == eEnd) {
profiler_add_marker("Fullscreen transition end");
PROFILER_ADD_MARKER("Fullscreen transition end");
}
return NS_OK;
}
@ -7130,7 +7130,7 @@ FullscreenTransitionTask::Observer::Observe(nsISupports* aSubject,
// The paint notification arrives first. Cancel the timer.
mTask->mTimer->Cancel();
shouldContinue = true;
profiler_add_marker("Fullscreen toggle end");
PROFILER_ADD_MARKER("Fullscreen toggle end");
}
} else {
#ifdef DEBUG
@ -7141,7 +7141,7 @@ FullscreenTransitionTask::Observer::Observe(nsISupports* aSubject,
"Should only trigger this with the timer the task created");
#endif
shouldContinue = true;
profiler_add_marker("Fullscreen toggle timeout");
PROFILER_ADD_MARKER("Fullscreen toggle timeout");
}
if (shouldContinue) {
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();

Просмотреть файл

@ -1239,8 +1239,8 @@ static void
FireForgetSkippable(uint32_t aSuspected, bool aRemoveChildless,
TimeStamp aDeadline)
{
AutoProfilerTracing
tracing("CC", aDeadline.IsNull() ? "ForgetSkippable" : "IdleForgetSkippable");
AUTO_PROFILER_TRACING("CC", aDeadline.IsNull() ? "ForgetSkippable"
: "IdleForgetSkippable");
PRTime startTime = PR_Now();
TimeStamp startTimeStamp = TimeStamp::Now();
FinishAnyIncrementalGC();
@ -1489,8 +1489,7 @@ nsJSContext::RunCycleCollectorSlice(TimeStamp aDeadline)
return;
}
AutoProfilerTracing
tracing("CC", aDeadline.IsNull() ? "CCSlice" : "IdleCCSlice");
AUTO_PROFILER_TRACING("CC", aDeadline.IsNull() ? "CCSlice" : "IdleCCSlice");
AUTO_PROFILER_LABEL("nsJSContext::RunCycleCollectorSlice", CC);

Просмотреть файл

@ -135,8 +135,10 @@ EvaluationExceptionToNSResult(JSContext* aCx)
nsJSUtils::ExecutionContext::ExecutionContext(JSContext* aCx,
JS::Handle<JSObject*> aGlobal)
:
#ifdef MOZ_GECKO_PROFILER
mAutoProfilerLabel("nsJSUtils::ExecutionContext", /* dynamicStr */ nullptr,
__LINE__, js::ProfileEntry::Category::JS),
#endif
mCx(aCx)
, mCompartment(aCx, aGlobal)
, mRetValue(aCx)

Просмотреть файл

@ -68,8 +68,10 @@ public:
// ExecutionContext is used to switch compartment.
class MOZ_STACK_CLASS ExecutionContext {
#ifdef MOZ_GECKO_PROFILER
// Register stack annotations for the Gecko profiler.
mozilla::AutoProfilerLabel mAutoProfilerLabel;
#endif
JSContext* mCx;

Просмотреть файл

@ -30,7 +30,6 @@
#include "EventListenerService.h"
#include "GeckoProfiler.h"
#include "ProfilerMarkerPayload.h"
#include "nsCOMArray.h"
#include "nsCOMPtr.h"
#include "nsContentUtils.h"
@ -53,6 +52,10 @@
#include "nsIFrame.h"
#include "nsDisplayList.h"
#ifdef MOZ_GECKO_PROFILER
#include "ProfilerMarkerPayload.h"
#endif
namespace mozilla {
using namespace dom;
@ -1262,6 +1265,7 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
}
nsresult rv = NS_OK;
#ifdef MOZ_GECKO_PROFILER
if (profiler_is_active()) {
// Add a profiler label and a profiler marker for the actual
// dispatch of the event.
@ -1285,7 +1289,9 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
MakeUnique<DOMEventMarkerPayload>(typeStr, phase,
aEvent->mTimeStamp,
startTime, endTime));
} else {
} else
#endif
{
rv = HandleEventSubType(listener, *aDOMEvent, aCurrentTarget);
}

Просмотреть файл

@ -291,7 +291,12 @@ LoggingHelper(bool aUseProfiler, const char* aFmt, ...)
static const mozilla::LogLevel logLevel = LogLevel::Warning;
if (MOZ_LOG_TEST(logModule, logLevel) ||
(aUseProfiler && profiler_is_active())) {
#ifdef MOZ_GECKO_PROFILER
(aUseProfiler && profiler_is_active())
#else
false
#endif
) {
nsAutoCString message;
{
@ -306,7 +311,7 @@ LoggingHelper(bool aUseProfiler, const char* aFmt, ...)
MOZ_LOG(logModule, logLevel, ("%s", message.get()));
if (aUseProfiler) {
profiler_add_marker(message.get());
PROFILER_ADD_MARKER(message.get());
}
}
}

Просмотреть файл

@ -158,7 +158,7 @@ void HRTFDatabaseLoader::MainThreadRelease()
// Asynchronously load the database in this thread.
static void databaseLoaderEntry(void* threadData)
{
AutoProfilerRegisterThread registerThread("HRTFDatabaseLdr");
AUTO_PROFILER_REGISTER_THREAD("HRTFDatabaseLdr");
NS_SetCurrentThreadName("HRTFDatabaseLdr");
HRTFDatabaseLoader* loader = reinterpret_cast<HRTFDatabaseLoader*>(threadData);

Просмотреть файл

@ -8,7 +8,6 @@
#include "GeckoProfiler.h"
#include "nsRFPService.h"
#include "ProfilerMarkerPayload.h"
#include "PerformanceEntry.h"
#include "PerformanceMainThread.h"
#include "PerformanceMark.h"
@ -28,6 +27,10 @@
#include "WorkerPrivate.h"
#include "WorkerRunnable.h"
#ifdef MOZ_GECKO_PROFILER
#include "ProfilerMarkerPayload.h"
#endif
#define PERFLOG(msg, ...) printf_stderr(msg, ##__VA_ARGS__)
namespace mozilla {
@ -266,11 +269,13 @@ Performance::Mark(const nsAString& aName, ErrorResult& aRv)
new PerformanceMark(GetParentObject(), aName, Now());
InsertUserEntry(performanceMark);
#ifdef MOZ_GECKO_PROFILER
if (profiler_is_active()) {
profiler_add_marker(
"UserTiming",
MakeUnique<UserTimingMarkerPayload>(aName, TimeStamp::Now()));
}
#endif
}
void
@ -352,6 +357,7 @@ Performance::Measure(const nsAString& aName,
new PerformanceMeasure(GetParentObject(), aName, startTime, endTime);
InsertUserEntry(performanceMeasure);
#ifdef MOZ_GECKO_PROFILER
if (profiler_is_active()) {
TimeStamp startTimeStamp = CreationTimeStamp() +
TimeDuration::FromMilliseconds(startTime);
@ -361,6 +367,7 @@ Performance::Measure(const nsAString& aName,
"UserTiming",
MakeUnique<UserTimingMarkerPayload>(aName, startTimeStamp, endTimeStamp));
}
#endif
}
void

Просмотреть файл

@ -489,7 +489,7 @@ StorageDBThread::SetDefaultPriority()
void
StorageDBThread::ThreadFunc(void* aArg)
{
AutoProfilerRegisterThread registerThread("localStorage DB");
AUTO_PROFILER_REGISTER_THREAD("localStorage DB");
NS_SetCurrentThreadName("localStorage DB");
mozilla::IOInterposer::RegisterCurrentThread();

Просмотреть файл

@ -656,7 +656,7 @@ VRDisplay::GetLayers(nsTArray<VRLayer>& result)
void
VRDisplay::SubmitFrame()
{
AutoProfilerTracing tracing("VR", "SubmitFrameAtVRDisplay");
AUTO_PROFILER_TRACING("VR", "SubmitFrameAtVRDisplay");
if (mPresentation) {
mPresentation->SubmitFrame();

Просмотреть файл

@ -596,7 +596,7 @@ InterruptCallback(JSContext* aCx)
MOZ_ASSERT(worker);
// Now is a good time to turn on profiling if it's pending.
profiler_js_interrupt_callback();
PROFILER_JS_INTERRUPT_CALLBACK();
return worker->InterruptCallback(aCx);
}
@ -2765,8 +2765,6 @@ WorkerThreadPrimaryRunnable::Run()
{
using mozilla::ipc::BackgroundChild;
char stackBaseGuess;
NS_SetCurrentThreadName("DOM Worker");
nsAutoCString threadName;
@ -2774,7 +2772,7 @@ WorkerThreadPrimaryRunnable::Run()
threadName.Append(NS_LossyConvertUTF16toASCII(mWorkerPrivate->ScriptURL()));
threadName.Append('\'');
profiler_register_thread(threadName.get(), &stackBaseGuess);
AUTO_PROFILER_REGISTER_THREAD(threadName.get());
// Note: GetOrCreateForCurrentThread() must be called prior to
// mWorkerPrivate->SetThread() in order to avoid accidentally consuming
@ -2839,7 +2837,7 @@ WorkerThreadPrimaryRunnable::Run()
}
{
profiler_set_js_context(cx);
PROFILER_SET_JS_CONTEXT(cx);
{
JSAutoRequest ar(cx);
@ -2853,7 +2851,7 @@ WorkerThreadPrimaryRunnable::Run()
BackgroundChild::CloseForCurrentThread();
profiler_clear_js_context();
PROFILER_CLEAR_JS_CONTEXT();
}
// There may still be runnables on the debugger event queue that hold a
@ -2893,7 +2891,6 @@ WorkerThreadPrimaryRunnable::Run()
MOZ_ALWAYS_SUCCEEDS(mainTarget->Dispatch(finishedRunnable,
NS_DISPATCH_NORMAL));
profiler_unregister_thread();
return NS_OK;
}

Просмотреть файл

@ -331,7 +331,7 @@ ClientLayerManager::EndTransactionInternal(DrawPaintedLayerCallback aCallback,
EndTransactionFlags)
{
PaintTelemetry::AutoRecord record(PaintTelemetry::Metric::Rasterization);
AutoProfilerTracing tracing("Paint", "Rasterize");
AUTO_PROFILER_TRACING("Paint", "Rasterize");
Maybe<TimeStamp> startTime;
if (gfxPrefs::LayersDrawFPS()) {
@ -723,7 +723,7 @@ ClientLayerManager::StopFrameTimeRecording(uint32_t aStartIndex,
void
ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
{
AutoProfilerTracing tracing("Paint", "ForwardTransaction");
AUTO_PROFILER_TRACING("Paint", "ForwardTransaction");
TimeStamp start = TimeStamp::Now();
// Skip the synchronization for buffer since we also skip the painting during

Просмотреть файл

@ -109,7 +109,7 @@ ContentClient::PrintInfo(std::stringstream& aStream, const char* aPrefix)
aStream << aPrefix;
aStream << nsPrintfCString("ContentClient (0x%p)", this).get();
if (profiler_feature_active(ProfilerFeature::DisplayListDump)) {
if (PROFILER_FEATURE_ACTIVE(ProfilerFeature::DisplayListDump)) {
nsAutoCString pfx(aPrefix);
pfx += " ";

Просмотреть файл

@ -1397,7 +1397,7 @@ TextureClient::PrintInfo(std::stringstream& aStream, const char* aPrefix)
#ifdef MOZ_DUMP_PAINTING
if (gfxPrefs::LayersDumpTexture() ||
profiler_feature_active(ProfilerFeature::LayersDump)) {
PROFILER_FEATURE_ACTIVE(ProfilerFeature::LayersDump)) {
nsAutoCString pfx(aPrefix);
pfx += " ";

Просмотреть файл

@ -1400,7 +1400,7 @@ TiledContentClient::PrintInfo(std::stringstream& aStream, const char* aPrefix)
aStream << aPrefix;
aStream << nsPrintfCString("%sTiledContentClient (0x%p)", mName, this).get();
if (profiler_feature_active(ProfilerFeature::DisplayListDump)) {
if (PROFILER_FEATURE_ACTIVE(ProfilerFeature::DisplayListDump)) {
nsAutoCString pfx(aPrefix);
pfx += " ";

Просмотреть файл

@ -35,7 +35,10 @@
#include "TextRenderer.h" // for TextRenderer
#include <vector>
#include "GeckoProfiler.h" // for GeckoProfiler
#ifdef MOZ_GECKO_PROFILER
#include "ProfilerMarkerPayload.h" // for LayerTranslationMarkerPayload
#endif
#define CULLING_LOG(...)
// #define CULLING_LOG(...) printf_stderr("CULLING: " __VA_ARGS__)
@ -81,6 +84,7 @@ DrawLayerInfo(const RenderTargetIntRect& aClipRect,
static void
PrintUniformityInfo(Layer* aLayer)
{
#if defined(MOZ_GECKO_PROFILER)
if (!profiler_is_active()) {
return;
}
@ -101,6 +105,7 @@ PrintUniformityInfo(Layer* aLayer)
"LayerTranslation",
MakeUnique<LayerTranslationMarkerPayload>(aLayer, translation,
TimeStamp::Now()));
#endif
}
static Maybe<gfx::Polygon>

Просмотреть файл

@ -865,10 +865,10 @@ LayerManagerComposite::Render(const nsIntRegion& aInvalidRegion, const nsIntRegi
// Dump to console
if (gfxPrefs::LayersDump()) {
this->Dump(/* aSorted= */true);
} else if (profiler_feature_active(ProfilerFeature::LayersDump)) {
} else if (PROFILER_FEATURE_ACTIVE(ProfilerFeature::LayersDump)) {
std::stringstream ss;
Dump(ss);
profiler_tracing("log", ss.str().c_str(), TRACING_EVENT);
PROFILER_TRACING("log", ss.str().c_str(), TRACING_EVENT);
}
// Dump to LayerScope Viewer

Просмотреть файл

@ -411,7 +411,7 @@ TextureHost::PrintInfo(std::stringstream& aStream, const char* aPrefix)
AppendToString(aStream, mFlags, " [flags=", "]");
#ifdef MOZ_DUMP_PAINTING
if (gfxPrefs::LayersDumpTexture() ||
profiler_feature_active(ProfilerFeature::LayersDump)) {
PROFILER_FEATURE_ACTIVE(ProfilerFeature::LayersDump)) {
nsAutoCString pfx(aPrefix);
pfx += " ";

Просмотреть файл

@ -625,13 +625,15 @@ TiledContentHost::PrintInfo(std::stringstream& aStream, const char* aPrefix)
aStream << aPrefix;
aStream << nsPrintfCString("TiledContentHost (0x%p)", this).get();
#if defined(MOZ_DUMP_PAINTING)
if (gfxPrefs::LayersDumpTexture() ||
profiler_feature_active(ProfilerFeature::LayersDump)) {
PROFILER_FEATURE_ACTIVE(ProfilerFeature::LayersDump)) {
nsAutoCString pfx(aPrefix);
pfx += " ";
Dump(aStream, pfx.get(), false);
}
#endif
}
void

Просмотреть файл

@ -286,7 +286,7 @@ static void RunCompositorBench(Compositor* aCompositor, const gfx::Rect& aScreen
BenchTest* test = tests[i];
std::vector<TimeDuration> results;
int testsOverThreshold = 0;
profiler_add_marker(test->ToString());
PROFILER_ADD_MARKER(test->ToString());
for (size_t j = 0; j < TEST_STEPS; j++) {
test->Setup(aCompositor, j);

Просмотреть файл

@ -84,10 +84,12 @@
#include "mozilla/HalTypes.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/Telemetry.h"
#include "ProfilerMarkerPayload.h"
#ifdef MOZ_GECKO_PROFILER
# include "ProfilerMarkerPayload.h"
#endif
#include "mozilla/VsyncDispatcher.h"
#if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
#include "VsyncSource.h"
# include "VsyncSource.h"
#endif
#include "mozilla/widget/CompositorWidget.h"
#ifdef MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING
@ -937,7 +939,7 @@ CompositorBridgeParent::SetShadowProperties(Layer* aLayer)
void
CompositorBridgeParent::CompositeToTarget(DrawTarget* aTarget, const gfx::IntRect* aRect)
{
AutoProfilerTracing tracing("Paint", "Composite");
AUTO_PROFILER_TRACING("Paint", "Composite");
AUTO_PROFILER_LABEL("CompositorBridgeParent::CompositeToTarget", GRAPHICS);
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread(),
@ -1839,6 +1841,7 @@ CompositorBridgeParent::GetAPZCTreeManager(uint64_t aLayersId)
return apzctm.forget();
}
#if defined(MOZ_GECKO_PROFILER)
static void
InsertVsyncProfilerMarker(TimeStamp aVsyncTimestamp)
{
@ -1847,15 +1850,18 @@ InsertVsyncProfilerMarker(TimeStamp aVsyncTimestamp)
"VsyncTimestamp",
MakeUnique<VsyncMarkerPayload>(aVsyncTimestamp));
}
#endif
/*static */ void
CompositorBridgeParent::PostInsertVsyncProfilerMarker(TimeStamp aVsyncTimestamp)
{
#if defined(MOZ_GECKO_PROFILER)
// Called in the vsync thread
if (profiler_is_active() && CompositorThreadHolder::IsActive()) {
CompositorLoop()->PostTask(
NewRunnableFunction(InsertVsyncProfilerMarker, aVsyncTimestamp));
}
#endif
}
widget::PCompositorWidgetParent*

Просмотреть файл

@ -170,7 +170,7 @@ LayerTransactionParent::RecvInitReadLocks(ReadLockArray&& aReadLocks)
mozilla::ipc::IPCResult
LayerTransactionParent::RecvUpdate(const TransactionInfo& aInfo)
{
AutoProfilerTracing tracing("Paint", "LayerTransaction");
AUTO_PROFILER_TRACING("Paint", "LayerTransaction");
AUTO_PROFILER_LABEL("LayerTransactionParent::RecvUpdate", GRAPHICS);
TimeStamp updateStart = TimeStamp::Now();

Просмотреть файл

@ -534,7 +534,7 @@ WebRenderBridgeParent::RecvSetDisplayList(const gfx::IntSize& aSize,
return IPC_OK();
}
AutoProfilerTracing tracing("Paint", "SetDisplayList");
AUTO_PROFILER_TRACING("Paint", "SetDisplayList");
UpdateFwdTransactionId(aFwdTransactionId);
AutoClearReadLocks clearLocks(mReadLocks);
@ -1087,7 +1087,7 @@ WebRenderBridgeParent::SampleAnimations(nsTArray<wr::WrOpacityProperty>& aOpacit
void
WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect)
{
AutoProfilerTracing tracing("Paint", "CompositeToTraget");
AUTO_PROFILER_TRACING("Paint", "CompositeToTraget");
if (mPaused) {
return;
}

Просмотреть файл

@ -231,7 +231,7 @@ WebRenderLayerManager::EndTransactionWithoutLayer(nsDisplayList* aDisplayList,
MOZ_ASSERT(aDisplayList && aDisplayListBuilder);
WrBridge()->RemoveExpiredFontKeys();
AutoProfilerTracing tracing("Paint", "RenderLayers");
AUTO_PROFILER_TRACING("Paint", "RenderLayers");
mTransactionIncomplete = false;
if (gfxPrefs::LayersDump()) {
@ -303,8 +303,8 @@ WebRenderLayerManager::EndTransactionWithoutLayer(nsDisplayList* aDisplayList,
mLastDisplayListSize = dl.dl.inner.capacity;
{
AutoProfilerTracing
tracing("Paint", sync ? "ForwardDPTransactionSync":"ForwardDPTransaction");
AUTO_PROFILER_TRACING("Paint", sync ? "ForwardDPTransactionSync"
: "ForwardDPTransaction");
WrBridge()->EndTransaction(contentSize, dl, resourceUpdates, size.ToUnknownSize(), sync,
mLatestTransactionId, mScrollData, transactionStart);
}

Просмотреть файл

@ -6,13 +6,17 @@
#include "ContextStateTracker.h"
#include "GLContext.h"
#include "GeckoProfiler.h"
#ifdef MOZ_GECKO_PROFILER
#include "ProfilerMarkerPayload.h"
#endif
namespace mozilla {
void
ContextStateTrackerOGL::PushOGLSection(GLContext* aGL, const char* aSectionName)
{
#ifdef MOZ_GECKO_PROFILER
if (!profiler_feature_active(ProfilerFeature::GPU)) {
return;
}
@ -22,8 +26,8 @@ ContextStateTrackerOGL::PushOGLSection(GLContext* aGL, const char* aSectionName)
}
if (mSectionStack.Length() > 0) {
// We need to end the query since we're starting a new section and restore it
// when this section is finished.
// We need to end the query since we're starting a new section and restore
// it when this section is finished.
aGL->fEndQuery(LOCAL_GL_TIME_ELAPSED);
Top().mCpuTimeEnd = TimeStamp::Now();
}
@ -38,6 +42,7 @@ ContextStateTrackerOGL::PushOGLSection(GLContext* aGL, const char* aSectionName)
aGL->fBeginQuery(LOCAL_GL_TIME_ELAPSED_EXT, queryObject);
mSectionStack.AppendElement(newSection);
#endif
}
void
@ -109,6 +114,7 @@ ContextStateTrackerOGL::Flush(GLContext* aGL)
aGL->fDeleteQueries(1, &handle);
#ifdef MOZ_GECKO_PROFILER
if (profiler_is_active()) {
profiler_add_marker(
"gpu_timer_query",
@ -116,6 +122,7 @@ ContextStateTrackerOGL::Flush(GLContext* aGL)
mCompletedSections[0].mCpuTimeEnd,
0, gpuTime));
}
#endif
mCompletedSections.RemoveElementAt(0);
}

Просмотреть файл

@ -182,7 +182,7 @@ VRDisplayHost::RemoveLayer(VRLayerParent *aLayer)
void
VRDisplayHost::StartFrame()
{
AutoProfilerTracing tracing("VR", "GetSensorState");
AUTO_PROFILER_TRACING("VR", "GetSensorState");
mLastFrameStart = TimeStamp::Now();
++mDisplayInfo.mFrameId;
@ -261,7 +261,7 @@ VRDisplayHost::SubmitFrame(VRLayerParent* aLayer,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect)
{
AutoProfilerTracing tracing("VR", "SubmitFrameAtVRDisplayHost");
AUTO_PROFILER_TRACING("VR", "SubmitFrameAtVRDisplayHost");
if ((mDisplayInfo.mGroupMask & aLayer->GetGroup()) == 0) {
// Suppress layers hidden by the group mask

Просмотреть файл

@ -449,7 +449,7 @@ VRManagerChild::RecvReplyCreateVRServiceTestController(const nsCString& aID,
void
VRManagerChild::RunFrameRequestCallbacks()
{
AutoProfilerTracing tracing("VR", "RunFrameRequestCallbacks");
AUTO_PROFILER_TRACING("VR", "RunFrameRequestCallbacks");
TimeStamp nowTime = TimeStamp::Now();
mozilla::TimeDuration duration = nowTime - mStartTimeStamp;

Просмотреть файл

@ -205,7 +205,7 @@ NotifyDidRender(layers::CompositorBridgeParentBase* aBridge,
void
RenderThread::UpdateAndRender(wr::WindowId aWindowId)
{
AutoProfilerTracing tracing("Paint", "Composite");
AUTO_PROFILER_TRACING("Paint", "Composite");
MOZ_ASSERT(IsInRenderThread());
auto it = mRenderers.find(aWindowId);

Просмотреть файл

@ -180,9 +180,7 @@ public:
case Work::Type::SHUTDOWN:
DecodePoolImpl::ShutdownThread(thisThread);
profiler_unregister_thread();
PROFILER_UNREGISTER_THREAD();
return NS_OK;
default:

Просмотреть файл

@ -57,7 +57,7 @@ void MessagePumpDefault::Run(Delegate* delegate) {
hangMonitor.NotifyWait();
AUTO_PROFILER_LABEL("MessagePumpDefault::Run:Wait", OTHER);
{
mozilla::AutoProfilerThreadSleep sleep;
AUTO_PROFILER_THREAD_SLEEP;
event_.Wait();
}
} else {
@ -66,7 +66,7 @@ void MessagePumpDefault::Run(Delegate* delegate) {
hangMonitor.NotifyWait();
AUTO_PROFILER_LABEL("MessagePumpDefault::Run:Wait", OTHER);
{
mozilla::AutoProfilerThreadSleep sleep;
AUTO_PROFILER_THREAD_SLEEP;
event_.TimedWait(delay);
}
} else {

Просмотреть файл

@ -154,7 +154,7 @@ void Thread::StopSoon() {
}
void Thread::ThreadMain() {
mozilla::AutoProfilerRegisterThread registerThread(name_.c_str());
AUTO_PROFILER_REGISTER_THREAD(name_.c_str());
mozilla::IOInterposer::RegisterCurrentThread();
// The message loop for this thread.

Просмотреть файл

@ -572,7 +572,9 @@ GeckoChildProcessHost::SetChildLogName(const char* varName, const char* origLogN
bool
GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts, base::ProcessArchitecture arch)
{
#ifdef MOZ_GECKO_PROFILER
AutoSetProfilerEnvVarsForChildProcess profilerEnvironment;
#endif
const char* origNSPRLogName = PR_GetEnv("NSPR_LOG_FILE");
const char* origMozLogName = PR_GetEnv("MOZ_LOG_FILE");

Просмотреть файл

@ -4626,10 +4626,9 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
+ [ Whitespace.NL,
StmtDecl(Decl(Type.BOOL, sendok.name)),
StmtBlock([
StmtDecl(Decl(Type('AutoProfilerTracing'),
'syncIPCTracer'),
initargs=[ ExprLiteral.String("IPC"),
ExprLiteral.String(self.protocol.name + "::" + md.prettyMsgName()) ]),
StmtExpr(ExprCall(ExprVar('AUTO_PROFILER_TRACING'),
[ ExprLiteral.String("IPC"),
ExprLiteral.String(self.protocol.name + "::" + md.prettyMsgName()) ])),
StmtExpr(ExprAssn(sendok,
ExprCall(ExprSelect(self.protocol.callGetChannel(actor),
'->',

Просмотреть файл

@ -129,7 +129,7 @@ MainThreadInvoker::Invoke(already_AddRefed<nsIRunnable>&& aRunnable)
/* static */ VOID CALLBACK
MainThreadInvoker::MainThreadAPC(ULONG_PTR aParam)
{
AutoProfilerThreadWake wake;
AUTO_PROFILER_THREAD_WAKE;
mozilla::HangMonitor::NotifyActivity(mozilla::HangMonitor::kGeneralActivity);
MOZ_ASSERT(NS_IsMainThread());
auto runnable = reinterpret_cast<SyncRunnable*>(aParam);

Просмотреть файл

@ -2504,9 +2504,11 @@ nsXPCComponents_Utils::Import(const nsACString& registryLocation,
RefPtr<mozJSComponentLoader> moduleloader = mozJSComponentLoader::Get();
MOZ_ASSERT(moduleloader);
#ifdef MOZ_GECKO_PROFILER
const nsCString& flatLocation = PromiseFlatCString(registryLocation);
AUTO_PROFILER_LABEL_DYNAMIC("nsXPCComponents_Utils::Import", OTHER,
flatLocation.get());
#endif
return moduleloader->Import(registryLocation, targetObj, cx, optionalArgc, retval);
}

Просмотреть файл

@ -472,7 +472,7 @@ AutoLockWatchdog::~AutoLockWatchdog()
static void
WatchdogMain(void* arg)
{
mozilla::AutoProfilerRegisterThread registerThread("JS Watchdog");
AUTO_PROFILER_REGISTER_THREAD("JS Watchdog");
NS_SetCurrentThreadName("JS Watchdog");
Watchdog* self = static_cast<Watchdog*>(arg);
@ -601,7 +601,7 @@ XPCJSContext::InterruptCallback(JSContext* cx)
XPCJSContext* self = XPCJSContext::Get();
// Now is a good time to turn on profiling if it's pending.
profiler_js_interrupt_callback();
PROFILER_JS_INTERRUPT_CALLBACK();
// Normally we record mSlowScriptCheckpoint when we start to process an
// event. However, we can run JS outside of event handlers. This code takes
@ -910,7 +910,7 @@ XPCJSContext::~XPCJSContext()
delete rtPrivate;
JS_SetContextPrivate(Context(), nullptr);
profiler_clear_js_context();
PROFILER_CLEAR_JS_CONTEXT();
gTlsContext.set(nullptr);
}
@ -1093,7 +1093,7 @@ XPCJSContext::Initialize(XPCJSContext* aPrimaryContext)
kStackQuota - kSystemCodeBuffer,
kStackQuota - kSystemCodeBuffer - kTrustedScriptBuffer);
profiler_set_js_context(cx);
PROFILER_SET_JS_CONTEXT(cx);
js::SetActivityCallback(cx, ActivityCallback, this);
JS_AddInterruptCallback(cx, InterruptCallback);

Просмотреть файл

@ -1093,8 +1093,10 @@ XRE_XPCShellMain(int argc, char** argv, char** envp,
mozilla::LogModule::Init();
#ifdef MOZ_GECKO_PROFILER
char aLocal;
profiler_init(&aLocal);
#endif
if (PR_GetEnv("MOZ_CHAOSMODE")) {
ChaosFeature feature = ChaosFeature::Any;
@ -1417,9 +1419,11 @@ XRE_XPCShellMain(int argc, char** argv, char** envp,
CrashReporter::UnsetExceptionHandler();
#endif
#ifdef MOZ_GECKO_PROFILER
// This must precede NS_LogTerm(), otherwise xpcshell return non-zero
// during some tests, which causes failures.
profiler_shutdown();
#endif
NS_LogTerm();

Просмотреть файл

@ -3699,7 +3699,7 @@ void
PresShell::DispatchSynthMouseMove(WidgetGUIEvent* aEvent,
bool aFlushOnHoverChange)
{
AutoProfilerTracing tracing("Paint", "DispatchSynthMouseMove");
AUTO_PROFILER_TRACING("Paint", "DispatchSynthMouseMove");
RestyleManager* restyleManager = mPresContext->RestyleManager();
uint32_t hoverGenerationBefore =
restyleManager->GetHoverGeneration();
@ -4033,6 +4033,7 @@ PresShell::DoFlushPendingNotifications(mozilla::ChangesToFlush aFlush)
MOZ_ASSERT(NeedFlush(flushType), "Why did we get called?");
#ifdef MOZ_GECKO_PROFILER
static const EnumeratedArray<FlushType,
FlushType::Count,
const char*> flushTypeNames = {
@ -4048,9 +4049,9 @@ PresShell::DoFlushPendingNotifications(mozilla::ChangesToFlush aFlush)
"Layout",
"Display"
};
AUTO_PROFILER_LABEL_DYNAMIC("PresShell::DoFlushPendingNotifications",
GRAPHICS, flushTypeNames[flushType]);
#endif
#ifdef ACCESSIBILITY
#ifdef DEBUG

Просмотреть файл

@ -60,7 +60,9 @@ RestyleTracker::Document() const {
struct RestyleEnumerateData : RestyleTracker::Hints {
RefPtr<dom::Element> mElement;
#ifdef MOZ_GECKO_PROFILER
UniqueProfilerBacktrace mBacktrace;
#endif
};
inline void
@ -106,6 +108,7 @@ RestyleTracker::ProcessOneRestyle(Element* aElement,
void
RestyleTracker::DoProcessRestyles()
{
#ifdef MOZ_GECKO_PROFILER
nsAutoCString docURL("N/A");
if (profiler_is_active()) {
nsIURI *uri = Document()->GetDocumentURI();
@ -115,6 +118,7 @@ RestyleTracker::DoProcessRestyles()
}
AUTO_PROFILER_LABEL_DYNAMIC("RestyleTracker::DoProcessRestyles", CSS,
docURL.get());
#endif
// Create a AnimationsWithDestroyedFrame during restyling process to
// stop animations and transitions on elements that have no frame at the end
@ -252,10 +256,12 @@ RestyleTracker::DoProcessRestyles()
AutoRestyleTimelineMarker marker(
mRestyleManager->PresContext()->GetDocShell(),
data->mRestyleHint & eRestyle_AllHintsWithAnimations);
#ifdef MOZ_GECKO_PROFILER
Maybe<AutoProfilerTracing> tracing;
if (profiler_feature_active(ProfilerFeature::Restyle)) {
tracing.emplace("Paint", "Styles", Move(data->mBacktrace));
}
#endif
ProcessOneRestyle(element, data->mRestyleHint, data->mChangeHint,
data->mRestyleHintData);
AddRestyleRootsIfAwaitingRestyle(data->mDescendants);
@ -325,7 +331,9 @@ RestyleTracker::DoProcessRestyles()
// We can move data since we'll be clearing mPendingRestyles after
// we finish enumerating it.
restyle->mRestyleHintData = Move(data->mRestyleHintData);
#ifdef MOZ_GECKO_PROFILER
restyle->mBacktrace = Move(data->mBacktrace);
#endif
#ifdef RESTYLE_LOGGING
count++;
@ -351,10 +359,13 @@ RestyleTracker::DoProcessRestyles()
index++, count);
LOG_RESTYLE_INDENT();
#ifdef MOZ_GECKO_PROFILER
Maybe<AutoProfilerTracing> tracing;
if (profiler_feature_active(ProfilerFeature::Restyle)) {
tracing.emplace("Paint", "Styles", Move(currentRestyle->mBacktrace));
tracing.emplace("Paint", "Styles",
Move(currentRestyle->mBacktrace));
}
#endif
{
AutoRestyleTimelineMarker marker(

Просмотреть файл

@ -124,7 +124,9 @@ public:
// that we called AddPendingRestyle for and found the element this is
// the RestyleData for as its nearest restyle root.
nsTArray<RefPtr<Element>> mDescendants;
#if defined(MOZ_GECKO_PROFILER)
UniqueProfilerBacktrace mBacktrace;
#endif
};
/**
@ -259,9 +261,11 @@ RestyleTracker::AddPendingRestyleToTable(Element* aElement,
if (!existingData) {
RestyleData* rd =
new RestyleData(aRestyleHint, aMinChangeHint, aRestyleHintData);
#if defined(MOZ_GECKO_PROFILER)
if (profiler_feature_active(ProfilerFeature::Restyle)) {
rd->mBacktrace = profiler_get_backtrace();
}
#endif
mPendingRestyles.Put(aElement, rd);
return false;
}

Просмотреть файл

@ -3706,7 +3706,7 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
{
AUTO_PROFILER_LABEL("nsLayoutUtils::PaintFrame:BuildDisplayList",
GRAPHICS);
AutoProfilerTracing tracing("Paint", "DisplayList");
AUTO_PROFILER_TRACING("Paint", "DisplayList");
PaintTelemetry::AutoRecord record(PaintTelemetry::Metric::DisplayList);
@ -3759,7 +3759,7 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
startBuildDisplayList);
bool profilerNeedsDisplayList =
profiler_feature_active(ProfilerFeature::DisplayListDump);
PROFILER_FEATURE_ACTIVE(ProfilerFeature::DisplayListDump);
bool consoleNeedsDisplayList = gfxUtils::DumpDisplayList() || gfxEnv::DumpPaint();
#ifdef MOZ_DUMP_PAINTING
FILE* savedDumpFile = gfxUtils::sDumpPaintFile;
@ -3804,7 +3804,7 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
// Flush stream now to avoid reordering dump output relative to
// messages dumped by PaintRoot below.
if (profilerNeedsDisplayList && !consoleNeedsDisplayList) {
profiler_tracing("log", ss->str().c_str(), TRACING_EVENT);
PROFILER_TRACING("log", ss->str().c_str(), TRACING_EVENT);
} else {
fprint_stderr(gfxUtils::sDumpPaintFile, *ss);
}
@ -3877,7 +3877,7 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
}
if (profilerNeedsDisplayList && !consoleNeedsDisplayList) {
profiler_tracing("log", ss->str().c_str(), TRACING_EVENT);
PROFILER_TRACING("log", ss->str().c_str(), TRACING_EVENT);
} else {
fprint_stderr(gfxUtils::sDumpPaintFile, *ss);
}

Просмотреть файл

@ -323,7 +323,7 @@ protected:
LOG("[%p] ticking drivers...", this);
// RD is short for RefreshDriver
AutoProfilerTracing tracing("Paint", "RefreshDriverTick");
AUTO_PROFILER_TRACING("Paint", "RefreshDriverTick");
TickRefreshDrivers(jsnow, now, mContentRefreshDrivers);
TickRefreshDrivers(jsnow, now, mRootRefreshDrivers);
@ -1727,7 +1727,7 @@ nsRefreshDriver::RunFrameRequestCallbacks(TimeStamp aNowTime)
mFrameRequestCallbackDocs.Clear();
if (!frameRequestCallbacks.IsEmpty()) {
AutoProfilerTracing tracing("Paint", "Scripts");
AUTO_PROFILER_TRACING("Paint", "Scripts");
for (const DocumentFrameCallbacks& docCallbacks : frameRequestCallbacks) {
// XXXbz Bug 863140: GetInnerWindow can return the outer
// window in some cases.
@ -1901,7 +1901,9 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
DispatchScrollEvents();
if (mPresContext && mPresContext->GetPresShell()) {
#ifdef MOZ_GECKO_PROFILER
Maybe<AutoProfilerTracing> tracingStyleFlush;
#endif
AutoTArray<nsIPresShell*, 16> observers;
observers.AppendElements(mStyleFlushObservers);
for (uint32_t j = observers.Length();
@ -1912,10 +1914,12 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
if (!mStyleFlushObservers.RemoveElement(shell))
continue;
#ifdef MOZ_GECKO_PROFILER
if (!tracingStyleFlush) {
tracingStyleFlush.emplace("Paint", "Styles", Move(mStyleCause));
mStyleCause = nullptr;
}
#endif
nsCOMPtr<nsIPresShell> shellKungFuDeathGrip(shell);
shell->mObservingStyleFlushes = false;
@ -1932,7 +1936,9 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
}
} else if (i == 2) {
// This is the FlushType::Layout case.
#ifdef MOZ_GECKO_PROFILER
Maybe<AutoProfilerTracing> tracingLayoutFlush;
#endif
AutoTArray<nsIPresShell*, 16> observers;
observers.AppendElements(mLayoutFlushObservers);
for (uint32_t j = observers.Length();
@ -1943,10 +1949,12 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
if (!mLayoutFlushObservers.RemoveElement(shell))
continue;
#ifdef MOZ_GECKO_PROFILER
if (!tracingLayoutFlush) {
tracingLayoutFlush.emplace("Paint", "Reflow", Move(mReflowCause));
mReflowCause = nullptr;
}
#endif
nsCOMPtr<nsIPresShell> shellKungFuDeathGrip(shell);
shell->mObservingLayoutFlushes = false;
@ -2187,7 +2195,7 @@ nsRefreshDriver::FinishedWaitingForTransaction()
if (mSkippedPaints &&
!IsInRefresh() &&
(ObserverCount() || ImageRequestCount())) {
AutoProfilerTracing tracing("Paint", "RefreshDriverTick");
AUTO_PROFILER_TRACING("Paint", "RefreshDriverTick");
DoRefresh();
}
mSkippedPaints = false;

Просмотреть файл

@ -164,9 +164,11 @@ public:
// a stack is expensive. This is still useful if (1) you're trying to remove
// all flushes for a particial frame or (2) the costly flush is triggered
// near the call site where the first observer is triggered.
#ifdef MOZ_GECKO_PROFILER
if (!mStyleCause) {
mStyleCause = profiler_get_backtrace();
}
#endif
bool appended = mStyleFlushObservers.AppendElement(aShell) != nullptr;
EnsureTimerStarted();
@ -178,6 +180,7 @@ public:
bool AddLayoutFlushObserver(nsIPresShell* aShell) {
NS_ASSERTION(!IsLayoutFlushObserver(aShell),
"Double-adding layout flush observer");
#ifdef MOZ_GECKO_PROFILER
// We only get the cause for the first observer each frame because capturing
// a stack is expensive. This is still useful if (1) you're trying to remove
// all flushes for a particial frame or (2) the costly flush is triggered
@ -185,6 +188,7 @@ public:
if (!mReflowCause) {
mReflowCause = profiler_get_backtrace();
}
#endif
bool appended = mLayoutFlushObservers.AppendElement(aShell) != nullptr;
EnsureTimerStarted();
return appended;
@ -416,8 +420,10 @@ private:
mozilla::RefreshDriverTimer* ChooseTimer() const;
mozilla::RefreshDriverTimer* mActiveTimer;
#ifdef MOZ_GECKO_PROFILER
UniqueProfilerBacktrace mReflowCause;
UniqueProfilerBacktrace mStyleCause;
#endif
// nsPresContext passed in constructor and unset in Disconnect.
mozilla::WeakPtr<nsPresContext> mPresContext;

Просмотреть файл

@ -4755,7 +4755,7 @@ ScrollFrameHelper::ScrollEvent::Run()
void
ScrollFrameHelper::FireScrollEvent()
{
AutoProfilerTracing tracing("Paint", "FireScrollEvent");
AUTO_PROFILER_TRACING("Paint", "FireScrollEvent");
MOZ_ASSERT(mScrollEvent);
mScrollEvent->Revoke();
mScrollEvent = nullptr;

Просмотреть файл

@ -2209,7 +2209,7 @@ already_AddRefed<LayerManager> nsDisplayList::PaintRoot(nsDisplayListBuilder* aB
}
{
AutoProfilerTracing tracing("Paint", "LayerBuilding");
AUTO_PROFILER_TRACING("Paint", "LayerBuilding");
if (doBeginTransaction) {
if (aCtx) {

Просмотреть файл

@ -2704,14 +2704,13 @@ Gecko_Destroy_nsStyle##name(nsStyle##name* ptr) \
void
Gecko_RegisterProfilerThread(const char* name)
{
char stackTop;
profiler_register_thread(name, &stackTop);
PROFILER_REGISTER_THREAD(name);
}
void
Gecko_UnregisterProfilerThread()
{
profiler_unregister_thread();
PROFILER_UNREGISTER_THREAD();
}
bool

Просмотреть файл

@ -1456,15 +1456,13 @@ nsHostResolver::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const
void
nsHostResolver::ThreadFunc(void *arg)
{
char stackTop;
LOG(("DNS lookup thread - starting execution.\n"));
static nsThreadPoolNaming naming;
nsCString name = naming.GetNextThreadName("DNS Resolver");
AUTO_PROFILER_REGISTER_THREAD(name.BeginReading());
NS_SetCurrentThreadName(name.BeginReading());
profiler_register_thread(name.BeginReading(), &stackTop);
#if defined(RES_RETRY_ON_FAILURE)
nsResState rs;
@ -1535,8 +1533,6 @@ nsHostResolver::ThreadFunc(void *arg)
resolver->mThreadCount--;
NS_RELEASE(resolver);
LOG(("DNS lookup thread - queue empty, thread finished.\n"));
profiler_unregister_thread();
}
nsresult

Просмотреть файл

@ -118,7 +118,7 @@ nsresult nsKeygenThread::ConsumeResult(
static void nsKeygenThreadRunner(void *arg)
{
AutoProfilerRegisterThread registerThread("Keygen");
AUTO_PROFILER_REGISTER_THREAD("Keygen");
NS_SetCurrentThreadName("Keygen");
nsKeygenThread *self = static_cast<nsKeygenThread *>(arg);
self->Run();

Просмотреть файл

@ -22,7 +22,7 @@ NS_IMPL_ISUPPORTS(nsProtectedAuthThread, nsIProtectedAuthThread)
static void nsProtectedAuthThreadRunner(void *arg)
{
AutoProfilerRegisterThread registerThread("Protected Auth");
AUTO_PROFILER_REGISTER_THREAD("Protected Auth");
NS_SetCurrentThreadName("Protected Auth");
nsProtectedAuthThread *self = static_cast<nsProtectedAuthThread *>(arg);

Просмотреть файл

@ -390,7 +390,7 @@ const SECMODModule* SmartCardMonitoringThread::GetModule()
// C-like calling sequence to glue into PR_CreateThread.
void SmartCardMonitoringThread::LaunchExecute(void* arg)
{
AutoProfilerRegisterThread registerThread("SmartCard");
AUTO_PROFILER_REGISTER_THREAD("SmartCard");
NS_SetCurrentThreadName("SmartCard");
((SmartCardMonitoringThread*)arg)->Execute();

Просмотреть файл

@ -501,7 +501,7 @@ StartupCache::WaitOnWriteThread()
void
StartupCache::ThreadedWrite(void *aClosure)
{
AutoProfilerRegisterThread registerThread("StartupCache");
AUTO_PROFILER_REGISTER_THREAD("StartupCache");
NS_SetCurrentThreadName("StartupCache");
mozilla::IOInterposer::RegisterCurrentThread();
/*

Просмотреть файл

@ -65,7 +65,7 @@ private:
// Background hang monitor thread function
static void MonitorThread(void* aData)
{
AutoProfilerRegisterThread registerThread("BgHangMonitor");
AUTO_PROFILER_REGISTER_THREAD("BgHangMonitor");
NS_SetCurrentThreadName("BgHangManager");
/* We do not hold a reference to BackgroundHangManager here
@ -192,8 +192,10 @@ public:
bool mWaiting;
// Is the thread dedicated to a single BackgroundHangMonitor
BackgroundHangMonitor::ThreadType mThreadType;
#ifdef MOZ_GECKO_PROFILER
// Platform-specific helper to get hang stacks
ThreadStackHelper mStackHelper;
#endif
// Stack of current hang
HangStack mHangStack;
// Annotations for the current hang
@ -359,11 +361,13 @@ BackgroundHangManager::RunMonitorThread()
if (MOZ_LIKELY(!currentThread->mHanging)) {
if (MOZ_UNLIKELY(hangTime >= currentThread->mTimeout)) {
#ifdef MOZ_GECKO_PROFILER
// A hang started, collect a stack
currentThread->mStackHelper.GetStack(
currentThread->mHangStack,
currentThread->mRunnableName,
true);
#endif
// If we hang immediately on waking, then the most recently collected
// CPU usage is going to be an average across the whole time we were

Просмотреть файл

@ -7,6 +7,8 @@
#ifndef mozilla_ThreadStackHelper_h
#define mozilla_ThreadStackHelper_h
#ifdef MOZ_GECKO_PROFILER
#include "js/ProfilingStack.h"
#include "HangDetails.h"
#include "nsThread.h"
@ -25,10 +27,8 @@
// Support pseudostack and native stack on these platforms.
#if defined(XP_LINUX) || defined(XP_WIN) || defined(XP_MACOSX)
# ifdef MOZ_GECKO_PROFILER
# define MOZ_THREADSTACKHELPER_PSEUDO
# define MOZ_THREADSTACKHELPER_NATIVE
# endif
# define MOZ_THREADSTACKHELPER_PSEUDO
# define MOZ_THREADSTACKHELPER_NATIVE
#endif
@ -106,4 +106,6 @@ private:
} // namespace mozilla
#endif // MOZ_GECKO_PROFILER
#endif // mozilla_ThreadStackHelper_h

Просмотреть файл

@ -39,9 +39,13 @@ UNIFIED_SOURCES += [
'BackgroundHangMonitor.cpp',
'HangDetails.cpp',
'HangStack.cpp',
'ThreadStackHelper.cpp',
]
if CONFIG['MOZ_GECKO_PROFILER']:
UNIFIED_SOURCES += [
'ThreadStackHelper.cpp',
]
LOCAL_INCLUDES += [
'/caps', # For nsScriptSecurityManager.h
]

Просмотреть файл

@ -59,7 +59,7 @@ public:
#ifdef MOZILLA_INTERNAL_API
static void Record(Event ev) {
profiler_add_marker(Describe(ev));
PROFILER_ADD_MARKER(Describe(ev));
Record(ev, TimeStamp::Now());
}

Просмотреть файл

@ -387,7 +387,7 @@ nsAppStartup::Quit(uint32_t aMode)
}
}
profiler_add_marker("Shutdown start");
PROFILER_ADD_MARKER("Shutdown start");
mozilla::RecordShutdownStartTimeStamp();
mShuttingDown = true;
if (!mRestart) {

Просмотреть файл

@ -34,8 +34,8 @@ public:
size_t SizeOfExcludingThis() const;
#if defined(MOZ_GECKO_PROFILER)
/** Clears the contents of vectors and resets the index. */
void Clear();
/** Clears the contents of vectors and resets the index. */
void Clear();
#endif
private:

Просмотреть файл

@ -1540,7 +1540,7 @@ TelemetryImpl::DoStackCapture(const nsACString& aKey) {
nsresult
TelemetryImpl::CaptureStack(const nsACString& aKey) {
#if defined(MOZ_GECKO_PROFILER)
#ifdef MOZ_GECKO_PROFILER
TelemetryImpl::DoStackCapture(aKey);
#endif
return NS_OK;
@ -1991,7 +1991,7 @@ void RecordChromeHang(uint32_t duration,
void CaptureStack(const nsACString& aKey)
{
#if defined(MOZ_GECKO_PROFILER)
#ifdef MOZ_GECKO_PROFILER
TelemetryImpl::DoStackCapture(aKey);
#endif
}

Просмотреть файл

@ -216,7 +216,7 @@ PRMonitor* gWriteReady = nullptr;
void RunWriter(void* arg)
{
AutoProfilerRegisterThread registerThread("Shutdown Statistics Writer");
AUTO_PROFILER_REGISTER_THREAD("Shutdown Statistics Writer");
NS_SetCurrentThreadName("Shutdown Statistics Writer");
MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(arg);

Просмотреть файл

@ -93,7 +93,7 @@ struct TracerStartClosure {
*/
void TracerThread(void *arg)
{
AutoProfilerRegisterThread registerThread("Event Tracer");
AUTO_PROFILER_REGISTER_THREAD("Event Tracer");
NS_SetCurrentThreadName("Event Tracer");
TracerStartClosure* threadArgs = static_cast<TracerStartClosure*>(arg);

Просмотреть файл

@ -1514,7 +1514,7 @@ ScopedXPCOMStartup::~ScopedXPCOMStartup()
appStartup->DestroyHiddenWindow();
gDirServiceProvider->DoShutdown();
profiler_add_marker("Shutdown early");
PROFILER_ADD_MARKER("Shutdown early");
WriteConsoleLog();
@ -4740,8 +4740,7 @@ XREMain::XRE_main(int argc, char* argv[], const BootstrapConfig& aConfig)
CodeCoverageHandler::Init();
#endif
AutoProfilerInit profilerInit;
AUTO_PROFILER_INIT;
AUTO_PROFILER_LABEL("XREMain::XRE_main", OTHER);
nsresult rv = NS_OK;

Просмотреть файл

@ -399,8 +399,7 @@ XRE_InitChildProcess(int aArgc,
mozilla::LogModule::Init();
AutoProfilerInit profilerInit;
AUTO_PROFILER_INIT;
AUTO_PROFILER_LABEL("XRE_InitChildProcess", OTHER);
// Ensure AbstractThread is minimally setup, so async IPC messages
@ -771,7 +770,7 @@ XRE_InitParentProcess(int aArgc,
mozilla::LogModule::Init();
AutoProfilerInit profilerInit;
AUTO_PROFILER_INIT;
ScopedXREEmbed embed;

Просмотреть файл

@ -11,7 +11,9 @@ if CONFIG['MOZ_GECKO_PROFILER']:
]
EXPORTS += [
'public/ChildProfilerController.h',
'public/GeckoProfilerReporter.h',
'public/ProfilerChild.h',
'public/ProfilerMarkerPayload.h',
'public/ProfilerParent.h',
'public/shared-libraries.h',
]
@ -117,10 +119,10 @@ IPDL_SOURCES += [
include('/ipc/chromium/chromium-config.mozbuild')
# GeckoProfiler.h is the only code that's visible in non-MOZ_GECKO_PROFILER
# builds, and it only contains no-op macros in that case.
EXPORTS += [
'public/GeckoProfiler.h',
'public/GeckoProfilerReporter.h',
'public/ProfilerMarkerPayload.h',
]
if CONFIG['MOZ_TASK_TRACER']:

Просмотреть файл

@ -16,6 +16,39 @@
#ifndef GeckoProfiler_h
#define GeckoProfiler_h
#ifndef MOZ_GECKO_PROFILER
// This file can be #included unconditionally. However, everything within this
// file must be guarded by a #ifdef MOZ_GECKO_PROFILER, *except* for the
// following macros, which encapsulate the most common operations and thus
// avoid the need for many #ifdefs.
#define AUTO_PROFILER_INIT
#define PROFILER_REGISTER_THREAD(name)
#define PROFILER_UNREGISTER_THREAD()
#define AUTO_PROFILER_REGISTER_THREAD(name)
#define AUTO_PROFILER_THREAD_SLEEP
#define AUTO_PROFILER_THREAD_WAKE
#define PROFILER_JS_INTERRUPT_CALLBACK()
#define PROFILER_SET_JS_CONTEXT(cx)
#define PROFILER_CLEAR_JS_CONTEXT()
#define PROFILER_FEATURE_ACTIVE(feature) false
#define AUTO_PROFILER_LABEL(label, category)
#define AUTO_PROFILER_LABEL_DYNAMIC(label, category, dynamicStr)
#define PROFILER_ADD_MARKER(markerName)
#define PROFILER_TRACING(category, markerName, kind)
#define AUTO_PROFILER_TRACING(category, markerName)
#else // !MOZ_GECKO_PROFILER
#include <functional>
#include <signal.h>
#include <stdarg.h>
@ -49,17 +82,6 @@ template <class T, size_t MinInlineCapacity, class AllocPolicy> class Vector;
class TimeStamp;
} // namespace mozilla
// When the profiler is disabled functions declared with these macros are
// static inline functions (with a trivial return value if they are non-void)
// that will be optimized away during compilation.
#ifdef MOZ_GECKO_PROFILER
# define PROFILER_FUNC(decl, rv) decl;
# define PROFILER_FUNC_VOID(decl) void decl;
#else
# define PROFILER_FUNC(decl, rv) static inline decl { return rv; }
# define PROFILER_FUNC_VOID(decl) static inline void decl {}
#endif
// Macros used by the AUTO_PROFILER_* macros below.
#define PROFILER_RAII_PASTE(id, line) id ## line
#define PROFILER_RAII_EXPAND(id, line) PROFILER_RAII_PASTE(id, line)
@ -145,12 +167,15 @@ struct ProfilerFeature
// also be started. This call must happen before any other profiler calls
// (except profiler_start(), which will call profiler_init() if it hasn't
// already run).
PROFILER_FUNC_VOID(profiler_init(void* stackTop))
void profiler_init(void* stackTop);
#define AUTO_PROFILER_INIT \
mozilla::AutoProfilerInit PROFILER_RAII
// Clean up the profiler module, stopping it if required. This function may
// also save a shutdown profile if requested. No profiler calls should happen
// after this point and all pseudo labels should have been popped.
PROFILER_FUNC_VOID(profiler_shutdown())
void profiler_shutdown();
// Start the profiler -- initializing it first if necessary -- with the
// selected options. Stops and restarts the profiler if it is already active.
@ -160,23 +185,21 @@ PROFILER_FUNC_VOID(profiler_shutdown())
// "aInterval" the sampling interval, measured in millseconds.
// "aFeatures" is the feature set. Features unsupported by this
// platform/configuration are ignored.
PROFILER_FUNC_VOID(profiler_start(int aEntries, double aInterval,
uint32_t aFeatures,
const char** aFilters, uint32_t aFilterCount))
void profiler_start(int aEntries, double aInterval, uint32_t aFeatures,
const char** aFilters, uint32_t aFilterCount);
// Stop the profiler and discard the profile without saving it. A no-op if the
// profiler is inactive. After stopping the profiler is "inactive".
PROFILER_FUNC_VOID(profiler_stop())
void profiler_stop();
// If the profiler is inactive, start it. If it's already active, restart it if
// the requested settings differ from the current settings. Both the check and
// the state change are performed while the profiler state is locked.
// The only difference to profiler_start is that the current buffer contents are
// not discarded if the profiler is already running with the requested settings.
PROFILER_FUNC_VOID(profiler_ensure_started(int aEntries, double aInterval,
uint32_t aFeatures,
const char** aFilters,
uint32_t aFilterCount))
void profiler_ensure_started(int aEntries, double aInterval,
uint32_t aFeatures, const char** aFilters,
uint32_t aFilterCount);
//---------------------------------------------------------------------------
// Control the profiler
@ -184,9 +207,16 @@ PROFILER_FUNC_VOID(profiler_ensure_started(int aEntries, double aInterval,
// Register/unregister threads with the profiler. Both functions operate the
// same whether the profiler is active or inactive.
PROFILER_FUNC_VOID(profiler_register_thread(const char* name,
void* guessStackTop))
PROFILER_FUNC_VOID(profiler_unregister_thread())
#define PROFILER_REGISTER_THREAD(name) \
do { char stackTop; profiler_register_thread(name, &stackTop); } while (0)
#define PROFILER_UNREGISTER_THREAD() \
profiler_unregister_thread()
void profiler_register_thread(const char* name, void* guessStackTop);
void profiler_unregister_thread();
// Register and unregister a thread within a scope.
#define AUTO_PROFILER_REGISTER_THREAD(name) \
mozilla::AutoProfilerRegisterThread PROFILER_RAII(name)
// Pause and resume the profiler. No-ops if the profiler is inactive. While
// paused the profile will not take any samples and will not record any data
@ -194,24 +224,33 @@ PROFILER_FUNC_VOID(profiler_unregister_thread())
// Timeline markers will still be stored. This feature will keep JavaScript
// profiling enabled, thus allowing toggling the profiler without invalidating
// the JIT.
PROFILER_FUNC_VOID(profiler_pause())
PROFILER_FUNC_VOID(profiler_resume())
void profiler_pause();
void profiler_resume();
// These functions tell the profiler that a thread went to sleep so that we can
// avoid sampling it while it's sleeping. Calling profiler_thread_sleep()
// twice without an intervening profiler_thread_wake() is an error. All three
// functions operate the same whether the profiler is active or inactive.
PROFILER_FUNC_VOID(profiler_thread_sleep())
PROFILER_FUNC_VOID(profiler_thread_wake())
void profiler_thread_sleep();
void profiler_thread_wake();
// Mark a thread as asleep/awake within a scope.
#define AUTO_PROFILER_THREAD_SLEEP \
mozilla::AutoProfilerThreadSleep PROFILER_RAII
#define AUTO_PROFILER_THREAD_WAKE \
mozilla::AutoProfilerThreadWake PROFILER_RAII
// Called by the JSRuntime's operation callback. This is used to start profiling
// on auxiliary threads. Operates the same whether the profiler is active or
// not.
PROFILER_FUNC_VOID(profiler_js_interrupt_callback())
#define PROFILER_JS_INTERRUPT_CALLBACK() profiler_js_interrupt_callback()
void profiler_js_interrupt_callback();
// Set and clear the current thread's JSContext.
PROFILER_FUNC_VOID(profiler_set_js_context(JSContext* aCx))
PROFILER_FUNC_VOID(profiler_clear_js_context())
#define PROFILER_SET_JS_CONTEXT(cx) profiler_set_js_context(cx)
#define PROFILER_CLEAR_JS_CONTEXT() profiler_clear_js_context()
void profiler_set_js_context(JSContext* aCx);
void profiler_clear_js_context();
//---------------------------------------------------------------------------
// Get information from the profiler
@ -233,42 +272,42 @@ PROFILER_FUNC_VOID(profiler_clear_js_context())
// expensive data will end up being created but not used if another thread
// stops the profiler between the CreateExpensiveData() and PROFILER_OPERATION
// calls.
PROFILER_FUNC(bool profiler_is_active(), false)
bool profiler_is_active();
// Is the profiler active and paused? Returns false if the profiler is inactive.
PROFILER_FUNC(bool profiler_is_paused(), false)
bool profiler_is_paused();
// Is the current thread sleeping?
PROFILER_FUNC(bool profiler_thread_is_sleeping(), false)
bool profiler_thread_is_sleeping();
// Get all the features supported by the profiler that are accepted by
// profiler_start(). The result is the same whether the profiler is active or
// not.
PROFILER_FUNC(uint32_t profiler_get_available_features(), 0)
uint32_t profiler_get_available_features();
// Check if a profiler feature (specified via the ProfilerFeature type) is
// active. Returns false if the profiler is inactive. Note: the return value
// can become immediately out-of-date, much like the return value of
// profiler_is_active().
PROFILER_FUNC(bool profiler_feature_active(uint32_t aFeature), false)
#define PROFILER_FEATURE_ACTIVE(feature) profiler_feature_active(feature)
bool profiler_feature_active(uint32_t aFeature);
// Get the params used to start the profiler. Returns 0 and an empty vector
// (via outparams) if the profile is inactive. It's possible that the features
// returned may be slightly different to those requested due to required
// adjustments.
PROFILER_FUNC_VOID(
profiler_get_start_params(int* aEntrySize, double* aInterval,
uint32_t* aFeatures,
mozilla::Vector<const char*, 0,
mozilla::MallocAllocPolicy>*
aFilters))
void profiler_get_start_params(int* aEntrySize, double* aInterval,
uint32_t* aFeatures,
mozilla::Vector<const char*, 0,
mozilla::MallocAllocPolicy>*
aFilters);
// The number of milliseconds since the process started. Operates the same
// whether the profiler is active or inactive.
PROFILER_FUNC(double profiler_time(), 0)
double profiler_time();
// Get the current thread's ID.
PROFILER_FUNC(int profiler_current_thread_id(), 0)
int profiler_current_thread_id();
// An object of this class is passed to profiler_suspend_and_sample_thread().
// For each stack frame, one of the Collect methods will be called.
@ -302,19 +341,13 @@ public:
// pseudo-stack, JS stack, and (optionally) native stack, passing the collected
// frames into aCollector. aFeatures dictates which compiler features are used.
// |Privacy| and |Leaf| are the only relevant ones.
PROFILER_FUNC_VOID(
profiler_suspend_and_sample_thread(int aThreadId,
uint32_t aFeatures,
ProfilerStackCollector& aCollector,
bool aSampleNative = true))
void profiler_suspend_and_sample_thread(int aThreadId, uint32_t aFeatures,
ProfilerStackCollector& aCollector,
bool aSampleNative = true);
struct ProfilerBacktraceDestructor
{
#ifdef MOZ_GECKO_PROFILER
void operator()(ProfilerBacktrace*);
#else
void operator()(ProfilerBacktrace*) {}
#endif
};
using UniqueProfilerBacktrace =
@ -322,14 +355,14 @@ using UniqueProfilerBacktrace =
// Immediately capture the current thread's call stack and return it. A no-op
// if the profiler is inactive or in privacy mode.
PROFILER_FUNC(UniqueProfilerBacktrace profiler_get_backtrace(), nullptr)
UniqueProfilerBacktrace profiler_get_backtrace();
// Get information about the current buffer status. A no-op when the profiler
// is inactive. Do not call this function; call profiler_get_buffer_info()
// instead.
PROFILER_FUNC_VOID(profiler_get_buffer_info_helper(uint32_t* aCurrentPosition,
uint32_t* aEntries,
uint32_t* aGeneration))
void profiler_get_buffer_info_helper(uint32_t* aCurrentPosition,
uint32_t* aEntries,
uint32_t* aGeneration);
// Get information about the current buffer status. Returns (via outparams) the
// current write position in the buffer, the total size of the buffer, and the
@ -350,7 +383,7 @@ static inline void profiler_get_buffer_info(uint32_t* aCurrentPosition,
}
// Get the current thread's PseudoStack.
PROFILER_FUNC(PseudoStack* profiler_get_pseudo_stack(), nullptr)
PseudoStack* profiler_get_pseudo_stack();
//---------------------------------------------------------------------------
// Put profiling data into the profiler (labels and markers)
@ -397,10 +430,11 @@ PROFILER_FUNC(PseudoStack* profiler_get_pseudo_stack(), nullptr)
// aMarkerName is copied, so the caller does not need to ensure it lives for a
// certain length of time. A no-op if the profiler is inactive or in privacy
// mode.
PROFILER_FUNC_VOID(profiler_add_marker(const char* aMarkerName))
PROFILER_FUNC_VOID(
profiler_add_marker(const char* aMarkerName,
mozilla::UniquePtr<ProfilerMarkerPayload> aPayload))
#define PROFILER_ADD_MARKER(markerName) \
profiler_add_marker(markerName)
void profiler_add_marker(const char* aMarkerName);
void profiler_add_marker(const char* aMarkerName,
mozilla::UniquePtr<ProfilerMarkerPayload> aPayload);
enum TracingKind {
TRACING_EVENT,
@ -408,16 +442,18 @@ enum TracingKind {
TRACING_INTERVAL_END,
};
// Adds a tracing marker to the profile. A no-op if the profiler is inactive or
// in privacy mode.
#define PROFILER_TRACING(category, markerName, kind) \
profiler_tracing(category, markerName, kind)
void profiler_tracing(const char* aCategory, const char* aMarkerName,
TracingKind aKind);
void profiler_tracing(const char* aCategory, const char* aMarkerName,
TracingKind aKind, UniqueProfilerBacktrace aCause);
// Adds a tracing marker to the PseudoStack. A no-op if the profiler is
// inactive or in privacy mode.
PROFILER_FUNC_VOID(profiler_tracing(const char* aCategory,
const char* aMarkerName,
TracingKind aKind))
PROFILER_FUNC_VOID(profiler_tracing(const char* aCategory,
const char* aMarkerName,
TracingKind aKind,
UniqueProfilerBacktrace aCause))
// Adds a START/END pair of tracing markers.
#define AUTO_PROFILER_TRACING(category, markerName) \
mozilla::AutoProfilerTracing PROFILER_RAII(category, markerName)
//---------------------------------------------------------------------------
// Output profiles
@ -427,19 +463,15 @@ PROFILER_FUNC_VOID(profiler_tracing(const char* aCategory,
// profiler is inactive.
// If aIsShuttingDown is true, the current time is included as the process
// shutdown time in the JSON's "meta" object.
PROFILER_FUNC(
mozilla::UniquePtr<char[]> profiler_get_profile(double aSinceTime = 0,
bool aIsShuttingDown = false),
nullptr)
mozilla::UniquePtr<char[]> profiler_get_profile(double aSinceTime = 0,
bool aIsShuttingDown = false);
// Write the profile for this process (excluding subprocesses) into aWriter.
// Returns false if the profiler is inactive.
PROFILER_FUNC(
bool profiler_stream_json_for_this_process(SpliceableJSONWriter& aWriter,
double aSinceTime = 0,
bool aIsShuttingDown = false,
mozilla::TimeStamp* aOutFirstSampleTime = nullptr),
false)
bool profiler_stream_json_for_this_process(SpliceableJSONWriter& aWriter,
double aSinceTime = 0,
bool aIsShuttingDown = false,
mozilla::TimeStamp* aOutFirstSampleTime = nullptr);
// Get the profile and write it into a file. A no-op if the profile is
// inactive.
@ -448,7 +480,7 @@ PROFILER_FUNC(
// in a build without debugging information (a workaround for
// http://llvm.org/bugs/show_bug.cgi?id=22211).
extern "C" {
PROFILER_FUNC_VOID(profiler_save_profile_to_file(const char* aFilename))
void profiler_save_profile_to_file(const char* aFilename);
}
//---------------------------------------------------------------------------
@ -478,7 +510,7 @@ class MOZ_RAII AutoProfilerRegisterThread final
{
public:
explicit AutoProfilerRegisterThread(const char* aName
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
profiler_register_thread(aName, this);
@ -550,30 +582,25 @@ public:
// This function runs both on and off the main thread.
#ifdef MOZ_GECKO_PROFILER
mPseudoStack = sPseudoStack.get();
if (mPseudoStack) {
mPseudoStack->pushCppFrame(aLabel, aDynamicString, this, aLine,
js::ProfileEntry::Kind::CPP_NORMAL, aCategory);
}
#endif
}
~AutoProfilerLabel()
{
// This function runs both on and off the main thread.
#ifdef MOZ_GECKO_PROFILER
if (mPseudoStack) {
mPseudoStack->pop();
}
#endif
}
private:
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
#ifdef MOZ_GECKO_PROFILER
// We save a PseudoStack pointer in the ctor so we don't have to redo the TLS
// lookup in the dtor.
PseudoStack* mPseudoStack;
@ -581,7 +608,6 @@ private:
public:
// See the comment on the definition in platform.cpp for details about this.
static MOZ_THREAD_LOCAL(PseudoStack*) sPseudoStack;
#endif
};
class MOZ_RAII AutoProfilerTracing
@ -621,7 +647,6 @@ protected:
// Set MOZ_PROFILER_STARTUP* environment variables that will be inherited into
// a child process that is about to be launched, in order to make that child
// process start with the same profiler settings as in the current process.
#ifdef MOZ_GECKO_PROFILER
class MOZ_RAII AutoSetProfilerEnvVarsForChildProcess
{
public:
@ -635,12 +660,9 @@ private:
char mSetFeaturesBitfield[64];
char mSetFilters[1024];
};
#else
class AutoSetProfilerEnvVarsForChildProcess
{
};
#endif
} // namespace mozilla
#endif // !MOZ_GECKO_PROFILER
#endif // GeckoProfiler_h

Просмотреть файл

@ -72,17 +72,10 @@ private:
UniqueProfilerBacktrace mStack;
};
#define DECL_STREAM_PAYLOAD_BASE \
#define DECL_STREAM_PAYLOAD \
virtual void StreamPayload(SpliceableJSONWriter& aWriter, \
const mozilla::TimeStamp& aProcessStartTime, \
UniqueStacks& aUniqueStacks) override
// If the profiler is disabled then StreamPayload() will never be called.
#ifdef MOZ_GECKO_PROFILER
# define DECL_STREAM_PAYLOAD DECL_STREAM_PAYLOAD_BASE ;
#else
# define DECL_STREAM_PAYLOAD DECL_STREAM_PAYLOAD_BASE { MOZ_CRASH(); }
#endif
UniqueStacks& aUniqueStacks) override;
class TracingMarkerPayload : public ProfilerMarkerPayload
{

Просмотреть файл

@ -457,20 +457,20 @@ TEST(GeckoProfiler, Markers)
features, filters, MOZ_ARRAY_LENGTH(filters));
profiler_tracing("A", "B", TRACING_EVENT);
profiler_tracing("A", "C", TRACING_INTERVAL_START);
profiler_tracing("A", "C", TRACING_INTERVAL_END);
PROFILER_TRACING("A", "C", TRACING_INTERVAL_START);
PROFILER_TRACING("A", "C", TRACING_INTERVAL_END);
UniqueProfilerBacktrace bt = profiler_get_backtrace();
profiler_tracing("B", "A", TRACING_EVENT, Move(bt));
{
AutoProfilerTracing tracing("C", "A");
AUTO_PROFILER_TRACING("C", "A");
}
profiler_add_marker("M1");
profiler_add_marker("M2",
MakeUnique<TracingMarkerPayload>("C", TRACING_EVENT));
profiler_add_marker("M3");
profiler_add_marker(
"M2", MakeUnique<TracingMarkerPayload>("C", TRACING_EVENT));
PROFILER_ADD_MARKER("M3");
profiler_add_marker(
"M4",
MakeUnique<TracingMarkerPayload>("C", TRACING_EVENT,

Просмотреть файл

@ -13,6 +13,7 @@ namespace mozilla {
bool
ANRReporter::RequestNativeStack(bool aUnwind)
{
#ifdef MOZ_GECKO_PROFILER
if (profiler_is_active()) {
// Don't proceed if profiler is already running
return false;
@ -33,12 +34,14 @@ ANRReporter::RequestNativeStack(bool aUnwind)
profiler_start(/* entries */ 100, /* interval */ 10000, features,
NATIVE_STACK_THREADS,
sizeof(NATIVE_STACK_THREADS) / sizeof(char*));
#endif
return true;
}
jni::String::LocalRef
ANRReporter::GetNativeStack()
{
#ifdef MOZ_GECKO_PROFILER
// Timeout if we don't get a profiler sample after 5 seconds.
const PRIntervalTime timeout = PR_SecondsToInterval(5);
const PRIntervalTime startTime = PR_IntervalNow();
@ -46,8 +49,7 @@ ANRReporter::GetNativeStack()
// Pointer to a profile JSON string
typedef mozilla::UniquePtr<char[]> ProfilePtr;
// profiler_get_profile() will return nullptr if the profiler is disabled
// or inactive.
// profiler_get_profile() will return nullptr if the profiler is inactive.
ProfilePtr profile(profiler_get_profile());
if (!profile) {
return nullptr;
@ -65,17 +67,20 @@ ANRReporter::GetNativeStack()
if (profile) {
return jni::String::Param(profile.get());
}
#endif
return nullptr;
}
void
ANRReporter::ReleaseNativeStack()
{
#ifdef MOZ_GECKO_PROFILER
if (!profiler_is_active()) {
// Maybe profiler support is disabled?
return;
}
profiler_stop();
#endif
}
} // namespace

Просмотреть файл

@ -6746,8 +6746,7 @@ HandleEvent(CGEventTapProxy aProxy, CGEventType aType,
- (void)runEventThread
{
char aLocal;
profiler_register_thread("APZC Event Thread", &aLocal);
PROFILER_REGISTER_THREAD("APZC Event Thread");
NS_SetCurrentThreadName("APZC Event Thread");
mThread = [NSThread currentThread];

Просмотреть файл

@ -46,9 +46,11 @@ static gint
PollWrapper(GPollFD *ufds, guint nfsd, gint timeout_)
{
mozilla::HangMonitor::Suspend();
profiler_thread_sleep();
gint result = (*sPollFunc)(ufds, nfsd, timeout_);
profiler_thread_wake();
gint result;
{
AUTO_PROFILER_THREAD_SLEEP;
result = (*sPollFunc)(ufds, nfsd, timeout_);
}
mozilla::HangMonitor::NotifyActivity();
return result;
}

Просмотреть файл

@ -355,7 +355,7 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait)
// Block and wait for any posted application message
mozilla::HangMonitor::Suspend();
{
AutoProfilerThreadSleep sleep;
AUTO_PROFILER_THREAD_SLEEP;
WinUtils::WaitForMessage();
}
}

Просмотреть файл

@ -85,7 +85,10 @@
#include "nsWrapperCache.h"
#include "nsStringBuffer.h"
#include "GeckoProfiler.h"
#ifdef MOZ_GECKO_PROFILER
#include "ProfilerMarkerPayload.h"
#endif
#ifdef MOZ_CRASHREPORTER
#include "nsExceptionHandler.h"
@ -833,6 +836,7 @@ CycleCollectedJSRuntime::GCSliceCallback(JSContext* aContext,
CycleCollectedJSRuntime* self = CycleCollectedJSRuntime::Get();
MOZ_ASSERT(CycleCollectedJSContext::Get()->Context() == aContext);
#ifdef MOZ_GECKO_PROFILER
if (profiler_is_active()) {
if (aProgress == JS::GC_CYCLE_END) {
profiler_add_marker(
@ -848,6 +852,7 @@ CycleCollectedJSRuntime::GCSliceCallback(JSContext* aContext,
aDesc.sliceToJSON(aContext)));
}
}
#endif
if (aProgress == JS::GC_CYCLE_END &&
JS::dbg::FireOnGarbageCollectionHookRequired(aContext)) {
@ -930,8 +935,10 @@ CycleCollectedJSRuntime::GCNurseryCollectionCallback(JSContext* aContext,
if (aProgress == JS::GCNurseryProgress::GC_NURSERY_COLLECTION_START) {
self->mLatestNurseryCollectionStart = TimeStamp::Now();
} else if ((aProgress == JS::GCNurseryProgress::GC_NURSERY_COLLECTION_END) &&
profiler_is_active())
}
#ifdef MOZ_GECKO_PROFILER
else if (aProgress == JS::GCNurseryProgress::GC_NURSERY_COLLECTION_END &&
profiler_is_active())
{
profiler_add_marker(
"GCMinor",
@ -939,6 +946,7 @@ CycleCollectedJSRuntime::GCNurseryCollectionCallback(JSContext* aContext,
TimeStamp::Now(),
JS::MinorGcToJSON(aContext)));
}
#endif
if (self->mPrevGCNurseryCollectionCallback) {
self->mPrevGCNurseryCollectionCallback(aContext, aProgress, aReason);

Просмотреть файл

@ -18,7 +18,9 @@
#include "nsIObserverService.h"
#include "nsIGlobalObject.h"
#include "nsIXPConnect.h"
#ifdef MOZ_GECKO_PROFILER
#include "GeckoProfilerReporter.h"
#endif
#if defined(XP_UNIX) || defined(MOZ_DMD)
#include "nsMemoryInfoDumper.h"
#endif

Просмотреть файл

@ -29,10 +29,15 @@ namespace {
struct ObservationWithStack
{
ObservationWithStack(mozilla::IOInterposeObserver::Observation& aObs,
ProfilerBacktrace* aStack)
explicit ObservationWithStack(mozilla::IOInterposeObserver::Observation& aObs
#ifdef MOZ_GECKO_PROFILER
, ProfilerBacktrace* aStack
#endif
)
: mObservation(aObs)
#ifdef MOZ_GECKO_PROFILER
, mStack(aStack)
#endif
{
const char16_t* filename = aObs.Filename();
if (filename) {
@ -41,7 +46,9 @@ struct ObservationWithStack
}
mozilla::IOInterposeObserver::Observation mObservation;
#ifdef MOZ_GECKO_PROFILER
ProfilerBacktrace* mStack;
#endif
nsString mFilename;
};
@ -115,7 +122,8 @@ MainThreadIOLoggerImpl::Init()
/* static */ void
MainThreadIOLoggerImpl::sIOThreadFunc(void* aArg)
{
AutoProfilerRegisterThread registerThread("MainThreadIOLogger");
AUTO_PROFILER_REGISTER_THREAD("MainThreadIOLogger");
NS_SetCurrentThreadName("MainThreadIOLogger");
MainThreadIOLoggerImpl* obj = static_cast<MainThreadIOLoggerImpl*>(aArg);
obj->IOThreadFunc();
@ -174,8 +182,10 @@ MainThreadIOLoggerImpl::IOThreadFunc()
(i->mObservation.Start() - mLogStartTime).ToMilliseconds(),
i->mObservation.ObservedOperationString(), durationMs,
i->mObservation.Reference(), nativeFilename.get()) > 0) {
#ifdef MOZ_GECKO_PROFILER
// TODO: Write out the callstack
i->mStack = nullptr;
#endif
}
}
}
@ -195,7 +205,11 @@ MainThreadIOLoggerImpl::Observe(Observation& aObservation)
return;
}
// Passing nullptr as aStack parameter for now
mObservations.push_back(ObservationWithStack(aObservation, nullptr));
mObservations.push_back(ObservationWithStack(aObservation
#ifdef MOZ_GECKO_PROFILER
, nullptr
#endif
));
lock.Notify();
}

Просмотреть файл

@ -984,7 +984,7 @@ ShutdownXPCOM(nsIServiceManager* aServMgr)
#endif
nsCycleCollector_shutdown(shutdownCollect);
profiler_add_marker("Shutdown xpcom");
PROFILER_ADD_MARKER("Shutdown xpcom");
// If we are doing any shutdown checks, poison writes.
if (gShutdownChecks != SCM_NOTHING) {
#ifdef XP_MACOSX
@ -1016,7 +1016,7 @@ ShutdownXPCOM(nsIServiceManager* aServMgr)
// JS pseudo-stack's internal reference to the main thread JSContext,
// duplicating the call in XPCJSContext::~XPCJSContext() in case that
// never fired.
profiler_clear_js_context();
PROFILER_CLEAR_JS_CONTEXT();
if (sInitializedJS) {
// Shut down the JS engine.

Просмотреть файл

@ -506,18 +506,14 @@ ReentrantMonitor::Wait(PRIntervalTime aInterval)
mChainPrev = 0;
nsresult rv;
#if defined(MOZILLA_INTERNAL_API)
{
AutoProfilerThreadSleep sleep;
#endif //MOZILLA_INTERNAL_API
#if defined(MOZILLA_INTERNAL_API)
AUTO_PROFILER_THREAD_SLEEP;
#endif
// give up the monitor until we're back from Wait()
rv = PR_Wait(mReentrantMonitor, aInterval) == PR_SUCCESS ? NS_OK :
NS_ERROR_FAILURE;
#if defined(MOZILLA_INTERNAL_API)
}
#endif //MOZILLA_INTERNAL_API
// restore saved state
mEntryCount = savedEntryCount;

Просмотреть файл

@ -62,7 +62,7 @@ public:
{
#ifdef MOZILLA_INTERNAL_API
AutoProfilerThreadSleep sleep;
AUTO_PROFILER_THREAD_SLEEP;
#endif //MOZILLA_INTERNAL_API
if (aInterval == PR_INTERVAL_NO_TIMEOUT) {
mImpl.wait(*mLock);

Просмотреть файл

@ -196,7 +196,7 @@ GetChromeHangReport(Telemetry::ProcessedStack& aStack,
void
ThreadMain(void*)
{
AutoProfilerRegisterThread registerThread("Hang Monitor");
AUTO_PROFILER_REGISTER_THREAD("Hang Monitor");
NS_SetCurrentThreadName("Hang Monitor");
MonitorAutoLock lock(*gMonitor);

Просмотреть файл

@ -86,7 +86,7 @@ public:
nsresult Wait(PRIntervalTime aInterval = PR_INTERVAL_NO_TIMEOUT)
{
#ifdef MOZILLA_INTERNAL_API
AutoProfilerThreadSleep sleep;
AUTO_PROFILER_THREAD_SLEEP;
#endif //MOZILLA_INTERNAL_API
return PR_Wait(mReentrantMonitor, aInterval) == PR_SUCCESS ?
NS_OK : NS_ERROR_FAILURE;

Просмотреть файл

@ -631,7 +631,7 @@ SchedulerImpl::ThreadController::OnStartThread(size_t aIndex, const nsACString&
// GetCurrentVirtualThread() now returns mMainVirtual.
nsThreadManager::get().CreateCurrentThread(mMainQueue, nsThread::MAIN_THREAD);
profiler_register_thread(aName.BeginReading(), &aStackTop);
PROFILER_REGISTER_THREAD(aName.BeginReading());
mOldMainLoop = MessageLoop::current();
@ -659,7 +659,7 @@ SchedulerImpl::ThreadController::OnStopThread(size_t aIndex)
RefPtr<nsThread> self = static_cast<nsThread*>(NS_GetCurrentThread());
nsThreadManager::get().UnregisterCurrentThread(*self);
profiler_unregister_thread();
PROFILER_UNREGISTER_THREAD();
}
void

Просмотреть файл

@ -238,13 +238,16 @@ assembleCmdLine(char* const* aArgv, wchar_t** aWideCmdLine, UINT aCodePage)
void
nsProcess::Monitor(void* aArg)
{
char stackBaseGuess;
RefPtr<nsProcess> process = dont_AddRef(static_cast<nsProcess*>(aArg));
#ifdef MOZ_GECKO_PROFILER
Maybe<AutoProfilerRegisterThread> registerThread;
if (!process->mBlocking) {
registerThread.emplace("RunProcess");
}
#endif
if (!process->mBlocking) {
NS_SetCurrentThreadName("RunProcess");
profiler_register_thread("RunProcess", &stackBaseGuess);
}
#if defined(PROCESSMODEL_WINAPI)
@ -311,10 +314,6 @@ nsProcess::Monitor(void* aArg)
NS_DispatchToMainThread(NewRunnableMethod(
"nsProcess::ProcessComplete", process, &nsProcess::ProcessComplete));
}
if (!process->mBlocking) {
profiler_unregister_thread();
}
}
void

Просмотреть файл

@ -383,8 +383,6 @@ nsThread::ThreadFunc(void* aArg)
{
using mozilla::ipc::BackgroundChild;
char stackTop;
ThreadInitData* initData = static_cast<ThreadInitData*>(aArg);
nsThread* self = initData->thread; // strong reference
@ -406,7 +404,7 @@ nsThread::ThreadFunc(void* aArg)
// because that call is needed to properly set up this thread as an nsThread,
// which profiler_register_thread() requires. See bug 1347007.
if (!initData->name.IsEmpty()) {
profiler_register_thread(initData->name.BeginReading(), &stackTop);
PROFILER_REGISTER_THREAD(initData->name.BeginReading());
}
// Wait for and process startup event
@ -453,7 +451,7 @@ nsThread::ThreadFunc(void* aArg)
// Inform the threadmanager that this thread is going away
nsThreadManager::get().UnregisterCurrentThread(*self);
profiler_unregister_thread();
PROFILER_UNREGISTER_THREAD();
// Dispatch shutdown ACK
NotNull<nsThreadShutdownContext*> context =