Bug 1500692 - Centralize profiling category definition and add infrastructure for subcategories. r=njn
The actual subcategories will be added in later patches, so that there are no unused categories. Differential Revision: https://phabricator.services.mozilla.com/D11334
This commit is contained in:
@@ -811,8 +811,7 @@ nsresult Accessible::HandleAccEvent(AccEvent* aEvent) {
|
||||
nsAutoCString strMarker;
|
||||
strMarker.AppendLiteral("A11y Event - ");
|
||||
strMarker.Append(strEventType);
|
||||
profiler_add_marker(strMarker.get(),
|
||||
js::ProfilingStackFrame::Category::OTHER);
|
||||
profiler_add_marker(strMarker.get(), JS::ProfilingCategoryPair::OTHER);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ const { L10N } = require("devtools/client/performance/modules/global");
|
||||
|
||||
/**
|
||||
* Details about each label stack frame category.
|
||||
* To be kept in sync with the js::ProfilingStackFrame::Category in ProfilingStack.h
|
||||
* To be kept in sync with the JS::ProfilingCategory enum in ProfilingCategory.h
|
||||
*/
|
||||
const CATEGORIES = [{
|
||||
color: "#d99b28",
|
||||
|
||||
@@ -174,7 +174,7 @@ void TimeoutManager::MoveIdleToActive() {
|
||||
int(delta.ToMilliseconds()));
|
||||
// don't have end before start...
|
||||
profiler_add_marker(
|
||||
"setTimeout deferred release", js::ProfilingStackFrame::Category::DOM,
|
||||
"setTimeout deferred release", JS::ProfilingCategoryPair::DOM,
|
||||
MakeUnique<TextMarkerPayload>(
|
||||
marker, delta.ToMilliseconds() >= 0 ? timeout->When() : now,
|
||||
now));
|
||||
@@ -959,7 +959,7 @@ void TimeoutManager::RunTimeout(const TimeStamp& aNow,
|
||||
int(delta.ToMilliseconds()), int(runtime.ToMilliseconds()));
|
||||
// don't have end before start...
|
||||
profiler_add_marker(
|
||||
"setTimeout", js::ProfilingStackFrame::Category::DOM,
|
||||
"setTimeout", JS::ProfilingCategoryPair::DOM,
|
||||
MakeUnique<TextMarkerPayload>(
|
||||
marker, delta.ToMilliseconds() >= 0 ? timeout->When() : now,
|
||||
now));
|
||||
|
||||
@@ -162,7 +162,7 @@ void nsDOMNavigationTiming::NotifyLoadEventEnd() {
|
||||
DECLARE_DOCSHELL_AND_HISTORY_ID(mDocShell);
|
||||
PAGELOAD_LOG(("%s", marker.get()));
|
||||
profiler_add_marker(
|
||||
"DocumentLoad", js::ProfilingStackFrame::Category::DOM,
|
||||
"DocumentLoad", JS::ProfilingCategoryPair::DOM,
|
||||
MakeUnique<TextMarkerPayload>(marker, mNavigationStart, mLoadEventEnd,
|
||||
docShellId, docShellHistoryId));
|
||||
}
|
||||
@@ -357,7 +357,7 @@ void nsDOMNavigationTiming::TTITimeout(nsITimer* aTimer) {
|
||||
|
||||
DECLARE_DOCSHELL_AND_HISTORY_ID(mDocShell);
|
||||
profiler_add_marker(
|
||||
"TTFI", js::ProfilingStackFrame::Category::DOM,
|
||||
"TTFI", JS::ProfilingCategoryPair::DOM,
|
||||
MakeUnique<TextMarkerPayload>(marker, mNavigationStart, mTTFI,
|
||||
docShellId, docShellHistoryId));
|
||||
}
|
||||
@@ -392,7 +392,7 @@ void nsDOMNavigationTiming::NotifyNonBlankPaintForRootContentDocument() {
|
||||
PAGELOAD_LOG(("%s", marker.get()));
|
||||
DECLARE_DOCSHELL_AND_HISTORY_ID(mDocShell);
|
||||
profiler_add_marker(
|
||||
"FirstNonBlankPaint", js::ProfilingStackFrame::Category::DOM,
|
||||
"FirstNonBlankPaint", JS::ProfilingCategoryPair::DOM,
|
||||
MakeUnique<TextMarkerPayload>(marker, mNavigationStart, mNonBlankPaint,
|
||||
docShellId, docShellHistoryId));
|
||||
}
|
||||
@@ -441,11 +441,10 @@ void nsDOMNavigationTiming::NotifyContentfulPaintForRootContentDocument(
|
||||
"and first non-blank paint");
|
||||
DECLARE_DOCSHELL_AND_HISTORY_ID(mDocShell);
|
||||
PAGELOAD_LOG(("%s", marker.get()));
|
||||
profiler_add_marker(
|
||||
"FirstContentfulPaint", js::ProfilingStackFrame::Category::DOM,
|
||||
MakeUnique<TextMarkerPayload>(marker, mNavigationStart,
|
||||
mContentfulPaint, docShellId,
|
||||
docShellHistoryId));
|
||||
profiler_add_marker("FirstContentfulPaint", JS::ProfilingCategoryPair::DOM,
|
||||
MakeUnique<TextMarkerPayload>(
|
||||
marker, mNavigationStart, mContentfulPaint,
|
||||
docShellId, docShellHistoryId));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -492,11 +491,10 @@ void nsDOMNavigationTiming::NotifyDOMContentFlushedForRootContentDocument() {
|
||||
"and DOMContentFlushed");
|
||||
DECLARE_DOCSHELL_AND_HISTORY_ID(mDocShell);
|
||||
PAGELOAD_LOG(("%s", marker.get()));
|
||||
profiler_add_marker(
|
||||
"DOMContentFlushed", js::ProfilingStackFrame::Category::DOM,
|
||||
MakeUnique<TextMarkerPayload>(marker, mNavigationStart,
|
||||
mDOMContentFlushed, docShellId,
|
||||
docShellHistoryId));
|
||||
profiler_add_marker("DOMContentFlushed", JS::ProfilingCategoryPair::DOM,
|
||||
MakeUnique<TextMarkerPayload>(
|
||||
marker, mNavigationStart, mDOMContentFlushed,
|
||||
docShellId, docShellHistoryId));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ nsJSUtils::ExecutionContext::ExecutionContext(JSContext* aCx,
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
mAutoProfilerLabel("nsJSUtils::ExecutionContext",
|
||||
/* dynamicStr */ nullptr,
|
||||
js::ProfilingStackFrame::Category::JS),
|
||||
JS::ProfilingCategoryPair::JS),
|
||||
#endif
|
||||
mCx(aCx),
|
||||
mRealm(aCx, aGlobal),
|
||||
|
||||
@@ -1025,7 +1025,7 @@ static bool ShouldClearTargets(WidgetEvent* aEvent) {
|
||||
docShell = nsContentUtils::GetDocShellForEventTarget(aEvent->mTarget);
|
||||
DECLARE_DOCSHELL_AND_HISTORY_ID(docShell);
|
||||
profiler_add_marker(
|
||||
"DOMEvent", js::ProfilingStackFrame::Category::DOM,
|
||||
"DOMEvent", JS::ProfilingCategoryPair::DOM,
|
||||
MakeUnique<DOMEventMarkerPayload>(
|
||||
typeStr, aEvent->mTimeStamp, "DOMEvent",
|
||||
TRACING_INTERVAL_START, docShellId, docShellHistoryId));
|
||||
@@ -1034,7 +1034,7 @@ static bool ShouldClearTargets(WidgetEvent* aEvent) {
|
||||
aCallback, cd);
|
||||
|
||||
profiler_add_marker(
|
||||
"DOMEvent", js::ProfilingStackFrame::Category::DOM,
|
||||
"DOMEvent", JS::ProfilingCategoryPair::DOM,
|
||||
MakeUnique<DOMEventMarkerPayload>(
|
||||
typeStr, aEvent->mTimeStamp, "DOMEvent", TRACING_INTERVAL_END,
|
||||
docShellId, docShellHistoryId));
|
||||
|
||||
@@ -225,7 +225,7 @@ void Performance::Mark(const nsAString& aName, ErrorResult& aRv) {
|
||||
nsContentUtils::GetDocShellForEventTarget(et);
|
||||
DECLARE_DOCSHELL_AND_HISTORY_ID(docShell);
|
||||
profiler_add_marker(
|
||||
"UserTiming", js::ProfilingStackFrame::Category::DOM,
|
||||
"UserTiming", JS::ProfilingCategoryPair::DOM,
|
||||
MakeUnique<UserTimingMarkerPayload>(aName, TimeStamp::Now(), docShellId,
|
||||
docShellHistoryId));
|
||||
}
|
||||
@@ -321,7 +321,7 @@ void Performance::Measure(const nsAString& aName,
|
||||
nsCOMPtr<nsIDocShell> docShell =
|
||||
nsContentUtils::GetDocShellForEventTarget(et);
|
||||
DECLARE_DOCSHELL_AND_HISTORY_ID(docShell);
|
||||
profiler_add_marker("UserTiming", js::ProfilingStackFrame::Category::DOM,
|
||||
profiler_add_marker("UserTiming", JS::ProfilingCategoryPair::DOM,
|
||||
MakeUnique<UserTimingMarkerPayload>(
|
||||
aName, startMark, endMark, startTimeStamp,
|
||||
endTimeStamp, docShellId, docShellHistoryId));
|
||||
|
||||
@@ -567,7 +567,7 @@ AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
,
|
||||
mAutoProfilerLabel(
|
||||
"", aReason, js::ProfilingStackFrame::Category::JS,
|
||||
"", aReason, JS::ProfilingCategoryPair::JS,
|
||||
uint32_t(js::ProfilingStackFrame::Flags::RELEVANT_FOR_JS))
|
||||
#endif
|
||||
{
|
||||
|
||||
@@ -164,8 +164,7 @@ void LayerManager::PayloadPresented() {
|
||||
"Payload Presented, type: %d latency: %dms\n",
|
||||
int32_t(payload.mType),
|
||||
int32_t((presented - payload.mTimeStamp).ToMilliseconds()));
|
||||
profiler_add_marker(marker.get(),
|
||||
js::ProfilingStackFrame::Category::GRAPHICS);
|
||||
profiler_add_marker(marker.get(), JS::ProfilingCategoryPair::GRAPHICS);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ void ProfilerScreenshots::SubmitScreenshot(
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Add a marker with the data URL.
|
||||
profiler_add_marker_for_thread(
|
||||
sourceThread, js::ProfilingStackFrame::Category::GRAPHICS,
|
||||
sourceThread, JS::ProfilingCategoryPair::GRAPHICS,
|
||||
"CompositorScreenshot",
|
||||
MakeUnique<ScreenshotPayload>(timeStamp, std::move(dataURL),
|
||||
originalSize, windowIdentifier));
|
||||
|
||||
@@ -88,7 +88,7 @@ void CompositorScreenshotGrabber::MaybeProcessQueue() {
|
||||
void CompositorScreenshotGrabber::NotifyEmptyFrame() {
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
profiler_add_marker("NoCompositorScreenshot because nothing changed",
|
||||
js::ProfilingStackFrame::Category::GRAPHICS);
|
||||
JS::ProfilingCategoryPair::GRAPHICS);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -100,8 +100,7 @@ static void PrintUniformityInfo(Layer* aLayer) {
|
||||
}
|
||||
|
||||
Point translation = transform.As2D().GetTranslation();
|
||||
profiler_add_marker("LayerTranslation",
|
||||
js::ProfilingStackFrame::Category::GRAPHICS,
|
||||
profiler_add_marker("LayerTranslation", JS::ProfilingCategoryPair::GRAPHICS,
|
||||
MakeUnique<LayerTranslationMarkerPayload>(
|
||||
aLayer, translation, TimeStamp::Now()));
|
||||
#endif
|
||||
|
||||
@@ -1908,8 +1908,7 @@ CompositorBridgeParent::GetAPZCTreeManager(LayersId aLayersId) {
|
||||
static void InsertVsyncProfilerMarker(TimeStamp aVsyncTimestamp) {
|
||||
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
|
||||
if (profiler_thread_is_being_profiled()) {
|
||||
profiler_add_marker("VsyncTimestamp",
|
||||
js::ProfilingStackFrame::Category::GRAPHICS,
|
||||
profiler_add_marker("VsyncTimestamp", JS::ProfilingCategoryPair::GRAPHICS,
|
||||
MakeUnique<VsyncMarkerPayload>(aVsyncTimestamp));
|
||||
}
|
||||
}
|
||||
@@ -2452,8 +2451,8 @@ int32_t RecordContentFrameTime(
|
||||
}
|
||||
};
|
||||
profiler_add_marker_for_thread(
|
||||
profiler_current_thread_id(),
|
||||
js::ProfilingStackFrame::Category::GRAPHICS, "CONTENT_FRAME_TIME",
|
||||
profiler_current_thread_id(), JS::ProfilingCategoryPair::GRAPHICS,
|
||||
"CONTENT_FRAME_TIME",
|
||||
MakeUnique<ContentFramePayload>(aTxnStart, aCompositeEnd));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -380,8 +380,8 @@ void CrossProcessCompositorBridgeParent::ShadowLayersUpdated(
|
||||
}
|
||||
};
|
||||
profiler_add_marker_for_thread(
|
||||
profiler_current_thread_id(),
|
||||
js::ProfilingStackFrame::Category::GRAPHICS, "CONTENT_FULL_PAINT_TIME",
|
||||
profiler_current_thread_id(), JS::ProfilingCategoryPair::GRAPHICS,
|
||||
"CONTENT_FULL_PAINT_TIME",
|
||||
MakeUnique<ContentBuildPayload>(aInfo.transactionStart(), endTime));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -104,7 +104,7 @@ void MLGPUScreenshotGrabber::MaybeProcessQueue() {
|
||||
void MLGPUScreenshotGrabber::NotifyEmptyFrame() {
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
profiler_add_marker("NoCompositorScreenshot because nothing changed",
|
||||
js::ProfilingStackFrame::Category::GRAPHICS);
|
||||
JS::ProfilingCategoryPair::GRAPHICS);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -52,16 +52,14 @@ bool is_in_render_thread() {
|
||||
|
||||
void gecko_profiler_start_marker(const char* name) {
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
profiler_tracing("WebRender", name,
|
||||
js::ProfilingStackFrame::Category::GRAPHICS,
|
||||
profiler_tracing("WebRender", name, JS::ProfilingCategoryPair::GRAPHICS,
|
||||
TRACING_INTERVAL_START);
|
||||
#endif
|
||||
}
|
||||
|
||||
void gecko_profiler_end_marker(const char* name) {
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
profiler_tracing("WebRender", name,
|
||||
js::ProfilingStackFrame::Category::GRAPHICS,
|
||||
profiler_tracing("WebRender", name, JS::ProfilingCategoryPair::GRAPHICS,
|
||||
TRACING_INTERVAL_END);
|
||||
#endif
|
||||
}
|
||||
@@ -206,8 +204,7 @@ class SceneBuiltNotification : public wr::NotificationHandler {
|
||||
|
||||
profiler_add_marker_for_thread(
|
||||
profiler_current_thread_id(),
|
||||
js::ProfilingStackFrame::Category::GRAPHICS,
|
||||
"CONTENT_FULL_PAINT_TIME",
|
||||
JS::ProfilingCategoryPair::GRAPHICS, "CONTENT_FULL_PAINT_TIME",
|
||||
MakeUnique<ContentFullPaintPayload>(startTime, endTime));
|
||||
}
|
||||
#endif
|
||||
|
||||
107
js/public/ProfilingCategory.h
Normal file
107
js/public/ProfilingCategory.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
* 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 js_ProfilingCategory_h
|
||||
#define js_ProfilingCategory_h
|
||||
|
||||
#include "jstypes.h" // JS_FRIEND_API
|
||||
|
||||
// clang-format off
|
||||
|
||||
// This higher-order macro lists all categories with their subcategories.
|
||||
//
|
||||
// PROFILING_CATEGORY_LIST(BEGIN_CATEGORY, SUBCATEGORY, END_CATEGORY)
|
||||
// BEGIN_CATEGORY(name, labelAsString, colorAsString)
|
||||
// SUBCATEGORY(category, name, labelAsString)
|
||||
// END_CATEGORY
|
||||
//
|
||||
// The list of available color names for categories is:
|
||||
// transparent, grey, purple, yellow, orange, lightblue, green, blue, magenta
|
||||
//
|
||||
// Categories and subcategories are used for stack-based instrumentation. They
|
||||
// are specified in label frames in the profiling stack, see ProfilingStack.h.
|
||||
// At any point, the category pair of the topmost profiler label frame in the
|
||||
// label stack determines the category pair of that stack.
|
||||
// Each category describes a type of workload that the CPU can be busy with.
|
||||
// Categories should be non-overlapping: the list of categories should be
|
||||
// chosen in such a way that every possible stack can be mapped to a single
|
||||
// category unambiguously.
|
||||
|
||||
#define PROFILING_CATEGORY_LIST(BEGIN_CATEGORY, SUBCATEGORY, END_CATEGORY) \
|
||||
BEGIN_CATEGORY(IDLE, "Idle", "transparent") \
|
||||
SUBCATEGORY(IDLE, IDLE, "Other") \
|
||||
END_CATEGORY \
|
||||
BEGIN_CATEGORY(OTHER, "Other", "grey") \
|
||||
SUBCATEGORY(OTHER, OTHER, "Other") \
|
||||
END_CATEGORY \
|
||||
BEGIN_CATEGORY(LAYOUT, "Layout", "purple") \
|
||||
SUBCATEGORY(LAYOUT, LAYOUT, "Other") \
|
||||
END_CATEGORY \
|
||||
BEGIN_CATEGORY(JS, "JavaScript", "yellow") \
|
||||
SUBCATEGORY(JS, JS, "Other") \
|
||||
END_CATEGORY \
|
||||
BEGIN_CATEGORY(GCCC, "GC / CC", "orange") \
|
||||
SUBCATEGORY(GCCC, GCCC, "Other") \
|
||||
END_CATEGORY \
|
||||
BEGIN_CATEGORY(NETWORK, "Network", "lightblue") \
|
||||
SUBCATEGORY(NETWORK, NETWORK, "Other") \
|
||||
END_CATEGORY \
|
||||
BEGIN_CATEGORY(GRAPHICS, "Graphics", "green") \
|
||||
SUBCATEGORY(GRAPHICS, GRAPHICS, "Other") \
|
||||
END_CATEGORY \
|
||||
BEGIN_CATEGORY(DOM, "DOM", "blue") \
|
||||
SUBCATEGORY(DOM, DOM, "Other") \
|
||||
END_CATEGORY
|
||||
|
||||
namespace JS {
|
||||
|
||||
// An enum that lists all possible category pairs in one list.
|
||||
// This is the enum that is used in profiler stack labels. Having one list that
|
||||
// includes subcategories from all categories in one list allows assigning the
|
||||
// category pair to a stack label with just one number.
|
||||
#define CATEGORY_ENUM_BEGIN_CATEGORY(name, labelAsString, color)
|
||||
#define CATEGORY_ENUM_SUBCATEGORY(supercategory, name, labelAsString) name,
|
||||
#define CATEGORY_ENUM_END_CATEGORY
|
||||
enum class ProfilingCategoryPair : uint32_t {
|
||||
PROFILING_CATEGORY_LIST(CATEGORY_ENUM_BEGIN_CATEGORY,
|
||||
CATEGORY_ENUM_SUBCATEGORY,
|
||||
CATEGORY_ENUM_END_CATEGORY)
|
||||
COUNT,
|
||||
LAST = COUNT - 1,
|
||||
};
|
||||
#undef CATEGORY_ENUM_BEGIN_CATEGORY
|
||||
#undef CATEGORY_ENUM_SUBCATEGORY
|
||||
#undef CATEGORY_ENUM_END_CATEGORY
|
||||
|
||||
// An enum that lists just the categories without their subcategories.
|
||||
#define SUPERCATEGORY_ENUM_BEGIN_CATEGORY(name, labelAsString, color) name,
|
||||
#define SUPERCATEGORY_ENUM_SUBCATEGORY(supercategory, name, labelAsString)
|
||||
#define SUPERCATEGORY_ENUM_END_CATEGORY
|
||||
enum class ProfilingCategory : uint32_t {
|
||||
PROFILING_CATEGORY_LIST(SUPERCATEGORY_ENUM_BEGIN_CATEGORY,
|
||||
SUPERCATEGORY_ENUM_SUBCATEGORY,
|
||||
SUPERCATEGORY_ENUM_END_CATEGORY)
|
||||
COUNT,
|
||||
LAST = COUNT - 1,
|
||||
};
|
||||
#undef SUPERCATEGORY_ENUM_BEGIN_CATEGORY
|
||||
#undef SUPERCATEGORY_ENUM_SUBCATEGORY
|
||||
#undef SUPERCATEGORY_ENUM_END_CATEGORY
|
||||
|
||||
// clang-format on
|
||||
|
||||
struct ProfilingCategoryPairInfo {
|
||||
ProfilingCategory mCategory;
|
||||
uint32_t mSubcategoryIndex;
|
||||
const char* mLabel;
|
||||
};
|
||||
|
||||
JS_FRIEND_API const ProfilingCategoryPairInfo& GetProfilingCategoryPairInfo(
|
||||
ProfilingCategoryPair aCategoryPair);
|
||||
|
||||
} // namespace JS
|
||||
|
||||
#endif /* js_ProfilingCategory_h */
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "jstypes.h"
|
||||
|
||||
#include "js/ProfilingCategory.h"
|
||||
#include "js/TypeDecls.h"
|
||||
#include "js/Utility.h"
|
||||
|
||||
@@ -156,10 +157,10 @@ class ProfilingStackFrame {
|
||||
mozilla::recordreplay::Behavior::DontPreserve>
|
||||
pcOffsetIfJS_;
|
||||
|
||||
// Bits 0...7 hold the Flags. Bits 8...31 hold the category.
|
||||
// Bits 0...7 hold the Flags. Bits 8...31 hold the category pair.
|
||||
mozilla::Atomic<uint32_t, mozilla::ReleaseAcquire,
|
||||
mozilla::recordreplay::Behavior::DontPreserve>
|
||||
flagsAndCategory_;
|
||||
flagsAndCategoryPair_;
|
||||
|
||||
static int32_t pcToOffset(JSScript* aScript, jsbytecode* aPc);
|
||||
|
||||
@@ -172,13 +173,13 @@ class ProfilingStackFrame {
|
||||
spOrScript = spScript;
|
||||
int32_t offsetIfJS = other.pcOffsetIfJS_;
|
||||
pcOffsetIfJS_ = offsetIfJS;
|
||||
uint32_t flagsAndCategory = other.flagsAndCategory_;
|
||||
flagsAndCategory_ = flagsAndCategory;
|
||||
uint32_t flagsAndCategory = other.flagsAndCategoryPair_;
|
||||
flagsAndCategoryPair_ = flagsAndCategory;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// 8 bits for the flags.
|
||||
// That leaves 32 - 8 = 25 bits for the category.
|
||||
// That leaves 32 - 8 = 25 bits for the category pair.
|
||||
enum class Flags : uint32_t {
|
||||
// The first three flags describe the kind of the frame and are
|
||||
// mutually exclusive. (We still give them individual bits for
|
||||
@@ -220,48 +221,36 @@ class ProfilingStackFrame {
|
||||
FLAGS_MASK = (1 << FLAGS_BITCOUNT) - 1
|
||||
};
|
||||
|
||||
// Keep these in sync with devtools/client/performance/modules/categories.js
|
||||
enum class Category : uint32_t {
|
||||
IDLE,
|
||||
OTHER,
|
||||
LAYOUT,
|
||||
JS,
|
||||
GCCC,
|
||||
NETWORK,
|
||||
GRAPHICS,
|
||||
DOM,
|
||||
|
||||
FIRST = OTHER,
|
||||
LAST = DOM,
|
||||
};
|
||||
|
||||
static_assert(uint32_t(Category::LAST) <=
|
||||
static_assert(
|
||||
uint32_t(JS::ProfilingCategoryPair::LAST) <=
|
||||
(UINT32_MAX >> uint32_t(Flags::FLAGS_BITCOUNT)),
|
||||
"Too many categories to fit into u32 with together with the "
|
||||
"Too many category pairs to fit into u32 with together with the "
|
||||
"reserved bits for the flags");
|
||||
|
||||
bool isLabelFrame() const {
|
||||
return uint32_t(flagsAndCategory_) & uint32_t(Flags::IS_LABEL_FRAME);
|
||||
return uint32_t(flagsAndCategoryPair_) & uint32_t(Flags::IS_LABEL_FRAME);
|
||||
}
|
||||
|
||||
bool isSpMarkerFrame() const {
|
||||
return uint32_t(flagsAndCategory_) & uint32_t(Flags::IS_SP_MARKER_FRAME);
|
||||
return uint32_t(flagsAndCategoryPair_) &
|
||||
uint32_t(Flags::IS_SP_MARKER_FRAME);
|
||||
}
|
||||
|
||||
bool isJsFrame() const {
|
||||
return uint32_t(flagsAndCategory_) & uint32_t(Flags::IS_JS_FRAME);
|
||||
return uint32_t(flagsAndCategoryPair_) & uint32_t(Flags::IS_JS_FRAME);
|
||||
}
|
||||
|
||||
bool isOSRFrame() const {
|
||||
return uint32_t(flagsAndCategory_) & uint32_t(Flags::JS_OSR);
|
||||
return uint32_t(flagsAndCategoryPair_) & uint32_t(Flags::JS_OSR);
|
||||
}
|
||||
|
||||
void setIsOSRFrame(bool isOSR) {
|
||||
if (isOSR) {
|
||||
flagsAndCategory_ = uint32_t(flagsAndCategory_) | uint32_t(Flags::JS_OSR);
|
||||
flagsAndCategoryPair_ =
|
||||
uint32_t(flagsAndCategoryPair_) | uint32_t(Flags::JS_OSR);
|
||||
} else {
|
||||
flagsAndCategory_ =
|
||||
uint32_t(flagsAndCategory_) & ~uint32_t(Flags::JS_OSR);
|
||||
flagsAndCategoryPair_ =
|
||||
uint32_t(flagsAndCategoryPair_) & ~uint32_t(Flags::JS_OSR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,14 +260,15 @@ class ProfilingStackFrame {
|
||||
const char* dynamicString() const { return dynamicString_; }
|
||||
|
||||
void initLabelFrame(const char* aLabel, const char* aDynamicString, void* sp,
|
||||
Category aCategory, uint32_t aFlags) {
|
||||
JS::ProfilingCategoryPair aCategoryPair,
|
||||
uint32_t aFlags) {
|
||||
label_ = aLabel;
|
||||
dynamicString_ = aDynamicString;
|
||||
spOrScript = sp;
|
||||
// pcOffsetIfJS_ is not set and must not be used on label frames.
|
||||
flagsAndCategory_ =
|
||||
flagsAndCategoryPair_ =
|
||||
uint32_t(Flags::IS_LABEL_FRAME) |
|
||||
(uint32_t(aCategory) << uint32_t(Flags::FLAGS_BITCOUNT)) | aFlags;
|
||||
(uint32_t(aCategoryPair) << uint32_t(Flags::FLAGS_BITCOUNT)) | aFlags;
|
||||
MOZ_ASSERT(isLabelFrame());
|
||||
}
|
||||
|
||||
@@ -287,9 +277,9 @@ class ProfilingStackFrame {
|
||||
dynamicString_ = nullptr;
|
||||
spOrScript = sp;
|
||||
// pcOffsetIfJS_ is not set and must not be used on sp marker frames.
|
||||
flagsAndCategory_ =
|
||||
uint32_t(Flags::IS_SP_MARKER_FRAME) |
|
||||
(uint32_t(Category::OTHER) << uint32_t(Flags::FLAGS_BITCOUNT));
|
||||
flagsAndCategoryPair_ = uint32_t(Flags::IS_SP_MARKER_FRAME) |
|
||||
(uint32_t(JS::ProfilingCategoryPair::OTHER)
|
||||
<< uint32_t(Flags::FLAGS_BITCOUNT));
|
||||
MOZ_ASSERT(isSpMarkerFrame());
|
||||
}
|
||||
|
||||
@@ -299,18 +289,19 @@ class ProfilingStackFrame {
|
||||
dynamicString_ = aDynamicString;
|
||||
spOrScript = aScript;
|
||||
pcOffsetIfJS_ = pcToOffset(aScript, aPc);
|
||||
flagsAndCategory_ =
|
||||
uint32_t(Flags::IS_JS_FRAME) |
|
||||
(uint32_t(Category::JS) << uint32_t(Flags::FLAGS_BITCOUNT));
|
||||
flagsAndCategoryPair_ =
|
||||
uint32_t(Flags::IS_JS_FRAME) | (uint32_t(JS::ProfilingCategoryPair::JS)
|
||||
<< uint32_t(Flags::FLAGS_BITCOUNT));
|
||||
MOZ_ASSERT(isJsFrame());
|
||||
}
|
||||
|
||||
uint32_t flags() const {
|
||||
return uint32_t(flagsAndCategory_) & uint32_t(Flags::FLAGS_MASK);
|
||||
return uint32_t(flagsAndCategoryPair_) & uint32_t(Flags::FLAGS_MASK);
|
||||
}
|
||||
|
||||
Category category() const {
|
||||
return Category(flagsAndCategory_ >> uint32_t(Flags::FLAGS_BITCOUNT));
|
||||
JS::ProfilingCategoryPair categoryPair() const {
|
||||
return JS::ProfilingCategoryPair(flagsAndCategoryPair_ >>
|
||||
uint32_t(Flags::FLAGS_BITCOUNT));
|
||||
}
|
||||
|
||||
void* stackAddress() const {
|
||||
@@ -390,7 +381,7 @@ class ProfilingStack final {
|
||||
~ProfilingStack();
|
||||
|
||||
void pushLabelFrame(const char* label, const char* dynamicString, void* sp,
|
||||
js::ProfilingStackFrame::Category category,
|
||||
JS::ProfilingCategoryPair categoryPair,
|
||||
uint32_t flags = 0) {
|
||||
// This thread is the only one that ever changes the value of
|
||||
// stackPointer.
|
||||
@@ -402,8 +393,8 @@ class ProfilingStack final {
|
||||
if (MOZ_UNLIKELY(stackPointerVal >= capacity)) {
|
||||
ensureCapacitySlow();
|
||||
}
|
||||
frames[stackPointerVal].initLabelFrame(label, dynamicString, sp, category,
|
||||
flags);
|
||||
frames[stackPointerVal].initLabelFrame(label, dynamicString, sp,
|
||||
categoryPair, flags);
|
||||
|
||||
// This must happen at the end! The compiler will not reorder this
|
||||
// update because stackPointer is Atomic<..., ReleaseAcquire>, so any
|
||||
|
||||
@@ -1382,7 +1382,7 @@ bool js::array_join(JSContext* cx, unsigned argc, Value* vp) {
|
||||
}
|
||||
|
||||
AutoGeckoProfilerEntry pseudoFrame(
|
||||
cx, "Array.prototype.join", ProfilingStackFrame::Category::JS,
|
||||
cx, "Array.prototype.join", JS::ProfilingCategoryPair::JS,
|
||||
uint32_t(ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
@@ -1657,7 +1657,7 @@ static DenseElementResult ArrayReverseDenseKernel(JSContext* cx,
|
||||
// 22.1.3.21 Array.prototype.reverse ( )
|
||||
bool js::array_reverse(JSContext* cx, unsigned argc, Value* vp) {
|
||||
AutoGeckoProfilerEntry pseudoFrame(
|
||||
cx, "Array.prototype.reverse", ProfilingStackFrame::Category::JS,
|
||||
cx, "Array.prototype.reverse", JS::ProfilingCategoryPair::JS,
|
||||
uint32_t(ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
@@ -2381,7 +2381,7 @@ bool js::NewbornArrayPush(JSContext* cx, HandleObject obj, const Value& v) {
|
||||
// 22.1.3.18 Array.prototype.push ( ...items )
|
||||
bool js::array_push(JSContext* cx, unsigned argc, Value* vp) {
|
||||
AutoGeckoProfilerEntry pseudoFrame(
|
||||
cx, "Array.prototype.push", ProfilingStackFrame::Category::JS,
|
||||
cx, "Array.prototype.push", JS::ProfilingCategoryPair::JS,
|
||||
uint32_t(ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
@@ -2442,7 +2442,7 @@ bool js::array_push(JSContext* cx, unsigned argc, Value* vp) {
|
||||
// 22.1.3.17 Array.prototype.pop ( )
|
||||
bool js::array_pop(JSContext* cx, unsigned argc, Value* vp) {
|
||||
AutoGeckoProfilerEntry pseudoFrame(
|
||||
cx, "Array.prototype.pop", ProfilingStackFrame::Category::JS,
|
||||
cx, "Array.prototype.pop", JS::ProfilingCategoryPair::JS,
|
||||
uint32_t(ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
@@ -2562,7 +2562,7 @@ static DenseElementResult ArrayShiftDenseKernel(JSContext* cx, HandleObject obj,
|
||||
// 22.1.3.22 Array.prototype.shift ( )
|
||||
bool js::array_shift(JSContext* cx, unsigned argc, Value* vp) {
|
||||
AutoGeckoProfilerEntry pseudoFrame(
|
||||
cx, "Array.prototype.shift", ProfilingStackFrame::Category::JS,
|
||||
cx, "Array.prototype.shift", JS::ProfilingCategoryPair::JS,
|
||||
uint32_t(ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
@@ -2648,7 +2648,7 @@ bool js::array_shift(JSContext* cx, unsigned argc, Value* vp) {
|
||||
// 22.1.3.29 Array.prototype.unshift ( ...items )
|
||||
bool js::array_unshift(JSContext* cx, unsigned argc, Value* vp) {
|
||||
AutoGeckoProfilerEntry pseudoFrame(
|
||||
cx, "Array.prototype.unshift", ProfilingStackFrame::Category::JS,
|
||||
cx, "Array.prototype.unshift", JS::ProfilingCategoryPair::JS,
|
||||
uint32_t(ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
@@ -2908,7 +2908,7 @@ static bool CopyArrayElements(JSContext* cx, HandleObject obj, uint64_t begin,
|
||||
static bool array_splice_impl(JSContext* cx, unsigned argc, Value* vp,
|
||||
bool returnValueIsUsed) {
|
||||
AutoGeckoProfilerEntry pseudoFrame(
|
||||
cx, "Array.prototype.splice", ProfilingStackFrame::Category::JS,
|
||||
cx, "Array.prototype.splice", JS::ProfilingCategoryPair::JS,
|
||||
uint32_t(ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
@@ -3504,7 +3504,7 @@ static bool ArraySliceOrdinary(JSContext* cx, HandleObject obj, uint64_t begin,
|
||||
/* ES 2016 draft Mar 25, 2016 22.1.3.23. */
|
||||
bool js::array_slice(JSContext* cx, unsigned argc, Value* vp) {
|
||||
AutoGeckoProfilerEntry pseudoFrame(
|
||||
cx, "Array.prototype.slice", ProfilingStackFrame::Category::JS,
|
||||
cx, "Array.prototype.slice", JS::ProfilingCategoryPair::JS,
|
||||
uint32_t(ProfilingStackFrame::Flags::RELEVANT_FOR_JS));
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
|
||||
@@ -6712,7 +6712,7 @@ AutoHeapSession::AutoHeapSession(JSRuntime* rt, JS::HeapState heapState)
|
||||
prevState(rt->heapState_),
|
||||
profilingStackFrame(rt->mainContextFromOwnThread(),
|
||||
HeapStateToLabel(heapState),
|
||||
ProfilingStackFrame::Category::GCCC) {
|
||||
JS::ProfilingCategoryPair::GCCC) {
|
||||
MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt));
|
||||
MOZ_ASSERT(prevState == JS::HeapState::Idle);
|
||||
MOZ_ASSERT(heapState != JS::HeapState::Idle);
|
||||
|
||||
@@ -3590,9 +3590,9 @@ static bool UnmarkGrayGCThing(JSRuntime* rt, JS::GCCellPtr thing) {
|
||||
// replay, so disallow recorded events from occurring in the tracer.
|
||||
mozilla::recordreplay::AutoDisallowThreadEvents d;
|
||||
|
||||
AutoGeckoProfilerEntry profilingStackFrame(
|
||||
rt->mainContextFromOwnThread(), "UnmarkGrayGCThing",
|
||||
ProfilingStackFrame::Category::GCCC);
|
||||
AutoGeckoProfilerEntry profilingStackFrame(rt->mainContextFromOwnThread(),
|
||||
"UnmarkGrayGCThing",
|
||||
JS::ProfilingCategoryPair::GCCC);
|
||||
|
||||
UnmarkGrayTracer unmarker(rt);
|
||||
gcstats::AutoPhase innerPhase(rt->gc.stats(),
|
||||
|
||||
@@ -147,6 +147,7 @@ EXPORTS.js += [
|
||||
'../public/OffThreadScriptCompilation.h',
|
||||
'../public/Principals.h',
|
||||
'../public/Printf.h',
|
||||
'../public/ProfilingCategory.h',
|
||||
'../public/ProfilingFrameIterator.h',
|
||||
'../public/ProfilingStack.h',
|
||||
'../public/Promise.h',
|
||||
|
||||
@@ -79,7 +79,7 @@ GeckoProfilerEntryMarker::~GeckoProfilerEntryMarker() {
|
||||
|
||||
MOZ_ALWAYS_INLINE
|
||||
AutoGeckoProfilerEntry::AutoGeckoProfilerEntry(
|
||||
JSContext* cx, const char* label, ProfilingStackFrame::Category category,
|
||||
JSContext* cx, const char* label, JS::ProfilingCategoryPair categoryPair,
|
||||
uint32_t flags MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
: profiler_(&cx->geckoProfiler()) {
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
@@ -92,7 +92,8 @@ AutoGeckoProfilerEntry::AutoGeckoProfilerEntry(
|
||||
#endif
|
||||
profiler_->profilingStack_->pushLabelFrame(label,
|
||||
/* dynamicString = */ nullptr,
|
||||
/* sp = */ this, category, flags);
|
||||
/* sp = */ this, categoryPair,
|
||||
flags);
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "vm/GeckoProfiler-inl.h"
|
||||
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
|
||||
#include "jsnum.h"
|
||||
@@ -476,3 +477,60 @@ AutoSuppressProfilerSampling::~AutoSuppressProfilerSampling() {
|
||||
cx_->enableProfilerSampling();
|
||||
}
|
||||
}
|
||||
|
||||
namespace JS {
|
||||
|
||||
// clang-format off
|
||||
|
||||
// ProfilingSubcategory_X:
|
||||
// One enum for each category X, listing that category's subcategories. This
|
||||
// allows the sProfilingCategoryInfo macro construction below to look up a
|
||||
// per-category index for a subcategory.
|
||||
#define SUBCATEGORY_ENUMS_BEGIN_CATEGORY(name, labelAsString, color) \
|
||||
enum class ProfilingSubcategory_##name : uint32_t {
|
||||
#define SUBCATEGORY_ENUMS_SUBCATEGORY(category, name, labelAsString) \
|
||||
name,
|
||||
#define SUBCATEGORY_ENUMS_END_CATEGORY \
|
||||
};
|
||||
PROFILING_CATEGORY_LIST(SUBCATEGORY_ENUMS_BEGIN_CATEGORY,
|
||||
SUBCATEGORY_ENUMS_SUBCATEGORY,
|
||||
SUBCATEGORY_ENUMS_END_CATEGORY)
|
||||
#undef SUBCATEGORY_ENUMS_BEGIN_CATEGORY
|
||||
#undef SUBCATEGORY_ENUMS_SUBCATEGORY
|
||||
#undef SUBCATEGORY_ENUMS_END_CATEGORY
|
||||
|
||||
// sProfilingCategoryPairInfo:
|
||||
// A list of ProfilingCategoryPairInfos with the same order as
|
||||
// ProfilingCategoryPair, which can be used to map a ProfilingCategoryPair to
|
||||
// its information.
|
||||
#define CATEGORY_INFO_BEGIN_CATEGORY(name, labelAsString, color)
|
||||
#define CATEGORY_INFO_SUBCATEGORY(category, name, labelAsString) \
|
||||
{ProfilingCategory::category, \
|
||||
uint32_t(ProfilingSubcategory_##category::name), labelAsString},
|
||||
#define CATEGORY_INFO_END_CATEGORY
|
||||
const ProfilingCategoryPairInfo sProfilingCategoryPairInfo[] = {
|
||||
PROFILING_CATEGORY_LIST(CATEGORY_INFO_BEGIN_CATEGORY,
|
||||
CATEGORY_INFO_SUBCATEGORY,
|
||||
CATEGORY_INFO_END_CATEGORY)
|
||||
};
|
||||
#undef CATEGORY_INFO_BEGIN_CATEGORY
|
||||
#undef CATEGORY_INFO_SUBCATEGORY
|
||||
#undef CATEGORY_INFO_END_CATEGORY
|
||||
|
||||
// clang-format on
|
||||
|
||||
JS_FRIEND_API const ProfilingCategoryPairInfo& GetProfilingCategoryPairInfo(
|
||||
ProfilingCategoryPair aCategoryPair) {
|
||||
static_assert(
|
||||
MOZ_ARRAY_LENGTH(sProfilingCategoryPairInfo) ==
|
||||
uint32_t(ProfilingCategoryPair::COUNT),
|
||||
"sProfilingCategoryPairInfo and ProfilingCategory need to have the "
|
||||
"same order and the same length");
|
||||
|
||||
uint32_t categoryPairIndex = uint32_t(aCategoryPair);
|
||||
MOZ_RELEASE_ASSERT(categoryPairIndex <=
|
||||
uint32_t(ProfilingCategoryPair::LAST));
|
||||
return sProfilingCategoryPairInfo[categoryPairIndex];
|
||||
}
|
||||
|
||||
} // namespace JS
|
||||
|
||||
@@ -177,8 +177,7 @@ class MOZ_NONHEAP_CLASS AutoGeckoProfilerEntry {
|
||||
public:
|
||||
explicit MOZ_ALWAYS_INLINE AutoGeckoProfilerEntry(
|
||||
JSContext* cx, const char* label,
|
||||
ProfilingStackFrame::Category category =
|
||||
ProfilingStackFrame::Category::JS,
|
||||
JS::ProfilingCategoryPair categoryPair = JS::ProfilingCategoryPair::JS,
|
||||
uint32_t flags = 0 MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
|
||||
MOZ_ALWAYS_INLINE ~AutoGeckoProfilerEntry();
|
||||
|
||||
|
||||
@@ -57,9 +57,9 @@ GlobalHelperThreadState* gHelperThreadState = nullptr;
|
||||
#define PROFILER_RAII_PASTE(id, line) id##line
|
||||
#define PROFILER_RAII_EXPAND(id, line) PROFILER_RAII_PASTE(id, line)
|
||||
#define PROFILER_RAII PROFILER_RAII_EXPAND(raiiObject, __LINE__)
|
||||
#define AUTO_PROFILER_LABEL(label, category) \
|
||||
#define AUTO_PROFILER_LABEL(label, categoryPair) \
|
||||
HelperThread::AutoProfilerLabel PROFILER_RAII( \
|
||||
this, label, js::ProfilingStackFrame::Category::category)
|
||||
this, label, JS::ProfilingCategoryPair::categoryPair)
|
||||
|
||||
bool js::CreateHelperThreadsState() {
|
||||
MOZ_ASSERT(!gHelperThreadState);
|
||||
@@ -2410,10 +2410,10 @@ const HelperThread::TaskSpec HelperThread::taskSpecs[] = {
|
||||
|
||||
HelperThread::AutoProfilerLabel::AutoProfilerLabel(
|
||||
HelperThread* helperThread, const char* label,
|
||||
ProfilingStackFrame::Category category)
|
||||
JS::ProfilingCategoryPair categoryPair)
|
||||
: profilingStack(helperThread->profilingStack) {
|
||||
if (profilingStack) {
|
||||
profilingStack->pushLabelFrame(label, nullptr, this, category);
|
||||
profilingStack->pushLabelFrame(label, nullptr, this, categoryPair);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -426,7 +426,7 @@ struct HelperThread {
|
||||
private:
|
||||
struct AutoProfilerLabel {
|
||||
AutoProfilerLabel(HelperThread* helperThread, const char* label,
|
||||
ProfilingStackFrame::Category category);
|
||||
JS::ProfilingCategoryPair categoryPair);
|
||||
~AutoProfilerLabel();
|
||||
|
||||
private:
|
||||
|
||||
@@ -39,7 +39,7 @@ class MOZ_RAII AutoProfilerStyleMarker {
|
||||
return;
|
||||
}
|
||||
ServoTraversalStatistics::sActive = false;
|
||||
profiler_add_marker("Styles", js::ProfilingStackFrame::Category::LAYOUT,
|
||||
profiler_add_marker("Styles", JS::ProfilingCategoryPair::LAYOUT,
|
||||
MakeUnique<StyleMarkerPayload>(
|
||||
mStartTime, TimeStamp::Now(), std::move(mCause),
|
||||
ServoTraversalStatistics::sSingleton, mDocShellId,
|
||||
|
||||
@@ -8881,7 +8881,7 @@ bool nsIPresShell::DoReflow(nsIFrame* target, bool aInterruptible,
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
DECLARE_DOCSHELL_AND_HISTORY_ID(docShell);
|
||||
AutoProfilerTracing tracingLayoutFlush(
|
||||
"Paint", "Reflow", js::ProfilingStackFrame::Category::LAYOUT,
|
||||
"Paint", "Reflow", JS::ProfilingCategoryPair::LAYOUT,
|
||||
std::move(mReflowCause), docShellId, docShellHistoryId);
|
||||
mReflowCause = nullptr;
|
||||
#endif
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
//
|
||||
// Note that this class is slightly slower than the other AutoProfilerLabel,
|
||||
// and it lacks the macro wrappers. It also is effectively hardwired to use
|
||||
// js::ProfilingStackFrame::Category::OTHER as the category, because that's what
|
||||
// the callbacks provided by the profiler use. (Specifying the category in
|
||||
// this file would require #including ProfilingStack.h in mozglue, which we
|
||||
// JS::ProfilingCategory::OTHER as the category pair, because that's what
|
||||
// the callbacks provided by the profiler use. (Specifying the categories in
|
||||
// this file would require #including ProfilingCategory.h in mozglue, which we
|
||||
// don't want to do.)
|
||||
|
||||
class ProfilingStack;
|
||||
|
||||
@@ -498,7 +498,7 @@ void BackgroundHangThread::ReportHang(TimeDuration aHangTime) {
|
||||
TimeStamp endTime = TimeStamp::Now();
|
||||
TimeStamp startTime = endTime - aHangTime;
|
||||
profiler_add_marker_for_thread(
|
||||
mStackHelper.GetThreadId(), js::ProfilingStackFrame::Category::OTHER,
|
||||
mStackHelper.GetThreadId(), JS::ProfilingCategoryPair::OTHER,
|
||||
"BHR-detected hang", MakeUnique<HangMarkerPayload>(startTime, endTime));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -58,7 +58,7 @@ void ProfileBuffer::AddStoredMarker(ProfilerMarker* aStoredMarker) {
|
||||
void ProfileBuffer::CollectCodeLocation(
|
||||
const char* aLabel, const char* aStr, uint32_t aFrameFlags,
|
||||
const Maybe<uint32_t>& aLineNumber, const Maybe<uint32_t>& aColumnNumber,
|
||||
const Maybe<js::ProfilingStackFrame::Category>& aCategory) {
|
||||
const Maybe<JS::ProfilingCategoryPair>& aCategoryPair) {
|
||||
AddEntry(ProfileBufferEntry::Label(aLabel));
|
||||
AddEntry(ProfileBufferEntry::FrameFlags(uint64_t(aFrameFlags)));
|
||||
|
||||
@@ -87,8 +87,8 @@ void ProfileBuffer::CollectCodeLocation(
|
||||
AddEntry(ProfileBufferEntry::ColumnNumber(*aColumnNumber));
|
||||
}
|
||||
|
||||
if (aCategory.isSome()) {
|
||||
AddEntry(ProfileBufferEntry::Category(int(*aCategory)));
|
||||
if (aCategoryPair.isSome()) {
|
||||
AddEntry(ProfileBufferEntry::CategoryPair(int(*aCategoryPair)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,5 +186,5 @@ void ProfileBufferCollector::CollectProfilingStackFrame(
|
||||
}
|
||||
|
||||
mBuf.CollectCodeLocation(label, dynamicString, aFrame.flags(), line, column,
|
||||
Some(aFrame.category()));
|
||||
Some(aFrame.categoryPair()));
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ class ProfileBuffer final {
|
||||
const char* aLabel, const char* aStr, uint32_t aFrameFlags,
|
||||
const mozilla::Maybe<uint32_t>& aLineNumber,
|
||||
const mozilla::Maybe<uint32_t>& aColumnNumber,
|
||||
const mozilla::Maybe<js::ProfilingStackFrame::Category>& aCategory);
|
||||
const mozilla::Maybe<JS::ProfilingCategoryPair>& aCategoryPair);
|
||||
|
||||
// Maximum size of a frameKey string that we'll handle.
|
||||
static const size_t kMaxFrameKeyLength = 512;
|
||||
|
||||
@@ -357,7 +357,7 @@ bool UniqueStacks::FrameKey::NormalFrameData::operator==(
|
||||
const NormalFrameData& aOther) const {
|
||||
return mLocation == aOther.mLocation &&
|
||||
mRelevantForJS == aOther.mRelevantForJS && mLine == aOther.mLine &&
|
||||
mColumn == aOther.mColumn && mCategory == aOther.mCategory;
|
||||
mColumn == aOther.mColumn && mCategoryPair == aOther.mCategoryPair;
|
||||
}
|
||||
|
||||
bool UniqueStacks::FrameKey::JITFrameData::operator==(
|
||||
@@ -380,8 +380,8 @@ uint32_t UniqueStacks::FrameKey::Hash() const {
|
||||
if (data.mColumn.isSome()) {
|
||||
hash = AddToHash(hash, *data.mColumn);
|
||||
}
|
||||
if (data.mCategory.isSome()) {
|
||||
hash = AddToHash(hash, *data.mCategory);
|
||||
if (data.mCategoryPair.isSome()) {
|
||||
hash = AddToHash(hash, uint32_t(*data.mCategoryPair));
|
||||
}
|
||||
} else {
|
||||
const JITFrameData& data = mData.as<JITFrameData>();
|
||||
@@ -527,8 +527,10 @@ void UniqueStacks::StreamNonJITFrame(const FrameKey& aFrame) {
|
||||
if (data.mColumn.isSome()) {
|
||||
writer.IntElement(COLUMN, *data.mColumn);
|
||||
}
|
||||
if (data.mCategory.isSome()) {
|
||||
writer.IntElement(CATEGORY, *data.mCategory);
|
||||
if (data.mCategoryPair.isSome()) {
|
||||
const JS::ProfilingCategoryPairInfo& info =
|
||||
JS::GetProfilingCategoryPairInfo(*data.mCategoryPair);
|
||||
writer.IntElement(CATEGORY, uint32_t(info.mCategory));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -785,7 +787,7 @@ class EntryGetter {
|
||||
// ThreadId
|
||||
// Time
|
||||
// ( NativeLeafAddr
|
||||
// | Label FrameFlags? DynamicStringFragment* LineNumber? Category?
|
||||
// | Label FrameFlags? DynamicStringFragment* LineNumber? CategoryPair?
|
||||
// | JitReturnAddr
|
||||
// )+
|
||||
// Marker*
|
||||
@@ -821,15 +823,15 @@ class EntryGetter {
|
||||
// - ProfilingStack frames without a dynamic string:
|
||||
//
|
||||
// Label("js::RunScript")
|
||||
// Category(ProfilingStackFrame::Category::JS)
|
||||
// CategoryPair(JS::ProfilingCategoryPair::JS)
|
||||
//
|
||||
// Label("XREMain::XRE_main")
|
||||
// LineNumber(4660)
|
||||
// Category(ProfilingStackFrame::Category::OTHER)
|
||||
// CategoryPair(JS::ProfilingCategoryPair::OTHER)
|
||||
//
|
||||
// Label("ElementRestyler::ComputeStyleChangeFor")
|
||||
// LineNumber(3003)
|
||||
// Category(ProfilingStackFrame::Category::CSS)
|
||||
// CategoryPair(JS::ProfilingCategoryPair::CSS)
|
||||
//
|
||||
// - ProfilingStack frames with a dynamic string:
|
||||
//
|
||||
@@ -838,7 +840,7 @@ class EntryGetter {
|
||||
// DynamicStringFragment("domwindo")
|
||||
// DynamicStringFragment("wopened")
|
||||
// LineNumber(291)
|
||||
// Category(ProfilingStackFrame::Category::OTHER)
|
||||
// CategoryPair(JS::ProfilingCategoryPair::OTHER)
|
||||
//
|
||||
// Label("")
|
||||
// FrameFlags(uint64_t(ProfilingStackFrame::Flags::IS_JS_FRAME))
|
||||
@@ -851,7 +853,7 @@ class EntryGetter {
|
||||
// DynamicStringFragment("ay.js:5)")
|
||||
// DynamicStringFragment("") # this string holds the closing '\0'
|
||||
// LineNumber(25)
|
||||
// Category(ProfilingStackFrame::Category::JS)
|
||||
// CategoryPair(JS::ProfilingCategoryPair::JS)
|
||||
//
|
||||
// Label("")
|
||||
// FrameFlags(uint64_t(ProfilingStackFrame::Flags::IS_JS_FRAME))
|
||||
@@ -859,7 +861,7 @@ class EntryGetter {
|
||||
// DynamicStringFragment("elf-host")
|
||||
// DynamicStringFragment("ed:914)")
|
||||
// LineNumber(945)
|
||||
// Category(ProfilingStackFrame::Category::JS)
|
||||
// CategoryPair(JS::ProfilingCategoryPair::JS)
|
||||
//
|
||||
// - A profiling stack frame with a dynamic string, but with privacy enabled:
|
||||
//
|
||||
@@ -868,7 +870,7 @@ class EntryGetter {
|
||||
// DynamicStringFragment("(private")
|
||||
// DynamicStringFragment(")")
|
||||
// LineNumber(291)
|
||||
// Category(ProfilingStackFrame::Category::OTHER)
|
||||
// CategoryPair(JS::ProfilingCategoryPair::OTHER)
|
||||
//
|
||||
// - A profiling stack frame with an overly long dynamic string:
|
||||
//
|
||||
@@ -877,7 +879,7 @@ class EntryGetter {
|
||||
// DynamicStringFragment("(too lon")
|
||||
// DynamicStringFragment("g)")
|
||||
// LineNumber(100)
|
||||
// Category(ProfilingStackFrame::Category::NETWORK)
|
||||
// CategoryPair(JS::ProfilingCategoryPair::NETWORK)
|
||||
//
|
||||
// - A wasm JIT frame:
|
||||
//
|
||||
@@ -1062,15 +1064,16 @@ void ProfileBuffer::StreamSamplesToJSON(SpliceableJSONWriter& aWriter,
|
||||
e.Next();
|
||||
}
|
||||
|
||||
Maybe<unsigned> category;
|
||||
if (e.Has() && e.Get().IsCategory()) {
|
||||
category = Some(unsigned(e.Get().GetInt()));
|
||||
Maybe<JS::ProfilingCategoryPair> categoryPair;
|
||||
if (e.Has() && e.Get().IsCategoryPair()) {
|
||||
categoryPair =
|
||||
Some(JS::ProfilingCategoryPair(uint32_t(e.Get().GetInt())));
|
||||
e.Next();
|
||||
}
|
||||
|
||||
stack = aUniqueStacks.AppendFrame(
|
||||
stack, UniqueStacks::FrameKey(std::move(frameLabel), relevantForJS,
|
||||
line, column, category));
|
||||
line, column, categoryPair));
|
||||
|
||||
} else if (e.Get().IsJitReturnAddr()) {
|
||||
numFrames++;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "ProfileJSONWriter.h"
|
||||
|
||||
#include "gtest/MozGtestFriend.h"
|
||||
#include "js/ProfilingCategory.h"
|
||||
#include "js/ProfilingFrameIterator.h"
|
||||
#include "js/TrackedOptimizationInfo.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
@@ -27,7 +28,7 @@ class ProfilerMarker;
|
||||
// NOTE! If you add entries, you need to verify if they need to be added to the
|
||||
// switch statement in DuplicateLastSample!
|
||||
#define FOR_EACH_PROFILE_BUFFER_ENTRY_KIND(MACRO) \
|
||||
MACRO(Category, int) \
|
||||
MACRO(CategoryPair, int) \
|
||||
MACRO(CollectionStart, double) \
|
||||
MACRO(CollectionEnd, double) \
|
||||
MACRO(Label, const char*) \
|
||||
@@ -224,9 +225,9 @@ class UniqueStacks {
|
||||
FrameKey(nsCString&& aLocation, bool aRelevantForJS,
|
||||
const mozilla::Maybe<unsigned>& aLine,
|
||||
const mozilla::Maybe<unsigned>& aColumn,
|
||||
const mozilla::Maybe<unsigned>& aCategory)
|
||||
const mozilla::Maybe<JS::ProfilingCategoryPair>& aCategoryPair)
|
||||
: mData(NormalFrameData{aLocation, aRelevantForJS, aLine, aColumn,
|
||||
aCategory}) {}
|
||||
aCategoryPair}) {}
|
||||
|
||||
FrameKey(void* aJITAddress, uint32_t aJITDepth, uint32_t aRangeIndex)
|
||||
: mData(JITFrameData{aJITAddress, aJITDepth, aRangeIndex}) {}
|
||||
@@ -245,7 +246,7 @@ class UniqueStacks {
|
||||
bool mRelevantForJS;
|
||||
mozilla::Maybe<unsigned> mLine;
|
||||
mozilla::Maybe<unsigned> mColumn;
|
||||
mozilla::Maybe<unsigned> mCategory;
|
||||
mozilla::Maybe<JS::ProfilingCategoryPair> mCategoryPair;
|
||||
};
|
||||
struct JITFrameData {
|
||||
bool operator==(const JITFrameData& aOther) const;
|
||||
|
||||
@@ -21,7 +21,7 @@ class ProfilerMarker {
|
||||
|
||||
public:
|
||||
explicit ProfilerMarker(
|
||||
const char* aMarkerName, js::ProfilingStackFrame::Category aCategory,
|
||||
const char* aMarkerName, JS::ProfilingCategoryPair aCategoryPair,
|
||||
int aThreadId,
|
||||
mozilla::UniquePtr<ProfilerMarkerPayload> aPayload = nullptr,
|
||||
double aTime = 0)
|
||||
@@ -31,7 +31,7 @@ class ProfilerMarker {
|
||||
mTime(aTime),
|
||||
mPositionInBuffer{0},
|
||||
mThreadId{aThreadId},
|
||||
mCategory{aCategory} {}
|
||||
mCategoryPair{aCategoryPair} {}
|
||||
|
||||
void SetPositionInBuffer(uint64_t aPosition) {
|
||||
mPositionInBuffer = aPosition;
|
||||
@@ -55,7 +55,9 @@ class ProfilerMarker {
|
||||
{
|
||||
aUniqueStacks.mUniqueStrings->WriteElement(aWriter, mMarkerName.get());
|
||||
aWriter.DoubleElement(mTime);
|
||||
aWriter.IntElement(unsigned(mCategory));
|
||||
const JS::ProfilingCategoryPairInfo& info =
|
||||
JS::GetProfilingCategoryPairInfo(mCategoryPair);
|
||||
aWriter.IntElement(unsigned(info.mCategory));
|
||||
// TODO: Store the callsite for this marker if available:
|
||||
// if have location data
|
||||
// b.NameValue(marker, "location", ...);
|
||||
@@ -75,7 +77,7 @@ class ProfilerMarker {
|
||||
double mTime;
|
||||
uint64_t mPositionInBuffer;
|
||||
int mThreadId;
|
||||
js::ProfilingStackFrame::Category mCategory;
|
||||
JS::ProfilingCategoryPair mCategoryPair;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
||||
@@ -38,13 +38,13 @@ class RacyRegisteredThread final {
|
||||
bool IsBeingProfiled() const { return mIsBeingProfiled; }
|
||||
|
||||
void AddPendingMarker(const char* aMarkerName,
|
||||
js::ProfilingStackFrame::Category aCategory,
|
||||
JS::ProfilingCategoryPair aCategoryPair,
|
||||
mozilla::UniquePtr<ProfilerMarkerPayload> aPayload,
|
||||
double aTime) {
|
||||
// Note: We don't assert on mIsBeingProfiled, because it could have changed
|
||||
// between the check in the caller and now.
|
||||
ProfilerMarker* marker = new ProfilerMarker(
|
||||
aMarkerName, aCategory, mThreadId, std::move(aPayload), aTime);
|
||||
aMarkerName, aCategoryPair, mThreadId, std::move(aPayload), aTime);
|
||||
mPendingMarkers.insert(marker);
|
||||
}
|
||||
|
||||
|
||||
@@ -1709,41 +1709,21 @@ static void StreamTaskTracer(PSLockRef aLock, SpliceableJSONWriter& aWriter) {
|
||||
}
|
||||
|
||||
static void StreamCategories(SpliceableJSONWriter& aWriter) {
|
||||
// Same order as ProfilingStackFrame::Category.
|
||||
// The list of available color names is:
|
||||
// transparent, grey, purple, yellow, orange, lightblue, green, blue, magenta
|
||||
aWriter.Start();
|
||||
aWriter.StringProperty("name", "Idle");
|
||||
aWriter.StringProperty("color", "transparent");
|
||||
aWriter.EndObject();
|
||||
aWriter.Start();
|
||||
aWriter.StringProperty("name", "Other");
|
||||
aWriter.StringProperty("color", "grey");
|
||||
aWriter.EndObject();
|
||||
aWriter.Start();
|
||||
aWriter.StringProperty("name", "Layout");
|
||||
aWriter.StringProperty("color", "purple");
|
||||
aWriter.EndObject();
|
||||
aWriter.Start();
|
||||
aWriter.StringProperty("name", "JavaScript");
|
||||
aWriter.StringProperty("color", "yellow");
|
||||
aWriter.EndObject();
|
||||
aWriter.Start();
|
||||
aWriter.StringProperty("name", "GC / CC");
|
||||
aWriter.StringProperty("color", "orange");
|
||||
aWriter.EndObject();
|
||||
aWriter.Start();
|
||||
aWriter.StringProperty("name", "Network");
|
||||
aWriter.StringProperty("color", "lightblue");
|
||||
aWriter.EndObject();
|
||||
aWriter.Start();
|
||||
aWriter.StringProperty("name", "Graphics");
|
||||
aWriter.StringProperty("color", "green");
|
||||
aWriter.EndObject();
|
||||
aWriter.Start();
|
||||
aWriter.StringProperty("name", "DOM");
|
||||
aWriter.StringProperty("color", "blue");
|
||||
aWriter.EndObject();
|
||||
// Same order as ProfilingCategory.
|
||||
|
||||
#define CATEGORY_JSON_BEGIN_CATEGORY(name, labelAsString, color) \
|
||||
aWriter.Start(); \
|
||||
aWriter.StringProperty("name", labelAsString); \
|
||||
aWriter.StringProperty("color", color);
|
||||
#define CATEGORY_JSON_SUBCATEGORY(category, name, labelAsString)
|
||||
#define CATEGORY_JSON_END_CATEGORY aWriter.EndObject();
|
||||
|
||||
PROFILING_CATEGORY_LIST(CATEGORY_JSON_BEGIN_CATEGORY,
|
||||
CATEGORY_JSON_SUBCATEGORY, CATEGORY_JSON_END_CATEGORY)
|
||||
|
||||
#undef CATEGORY_JSON_BEGIN_CATEGORY
|
||||
#undef CATEGORY_JSON_SUBCATEGORY
|
||||
#undef CATEGORY_JSON_END_CATEGORY
|
||||
}
|
||||
|
||||
static void StreamMetaJSCustomObject(PSLockRef aLock,
|
||||
@@ -1937,22 +1917,22 @@ static UniquePtr<ProfileBuffer> CollectJavaThreadProfileData() {
|
||||
}
|
||||
nsCString frameNameString = frameName->ToCString();
|
||||
|
||||
// Compute a category for the frame:
|
||||
// Compute a category pair for the frame:
|
||||
// - IDLE for the wait function android.os.MessageQueue.nativePollOnce()
|
||||
// - OTHER for any function that's directly called by that wait function
|
||||
// - no category on everything else
|
||||
Maybe<js::ProfilingStackFrame::Category> category;
|
||||
Maybe<JS::ProfilingCategoryPair> categoryPair;
|
||||
if (frameNameString.EqualsLiteral(
|
||||
"android.os.MessageQueue.nativePollOnce()")) {
|
||||
category = Some(js::ProfilingStackFrame::Category::IDLE);
|
||||
categoryPair = Some(JS::ProfilingCategoryPair::IDLE);
|
||||
parentFrameWasIdleFrame = true;
|
||||
} else if (parentFrameWasIdleFrame) {
|
||||
category = Some(js::ProfilingStackFrame::Category::OTHER);
|
||||
categoryPair = Some(JS::ProfilingCategoryPair::OTHER);
|
||||
parentFrameWasIdleFrame = false;
|
||||
}
|
||||
|
||||
buffer->CollectCodeLocation("", frameNameString.get(), 0, Nothing(),
|
||||
Nothing(), category);
|
||||
Nothing(), categoryPair);
|
||||
}
|
||||
sampleId++;
|
||||
}
|
||||
@@ -2636,7 +2616,7 @@ ProfilingStack* MozGlueLabelEnter(const char* aLabel,
|
||||
ProfilingStack* profilingStack = AutoProfilerLabel::sProfilingStack.get();
|
||||
if (profilingStack) {
|
||||
profilingStack->pushLabelFrame(aLabel, aDynamicString, aSp,
|
||||
js::ProfilingStackFrame::Category::OTHER);
|
||||
JS::ProfilingCategoryPair::OTHER);
|
||||
}
|
||||
return profilingStack;
|
||||
}
|
||||
@@ -3686,7 +3666,7 @@ void ProfilerBacktraceDestructor::operator()(ProfilerBacktrace* aBacktrace) {
|
||||
}
|
||||
|
||||
static void racy_profiler_add_marker(
|
||||
const char* aMarkerName, js::ProfilingStackFrame::Category aCategory,
|
||||
const char* aMarkerName, JS::ProfilingCategoryPair aCategoryPair,
|
||||
UniquePtr<ProfilerMarkerPayload> aPayload) {
|
||||
MOZ_RELEASE_ASSERT(CorePS::Exists());
|
||||
|
||||
@@ -3708,11 +3688,11 @@ static void racy_profiler_add_marker(
|
||||
: TimeStamp::Now();
|
||||
TimeDuration delta = origin - CorePS::ProcessStartTime();
|
||||
racyRegisteredThread->AddPendingMarker(
|
||||
aMarkerName, aCategory, std::move(aPayload), delta.ToMilliseconds());
|
||||
aMarkerName, aCategoryPair, std::move(aPayload), delta.ToMilliseconds());
|
||||
}
|
||||
|
||||
void profiler_add_marker(const char* aMarkerName,
|
||||
js::ProfilingStackFrame::Category aCategory,
|
||||
JS::ProfilingCategoryPair aCategoryPair,
|
||||
UniquePtr<ProfilerMarkerPayload> aPayload) {
|
||||
MOZ_RELEASE_ASSERT(CorePS::Exists());
|
||||
|
||||
@@ -3721,19 +3701,18 @@ void profiler_add_marker(const char* aMarkerName,
|
||||
return;
|
||||
}
|
||||
|
||||
racy_profiler_add_marker(aMarkerName, aCategory, std::move(aPayload));
|
||||
racy_profiler_add_marker(aMarkerName, aCategoryPair, std::move(aPayload));
|
||||
}
|
||||
|
||||
void profiler_add_marker(const char* aMarkerName,
|
||||
js::ProfilingStackFrame::Category aCategory) {
|
||||
profiler_add_marker(aMarkerName, aCategory, nullptr);
|
||||
JS::ProfilingCategoryPair aCategoryPair) {
|
||||
profiler_add_marker(aMarkerName, aCategoryPair, nullptr);
|
||||
}
|
||||
|
||||
// This is a simplified version of profiler_add_marker that can be easily passed
|
||||
// into the JS engine.
|
||||
void profiler_add_js_marker(const char* aMarkerName) {
|
||||
profiler_add_marker(aMarkerName, js::ProfilingStackFrame::Category::JS,
|
||||
nullptr);
|
||||
profiler_add_marker(aMarkerName, JS::ProfilingCategoryPair::JS, nullptr);
|
||||
}
|
||||
|
||||
void profiler_add_network_marker(
|
||||
@@ -3758,7 +3737,7 @@ void profiler_add_network_marker(
|
||||
char name[2048];
|
||||
SprintfLiteral(name, "Load %d: %s", id, PromiseFlatCString(spec).get());
|
||||
profiler_add_marker(
|
||||
name, js::ProfilingStackFrame::Category::NETWORK,
|
||||
name, JS::ProfilingCategoryPair::NETWORK,
|
||||
MakeUnique<NetworkMarkerPayload>(
|
||||
static_cast<int64_t>(aChannelId), PromiseFlatCString(spec).get(),
|
||||
aType, aStart, aEnd, aPriority, aCount, aCacheDisposition, aTimings,
|
||||
@@ -3768,7 +3747,7 @@ void profiler_add_network_marker(
|
||||
// This logic needs to add a marker for a different thread, so we actually need
|
||||
// to lock here.
|
||||
void profiler_add_marker_for_thread(int aThreadId,
|
||||
js::ProfilingStackFrame::Category aCategory,
|
||||
JS::ProfilingCategoryPair aCategoryPair,
|
||||
const char* aMarkerName,
|
||||
UniquePtr<ProfilerMarkerPayload> aPayload) {
|
||||
MOZ_RELEASE_ASSERT(CorePS::Exists());
|
||||
@@ -3784,8 +3763,8 @@ void profiler_add_marker_for_thread(int aThreadId,
|
||||
: TimeStamp::Now();
|
||||
TimeDuration delta = origin - CorePS::ProcessStartTime();
|
||||
ProfilerMarker* marker =
|
||||
new ProfilerMarker(aMarkerName, aCategory, aThreadId, std::move(aPayload),
|
||||
delta.ToMilliseconds());
|
||||
new ProfilerMarker(aMarkerName, aCategoryPair, aThreadId,
|
||||
std::move(aPayload), delta.ToMilliseconds());
|
||||
|
||||
#ifdef DEBUG
|
||||
// Assert that our thread ID makes sense
|
||||
@@ -3809,7 +3788,7 @@ void profiler_add_marker_for_thread(int aThreadId,
|
||||
}
|
||||
|
||||
void profiler_tracing(const char* aCategoryString, const char* aMarkerName,
|
||||
js::ProfilingStackFrame::Category aCategory,
|
||||
JS::ProfilingCategoryPair aCategoryPair,
|
||||
TracingKind aKind, const Maybe<nsID>& aDocShellId,
|
||||
const Maybe<uint32_t>& aDocShellHistoryId) {
|
||||
MOZ_RELEASE_ASSERT(CorePS::Exists());
|
||||
@@ -3823,11 +3802,11 @@ void profiler_tracing(const char* aCategoryString, const char* aMarkerName,
|
||||
|
||||
auto payload = MakeUnique<TracingMarkerPayload>(
|
||||
aCategoryString, aKind, aDocShellId, aDocShellHistoryId);
|
||||
racy_profiler_add_marker(aMarkerName, aCategory, std::move(payload));
|
||||
racy_profiler_add_marker(aMarkerName, aCategoryPair, std::move(payload));
|
||||
}
|
||||
|
||||
void profiler_tracing(const char* aCategoryString, const char* aMarkerName,
|
||||
js::ProfilingStackFrame::Category aCategory,
|
||||
JS::ProfilingCategoryPair aCategoryPair,
|
||||
TracingKind aKind, UniqueProfilerBacktrace aCause,
|
||||
const Maybe<nsID>& aDocShellId,
|
||||
const Maybe<uint32_t>& aDocShellHistoryId) {
|
||||
@@ -3843,18 +3822,18 @@ void profiler_tracing(const char* aCategoryString, const char* aMarkerName,
|
||||
auto payload =
|
||||
MakeUnique<TracingMarkerPayload>(aCategoryString, aKind, aDocShellId,
|
||||
aDocShellHistoryId, std::move(aCause));
|
||||
racy_profiler_add_marker(aMarkerName, aCategory, std::move(payload));
|
||||
racy_profiler_add_marker(aMarkerName, aCategoryPair, std::move(payload));
|
||||
}
|
||||
|
||||
void profiler_add_text_marker(
|
||||
const char* aMarkerName, const nsACString& aText,
|
||||
js::ProfilingStackFrame::Category aCategory,
|
||||
JS::ProfilingCategoryPair aCategoryPair,
|
||||
const mozilla::TimeStamp& aStartTime, const mozilla::TimeStamp& aEndTime,
|
||||
const mozilla::Maybe<nsID>& aDocShellId,
|
||||
const mozilla::Maybe<uint32_t>& aDocShellHistoryId,
|
||||
UniqueProfilerBacktrace aCause) {
|
||||
profiler_add_marker(
|
||||
aMarkerName, aCategory,
|
||||
aMarkerName, aCategoryPair,
|
||||
MakeUnique<TextMarkerPayload>(aText, aStartTime, aEndTime, aDocShellId,
|
||||
aDocShellHistoryId, std::move(aCause)));
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ void ProfilerIOInterposeObserver::Observe(Observation& aObservation) {
|
||||
nsString filename;
|
||||
aObservation.Filename(filename);
|
||||
profiler_add_marker(
|
||||
"DiskIO", js::ProfilingStackFrame::Category::OTHER,
|
||||
"DiskIO", JS::ProfilingCategoryPair::OTHER,
|
||||
MakeUnique<DiskIOMarkerPayload>(
|
||||
aObservation.ObservedOperationString(), aObservation.Reference(),
|
||||
NS_ConvertUTF16toUTF8(filename).get(), aObservation.Start(),
|
||||
|
||||
@@ -157,7 +157,7 @@ nsProfiler::ResumeSampling() {
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsProfiler::AddMarker(const char* aMarker) {
|
||||
profiler_add_marker(aMarker, js::ProfilingStackFrame::Category::OTHER);
|
||||
profiler_add_marker(aMarker, JS::ProfilingCategoryPair::OTHER);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,30 +41,30 @@
|
||||
# define PROFILER_SET_JS_CONTEXT(cx)
|
||||
# define PROFILER_CLEAR_JS_CONTEXT()
|
||||
|
||||
# define AUTO_PROFILER_LABEL(label, category)
|
||||
# define AUTO_PROFILER_LABEL_DYNAMIC_CSTR(label, category, cStr)
|
||||
# define AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING(label, category, nsCStr)
|
||||
# define AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING(label, category, nsStr)
|
||||
# define AUTO_PROFILER_LABEL_FAST(label, category, ctx)
|
||||
# define AUTO_PROFILER_LABEL_DYNAMIC_FAST(label, dynamicString, category, \
|
||||
# define AUTO_PROFILER_LABEL(label, categoryPair)
|
||||
# define AUTO_PROFILER_LABEL_DYNAMIC_CSTR(label, categoryPair, cStr)
|
||||
# define AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING(label, categoryPair, nsCStr)
|
||||
# define AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING(label, categoryPair, nsStr)
|
||||
# define AUTO_PROFILER_LABEL_FAST(label, categoryPair, ctx)
|
||||
# define AUTO_PROFILER_LABEL_DYNAMIC_FAST(label, dynamicString, categoryPair, \
|
||||
ctx, flags)
|
||||
|
||||
# define PROFILER_ADD_MARKER(markerName, category)
|
||||
# define PROFILER_ADD_MARKER(markerName, categoryPair)
|
||||
# define PROFILER_ADD_NETWORK_MARKER(uri, pri, channel, type, start, end, \
|
||||
count, cache, timings, redirect)
|
||||
|
||||
# define DECLARE_DOCSHELL_AND_HISTORY_ID(docShell)
|
||||
# define PROFILER_TRACING(categoryString, markerName, category, kind)
|
||||
# define PROFILER_TRACING_DOCSHELL(categoryString, markerName, category, \
|
||||
# define PROFILER_TRACING(categoryString, markerName, categoryPair, kind)
|
||||
# define PROFILER_TRACING_DOCSHELL(categoryString, markerName, categoryPair, \
|
||||
kind, docshell)
|
||||
# define AUTO_PROFILER_TRACING(categoryString, markerName, category)
|
||||
# define AUTO_PROFILER_TRACING_DOCSHELL(categoryString, markerName, category, \
|
||||
# define AUTO_PROFILER_TRACING(categoryString, markerName, categoryPair)
|
||||
# define AUTO_PROFILER_TRACING_DOCSHELL(categoryString, markerName, \
|
||||
categoryPair, docShell)
|
||||
# define AUTO_PROFILER_TEXT_MARKER_CAUSE(markerName, text, categoryPair, cause)
|
||||
# define AUTO_PROFILER_TEXT_MARKER_DOCSHELL(markerName, text, categoryPair, \
|
||||
docShell)
|
||||
# define AUTO_PROFILER_TEXT_MARKER_CAUSE(markerName, text, category, cause)
|
||||
# define AUTO_PROFILER_TEXT_MARKER_DOCSHELL(markerName, text, category, \
|
||||
docShell)
|
||||
# define AUTO_PROFILER_TEXT_MARKER_DOCSHELL_CAUSE(markerName, text, category, \
|
||||
docShell, cause)
|
||||
# define AUTO_PROFILER_TEXT_MARKER_DOCSHELL_CAUSE( \
|
||||
markerName, text, categoryPair, docShell, cause)
|
||||
|
||||
#else // !MOZ_GECKO_PROFILER
|
||||
|
||||
@@ -518,9 +518,9 @@ mozilla::Maybe<ProfilerBufferInfo> profiler_get_buffer_info();
|
||||
//
|
||||
// Use AUTO_PROFILER_LABEL_DYNAMIC_* if you want to add additional / dynamic
|
||||
// information to the label stack frame.
|
||||
# define AUTO_PROFILER_LABEL(label, category) \
|
||||
# define AUTO_PROFILER_LABEL(label, categoryPair) \
|
||||
mozilla::AutoProfilerLabel PROFILER_RAII( \
|
||||
label, nullptr, js::ProfilingStackFrame::Category::category)
|
||||
label, nullptr, JS::ProfilingCategoryPair::categoryPair)
|
||||
|
||||
// Similar to AUTO_PROFILER_LABEL, but with an additional string. The inserted
|
||||
// RAII object stores the cStr pointer in a field; it does not copy the string.
|
||||
@@ -541,9 +541,9 @@ mozilla::Maybe<ProfilerBufferInfo> profiler_get_buffer_info();
|
||||
// profile buffer can just store the raw pointers to the literal strings.
|
||||
// Consequently, AUTO_PROFILER_LABEL frames take up considerably less space in
|
||||
// the profile buffer than AUTO_PROFILER_LABEL_DYNAMIC_* frames.
|
||||
# define AUTO_PROFILER_LABEL_DYNAMIC_CSTR(label, category, cStr) \
|
||||
# define AUTO_PROFILER_LABEL_DYNAMIC_CSTR(label, categoryPair, cStr) \
|
||||
mozilla::AutoProfilerLabel PROFILER_RAII( \
|
||||
label, cStr, js::ProfilingStackFrame::Category::category)
|
||||
label, cStr, JS::ProfilingCategoryPair::categoryPair)
|
||||
|
||||
// Similar to AUTO_PROFILER_LABEL_DYNAMIC_CSTR, but takes an nsACString.
|
||||
//
|
||||
@@ -552,14 +552,13 @@ mozilla::Maybe<ProfilerBufferInfo> profiler_get_buffer_info();
|
||||
// cost of the string assignment unless the profiler is active. Therefore,
|
||||
// unlike AUTO_PROFILER_LABEL and AUTO_PROFILER_LABEL_DYNAMIC_CSTR, this macro
|
||||
// doesn't push/pop a label when the profiler is inactive.
|
||||
# define AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING(label, category, nsCStr) \
|
||||
# define AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING(label, categoryPair, nsCStr) \
|
||||
mozilla::Maybe<nsAutoCString> autoCStr; \
|
||||
mozilla::Maybe<AutoProfilerLabel> raiiObjectNsCString; \
|
||||
if (profiler_is_active()) { \
|
||||
autoCStr.emplace(nsCStr); \
|
||||
raiiObjectNsCString.emplace( \
|
||||
label, autoCStr->get(), \
|
||||
js::ProfilingStackFrame::Category::category); \
|
||||
raiiObjectNsCString.emplace(label, autoCStr->get(), \
|
||||
JS::ProfilingCategoryPair::categoryPair); \
|
||||
}
|
||||
|
||||
// Similar to AUTO_PROFILER_LABEL_DYNAMIC_CSTR, but takes an nsString that is
|
||||
@@ -570,14 +569,14 @@ mozilla::Maybe<ProfilerBufferInfo> profiler_get_buffer_info();
|
||||
// the runtime cost of the string conversion unless the profiler is active.
|
||||
// Therefore, unlike AUTO_PROFILER_LABEL and AUTO_PROFILER_LABEL_DYNAMIC_CSTR,
|
||||
// this macro doesn't push/pop a label when the profiler is inactive.
|
||||
# define AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING(label, category, nsStr) \
|
||||
# define AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING(label, categoryPair, \
|
||||
nsStr) \
|
||||
mozilla::Maybe<NS_LossyConvertUTF16toASCII> asciiStr; \
|
||||
mozilla::Maybe<AutoProfilerLabel> raiiObjectLossyNsString; \
|
||||
if (profiler_is_active()) { \
|
||||
asciiStr.emplace(nsStr); \
|
||||
raiiObjectLossyNsString.emplace( \
|
||||
label, asciiStr->get(), \
|
||||
js::ProfilingStackFrame::Category::category); \
|
||||
label, asciiStr->get(), JS::ProfilingCategoryPair::categoryPair); \
|
||||
}
|
||||
|
||||
// Similar to AUTO_PROFILER_LABEL, but accepting a JSContext* parameter, and a
|
||||
@@ -586,18 +585,18 @@ mozilla::Maybe<ProfilerBufferInfo> profiler_get_buffer_info();
|
||||
// noticeable. It avoids overhead from the TLS lookup because it can get the
|
||||
// ProfilingStack from the JS context, and avoids almost all overhead in the
|
||||
// case where the profiler is disabled.
|
||||
# define AUTO_PROFILER_LABEL_FAST(label, category, ctx) \
|
||||
# define AUTO_PROFILER_LABEL_FAST(label, categoryPair, ctx) \
|
||||
mozilla::AutoProfilerLabel PROFILER_RAII( \
|
||||
ctx, label, nullptr, js::ProfilingStackFrame::Category::category)
|
||||
ctx, label, nullptr, JS::ProfilingCategoryPair::categoryPair)
|
||||
|
||||
// Similar to AUTO_PROFILER_LABEL_FAST, but also takes an extra string and an
|
||||
// additional set of flags. The flags parameter should carry values from the
|
||||
// js::ProfilingStackFrame::Flags enum.
|
||||
# define AUTO_PROFILER_LABEL_DYNAMIC_FAST(label, dynamicString, category, \
|
||||
# define AUTO_PROFILER_LABEL_DYNAMIC_FAST(label, dynamicString, categoryPair, \
|
||||
ctx, flags) \
|
||||
mozilla::AutoProfilerLabel PROFILER_RAII( \
|
||||
ctx, label, dynamicString, \
|
||||
js::ProfilingStackFrame::Category::category, flags)
|
||||
ctx, label, dynamicString, JS::ProfilingCategoryPair::categoryPair, \
|
||||
flags)
|
||||
|
||||
// Insert a marker in the profile timeline. This is useful to delimit something
|
||||
// important happening such as the first paint. Unlike labels, which are only
|
||||
@@ -607,19 +606,19 @@ mozilla::Maybe<ProfilerBufferInfo> profiler_get_buffer_info();
|
||||
// certain length of time. A no-op if the profiler is inactive or in privacy
|
||||
// mode.
|
||||
|
||||
# define PROFILER_ADD_MARKER(markerName, category) \
|
||||
profiler_add_marker(markerName, js::ProfilingStackFrame::Category::category)
|
||||
# define PROFILER_ADD_MARKER(markerName, categoryPair) \
|
||||
profiler_add_marker(markerName, JS::ProfilingCategoryPair::categoryPair)
|
||||
|
||||
void profiler_add_marker(const char* aMarkerName,
|
||||
js::ProfilingStackFrame::Category aCategory);
|
||||
JS::ProfilingCategoryPair aCategoryPair);
|
||||
void profiler_add_marker(const char* aMarkerName,
|
||||
js::ProfilingStackFrame::Category aCategory,
|
||||
JS::ProfilingCategoryPair aCategoryPair,
|
||||
mozilla::UniquePtr<ProfilerMarkerPayload> aPayload);
|
||||
void profiler_add_js_marker(const char* aMarkerName);
|
||||
|
||||
// Insert a marker in the profile timeline for a specified thread.
|
||||
void profiler_add_marker_for_thread(
|
||||
int aThreadId, js::ProfilingStackFrame::Category aCategory,
|
||||
int aThreadId, JS::ProfilingCategoryPair aCategoryPair,
|
||||
const char* aMarkerName,
|
||||
mozilla::UniquePtr<ProfilerMarkerPayload> aPayload);
|
||||
|
||||
@@ -664,41 +663,39 @@ enum TracingKind {
|
||||
// Adds a tracing marker to the profile. A no-op if the profiler is inactive or
|
||||
// in privacy mode.
|
||||
|
||||
# define PROFILER_TRACING(categoryString, markerName, category, kind) \
|
||||
# define PROFILER_TRACING(categoryString, markerName, categoryPair, kind) \
|
||||
profiler_tracing(categoryString, markerName, \
|
||||
js::ProfilingStackFrame::Category::category, kind)
|
||||
# define PROFILER_TRACING_DOCSHELL(categoryString, markerName, category, \
|
||||
JS::ProfilingCategoryPair::categoryPair, kind)
|
||||
# define PROFILER_TRACING_DOCSHELL(categoryString, markerName, categoryPair, \
|
||||
kind, docShell) \
|
||||
DECLARE_DOCSHELL_AND_HISTORY_ID(docShell); \
|
||||
profiler_tracing(categoryString, markerName, \
|
||||
js::ProfilingStackFrame::Category::category, kind, \
|
||||
JS::ProfilingCategoryPair::categoryPair, kind, \
|
||||
docShellId, docShellHistoryId)
|
||||
|
||||
void profiler_tracing(
|
||||
const char* aCategoryString, const char* aMarkerName,
|
||||
js::ProfilingStackFrame::Category aCategory, TracingKind aKind,
|
||||
JS::ProfilingCategoryPair aCategoryPair, TracingKind aKind,
|
||||
const mozilla::Maybe<nsID>& aDocShellId = mozilla::Nothing(),
|
||||
const mozilla::Maybe<uint32_t>& aDocShellHistoryId = mozilla::Nothing());
|
||||
void profiler_tracing(
|
||||
const char* aCategoryString, const char* aMarkerName,
|
||||
js::ProfilingStackFrame::Category aCategory, TracingKind aKind,
|
||||
JS::ProfilingCategoryPair aCategoryPair, TracingKind aKind,
|
||||
UniqueProfilerBacktrace aCause,
|
||||
const mozilla::Maybe<nsID>& aDocShellId = mozilla::Nothing(),
|
||||
const mozilla::Maybe<uint32_t>& aDocShellHistoryId = mozilla::Nothing());
|
||||
|
||||
// Adds a START/END pair of tracing markers.
|
||||
# define AUTO_PROFILER_TRACING(categoryString, markerName, category) \
|
||||
# define AUTO_PROFILER_TRACING(categoryString, markerName, categoryPair) \
|
||||
mozilla::AutoProfilerTracing PROFILER_RAII( \
|
||||
categoryString, markerName, \
|
||||
js::ProfilingStackFrame::Category::category, mozilla::Nothing(), \
|
||||
mozilla::Nothing())
|
||||
# define AUTO_PROFILER_TRACING_DOCSHELL(categoryString, markerName, category, \
|
||||
docShell) \
|
||||
categoryString, markerName, JS::ProfilingCategoryPair::categoryPair, \
|
||||
mozilla::Nothing(), mozilla::Nothing())
|
||||
# define AUTO_PROFILER_TRACING_DOCSHELL(categoryString, markerName, \
|
||||
categoryPair, docShell) \
|
||||
DECLARE_DOCSHELL_AND_HISTORY_ID(docShell); \
|
||||
mozilla::AutoProfilerTracing PROFILER_RAII( \
|
||||
categoryString, markerName, \
|
||||
js::ProfilingStackFrame::Category::category, docShellId, \
|
||||
docShellHistoryId)
|
||||
categoryString, markerName, JS::ProfilingCategoryPair::categoryPair, \
|
||||
docShellId, docShellHistoryId)
|
||||
|
||||
// Add a text marker. Text markers are similar to tracing markers, with the
|
||||
// difference that text markers have their "text" separate from the marker name;
|
||||
@@ -708,7 +705,7 @@ void profiler_tracing(
|
||||
// into one marker.
|
||||
void profiler_add_text_marker(
|
||||
const char* aMarkerName, const nsACString& aText,
|
||||
js::ProfilingStackFrame::Category aCategory,
|
||||
JS::ProfilingCategoryPair aCategoryPair,
|
||||
const mozilla::TimeStamp& aStartTime, const mozilla::TimeStamp& aEndTime,
|
||||
const mozilla::Maybe<nsID>& aDocShellId = mozilla::Nothing(),
|
||||
const mozilla::Maybe<uint32_t>& aDocShellHistoryId = mozilla::Nothing(),
|
||||
@@ -717,14 +714,14 @@ void profiler_add_text_marker(
|
||||
class MOZ_RAII AutoProfilerTextMarker {
|
||||
public:
|
||||
AutoProfilerTextMarker(const char* aMarkerName, const nsACString& aText,
|
||||
js::ProfilingStackFrame::Category aCategory,
|
||||
JS::ProfilingCategoryPair aCategoryPair,
|
||||
const mozilla::Maybe<nsID>& aDocShellId,
|
||||
const mozilla::Maybe<uint32_t>& aDocShellHistoryId,
|
||||
UniqueProfilerBacktrace&& aCause =
|
||||
nullptr MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: mMarkerName(aMarkerName),
|
||||
mText(aText),
|
||||
mCategory(aCategory),
|
||||
mCategoryPair(aCategoryPair),
|
||||
mStartTime(mozilla::TimeStamp::Now()),
|
||||
mCause(std::move(aCause)),
|
||||
mDocShellId(aDocShellId),
|
||||
@@ -733,9 +730,8 @@ class MOZ_RAII AutoProfilerTextMarker {
|
||||
}
|
||||
|
||||
~AutoProfilerTextMarker() {
|
||||
profiler_add_text_marker(mMarkerName, mText,
|
||||
js::ProfilingStackFrame::Category::LAYOUT,
|
||||
mStartTime, mozilla::TimeStamp::Now(), mDocShellId,
|
||||
profiler_add_text_marker(mMarkerName, mText, mCategoryPair, mStartTime,
|
||||
mozilla::TimeStamp::Now(), mDocShellId,
|
||||
mDocShellHistoryId, std::move(mCause));
|
||||
}
|
||||
|
||||
@@ -743,32 +739,32 @@ class MOZ_RAII AutoProfilerTextMarker {
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
const char* mMarkerName;
|
||||
nsCString mText;
|
||||
const js::ProfilingStackFrame::Category mCategory;
|
||||
const JS::ProfilingCategoryPair mCategoryPair;
|
||||
mozilla::TimeStamp mStartTime;
|
||||
UniqueProfilerBacktrace mCause;
|
||||
const mozilla::Maybe<nsID> mDocShellId;
|
||||
const mozilla::Maybe<uint32_t> mDocShellHistoryId;
|
||||
};
|
||||
|
||||
# define AUTO_PROFILER_TEXT_MARKER_CAUSE(markerName, text, category, \
|
||||
# define AUTO_PROFILER_TEXT_MARKER_CAUSE(markerName, text, categoryPair, \
|
||||
cause) \
|
||||
AutoProfilerTextMarker PROFILER_RAII( \
|
||||
markerName, text, js::ProfilingStackFrame::Category::category, \
|
||||
Nothing(), Nothing(), cause)
|
||||
markerName, text, JS::ProfilingCategoryPair::categoryPair, Nothing(), \
|
||||
Nothing(), cause)
|
||||
|
||||
# define AUTO_PROFILER_TEXT_MARKER_DOCSHELL(markerName, text, category, \
|
||||
# define AUTO_PROFILER_TEXT_MARKER_DOCSHELL(markerName, text, categoryPair, \
|
||||
docShell) \
|
||||
DECLARE_DOCSHELL_AND_HISTORY_ID(docShell); \
|
||||
AutoProfilerTextMarker PROFILER_RAII( \
|
||||
markerName, text, js::ProfilingStackFrame::Category::category, \
|
||||
docShellId, docShellHistoryId)
|
||||
markerName, text, JS::ProfilingCategoryPair::categoryPair, docShellId, \
|
||||
docShellHistoryId)
|
||||
|
||||
# define AUTO_PROFILER_TEXT_MARKER_DOCSHELL_CAUSE(markerName, text, category, \
|
||||
docShell, cause) \
|
||||
# define AUTO_PROFILER_TEXT_MARKER_DOCSHELL_CAUSE( \
|
||||
markerName, text, categoryPair, docShell, cause) \
|
||||
DECLARE_DOCSHELL_AND_HISTORY_ID(docShell); \
|
||||
AutoProfilerTextMarker PROFILER_RAII( \
|
||||
markerName, text, js::ProfilingStackFrame::Category::category, \
|
||||
docShellId, docShellHistoryId, cause)
|
||||
markerName, text, JS::ProfilingCategoryPair::categoryPair, docShellId, \
|
||||
docShellHistoryId, cause)
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Output profiles
|
||||
@@ -883,12 +879,12 @@ class MOZ_RAII AutoProfilerLabel {
|
||||
public:
|
||||
// This is the AUTO_PROFILER_LABEL and AUTO_PROFILER_LABEL_DYNAMIC variant.
|
||||
AutoProfilerLabel(const char* aLabel, const char* aDynamicString,
|
||||
js::ProfilingStackFrame::Category aCategory,
|
||||
JS::ProfilingCategoryPair aCategoryPair,
|
||||
uint32_t aFlags = 0 MOZ_GUARD_OBJECT_NOTIFIER_PARAM) {
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
|
||||
// Get the ProfilingStack from TLS.
|
||||
Push(sProfilingStack.get(), aLabel, aDynamicString, aCategory, aFlags);
|
||||
Push(sProfilingStack.get(), aLabel, aDynamicString, aCategoryPair, aFlags);
|
||||
}
|
||||
|
||||
// This is the AUTO_PROFILER_LABEL_FAST variant. It retrieves the
|
||||
@@ -896,22 +892,22 @@ class MOZ_RAII AutoProfilerLabel {
|
||||
// inactive.
|
||||
AutoProfilerLabel(JSContext* aJSContext, const char* aLabel,
|
||||
const char* aDynamicString,
|
||||
js::ProfilingStackFrame::Category aCategory,
|
||||
JS::ProfilingCategoryPair aCategoryPair,
|
||||
uint32_t aFlags MOZ_GUARD_OBJECT_NOTIFIER_PARAM) {
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
Push(js::GetContextProfilingStackIfEnabled(aJSContext), aLabel,
|
||||
aDynamicString, aCategory, aFlags);
|
||||
aDynamicString, aCategoryPair, aFlags);
|
||||
}
|
||||
|
||||
void Push(ProfilingStack* aProfilingStack, const char* aLabel,
|
||||
const char* aDynamicString,
|
||||
js::ProfilingStackFrame::Category aCategory, uint32_t aFlags = 0) {
|
||||
const char* aDynamicString, JS::ProfilingCategoryPair aCategoryPair,
|
||||
uint32_t aFlags = 0) {
|
||||
// This function runs both on and off the main thread.
|
||||
|
||||
mProfilingStack = aProfilingStack;
|
||||
if (mProfilingStack) {
|
||||
mProfilingStack->pushLabelFrame(aLabel, aDynamicString, this, aCategory,
|
||||
aFlags);
|
||||
mProfilingStack->pushLabelFrame(aLabel, aDynamicString, this,
|
||||
aCategoryPair, aFlags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -938,39 +934,39 @@ class MOZ_RAII AutoProfilerLabel {
|
||||
class MOZ_RAII AutoProfilerTracing {
|
||||
public:
|
||||
AutoProfilerTracing(const char* aCategoryString, const char* aMarkerName,
|
||||
js::ProfilingStackFrame::Category aCategory,
|
||||
JS::ProfilingCategoryPair aCategoryPair,
|
||||
const mozilla::Maybe<nsID>& aDocShellId,
|
||||
const mozilla::Maybe<uint32_t>& aDocShellHistoryId
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: mCategoryString(aCategoryString),
|
||||
mMarkerName(aMarkerName),
|
||||
mCategory(aCategory),
|
||||
mCategoryPair(aCategoryPair),
|
||||
mDocShellId(aDocShellId),
|
||||
mDocShellHistoryId(aDocShellHistoryId) {
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
profiler_tracing(mCategoryString, mMarkerName, aCategory,
|
||||
profiler_tracing(mCategoryString, mMarkerName, aCategoryPair,
|
||||
TRACING_INTERVAL_START, mDocShellId, mDocShellHistoryId);
|
||||
}
|
||||
|
||||
AutoProfilerTracing(const char* aCategoryString, const char* aMarkerName,
|
||||
js::ProfilingStackFrame::Category aCategory,
|
||||
JS::ProfilingCategoryPair aCategoryPair,
|
||||
UniqueProfilerBacktrace aBacktrace,
|
||||
const mozilla::Maybe<nsID>& aDocShellId,
|
||||
const mozilla::Maybe<uint32_t>& aDocShellHistoryId
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: mCategoryString(aCategoryString),
|
||||
mMarkerName(aMarkerName),
|
||||
mCategory(aCategory),
|
||||
mCategoryPair(aCategoryPair),
|
||||
mDocShellId(aDocShellId),
|
||||
mDocShellHistoryId(aDocShellHistoryId) {
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
profiler_tracing(mCategoryString, mMarkerName, aCategory,
|
||||
profiler_tracing(mCategoryString, mMarkerName, aCategoryPair,
|
||||
TRACING_INTERVAL_START, std::move(aBacktrace), mDocShellId,
|
||||
mDocShellHistoryId);
|
||||
}
|
||||
|
||||
~AutoProfilerTracing() {
|
||||
profiler_tracing(mCategoryString, mMarkerName, mCategory,
|
||||
profiler_tracing(mCategoryString, mMarkerName, mCategoryPair,
|
||||
TRACING_INTERVAL_END, mDocShellId, mDocShellHistoryId);
|
||||
}
|
||||
|
||||
@@ -978,7 +974,7 @@ class MOZ_RAII AutoProfilerTracing {
|
||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
const char* mCategoryString;
|
||||
const char* mMarkerName;
|
||||
const js::ProfilingStackFrame::Category mCategory;
|
||||
const JS::ProfilingCategoryPair mCategoryPair;
|
||||
const mozilla::Maybe<nsID> mDocShellId;
|
||||
const mozilla::Maybe<uint32_t> mDocShellHistoryId;
|
||||
};
|
||||
|
||||
@@ -459,28 +459,27 @@ TEST(GeckoProfiler, Markers) {
|
||||
profiler_start(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL, features,
|
||||
filters, MOZ_ARRAY_LENGTH(filters));
|
||||
|
||||
profiler_tracing("A", "B", js::ProfilingStackFrame::Category::OTHER,
|
||||
TRACING_EVENT);
|
||||
profiler_tracing("A", "B", JS::ProfilingCategoryPair::OTHER, TRACING_EVENT);
|
||||
PROFILER_TRACING("A", "C", OTHER, TRACING_INTERVAL_START);
|
||||
PROFILER_TRACING("A", "C", OTHER, TRACING_INTERVAL_END);
|
||||
|
||||
UniqueProfilerBacktrace bt = profiler_get_backtrace();
|
||||
profiler_tracing("B", "A", js::ProfilingStackFrame::Category::OTHER,
|
||||
TRACING_EVENT, std::move(bt));
|
||||
profiler_tracing("B", "A", JS::ProfilingCategoryPair::OTHER, TRACING_EVENT,
|
||||
std::move(bt));
|
||||
|
||||
{ AUTO_PROFILER_TRACING("C", "A", OTHER); }
|
||||
|
||||
profiler_add_marker("M1", js::ProfilingStackFrame::Category::OTHER);
|
||||
profiler_add_marker("M2", js::ProfilingStackFrame::Category::OTHER,
|
||||
profiler_add_marker("M1", JS::ProfilingCategoryPair::OTHER);
|
||||
profiler_add_marker("M2", JS::ProfilingCategoryPair::OTHER,
|
||||
MakeUnique<TracingMarkerPayload>("C", TRACING_EVENT));
|
||||
PROFILER_ADD_MARKER("M3", OTHER);
|
||||
profiler_add_marker("M4", js::ProfilingStackFrame::Category::OTHER,
|
||||
profiler_add_marker("M4", JS::ProfilingCategoryPair::OTHER,
|
||||
MakeUnique<TracingMarkerPayload>(
|
||||
"C", TRACING_EVENT, mozilla::Nothing(),
|
||||
mozilla::Nothing(), profiler_get_backtrace()));
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
profiler_add_marker("M5", js::ProfilingStackFrame::Category::OTHER,
|
||||
profiler_add_marker("M5", JS::ProfilingCategoryPair::OTHER,
|
||||
MakeUnique<GTestMarkerPayload>(i));
|
||||
}
|
||||
|
||||
@@ -539,7 +538,7 @@ TEST(GeckoProfiler, Markers) {
|
||||
ASSERT_TRUE(GTestMarkerPayload::sNumDestroyed == 10);
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
profiler_add_marker("M5", js::ProfilingStackFrame::Category::OTHER,
|
||||
profiler_add_marker("M5", JS::ProfilingCategoryPair::OTHER,
|
||||
MakeUnique<GTestMarkerPayload>(i));
|
||||
}
|
||||
|
||||
@@ -569,10 +568,10 @@ TEST(GeckoProfiler, DurationLimit) {
|
||||
GTestMarkerPayload::sNumStreamed = 0;
|
||||
GTestMarkerPayload::sNumDestroyed = 0;
|
||||
|
||||
profiler_add_marker("M1", js::ProfilingStackFrame::Category::OTHER,
|
||||
profiler_add_marker("M1", JS::ProfilingCategoryPair::OTHER,
|
||||
MakeUnique<GTestMarkerPayload>(1));
|
||||
PR_Sleep(PR_MillisecondsToInterval(1100));
|
||||
profiler_add_marker("M2", js::ProfilingStackFrame::Category::OTHER,
|
||||
profiler_add_marker("M2", JS::ProfilingCategoryPair::OTHER,
|
||||
MakeUnique<GTestMarkerPayload>(2));
|
||||
PR_Sleep(PR_MillisecondsToInterval(500));
|
||||
|
||||
@@ -785,10 +784,9 @@ TEST(GeckoProfiler, ProfilingStack) {
|
||||
ASSERT_TRUE(profiler_get_backtrace());
|
||||
}
|
||||
|
||||
AutoProfilerLabel label1("A", nullptr,
|
||||
js::ProfilingStackFrame::Category::DOM);
|
||||
AutoProfilerLabel label1("A", nullptr, JS::ProfilingCategoryPair::DOM);
|
||||
AutoProfilerLabel label2("A", dynamic.get(),
|
||||
js::ProfilingStackFrame::Category::NETWORK);
|
||||
JS::ProfilingCategoryPair::NETWORK);
|
||||
ASSERT_TRUE(profiler_get_backtrace());
|
||||
|
||||
profiler_stop();
|
||||
|
||||
@@ -798,13 +798,13 @@ void CycleCollectedJSRuntime::TraverseNativeRoots(
|
||||
if (profiler_thread_is_being_profiled()) {
|
||||
if (aProgress == JS::GC_CYCLE_END) {
|
||||
profiler_add_marker(
|
||||
"GCMajor", js::ProfilingStackFrame::Category::GCCC,
|
||||
"GCMajor", JS::ProfilingCategoryPair::GCCC,
|
||||
MakeUnique<GCMajorMarkerPayload>(aDesc.startTime(aContext),
|
||||
aDesc.endTime(aContext),
|
||||
aDesc.formatJSONProfiler(aContext)));
|
||||
} else if (aProgress == JS::GC_SLICE_END) {
|
||||
profiler_add_marker(
|
||||
"GCSlice", js::ProfilingStackFrame::Category::GCCC,
|
||||
"GCSlice", JS::ProfilingCategoryPair::GCCC,
|
||||
MakeUnique<GCSliceMarkerPayload>(
|
||||
aDesc.lastSliceStart(aContext), aDesc.lastSliceEnd(aContext),
|
||||
aDesc.sliceToJSONProfiler(aContext)));
|
||||
@@ -885,7 +885,7 @@ class MinorGCMarker : public TimelineMarker {
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
else if (aProgress == JS::GCNurseryProgress::GC_NURSERY_COLLECTION_END &&
|
||||
profiler_thread_is_being_profiled()) {
|
||||
profiler_add_marker("GCMinor", js::ProfilingStackFrame::Category::GCCC,
|
||||
profiler_add_marker("GCMinor", JS::ProfilingCategoryPair::GCCC,
|
||||
MakeUnique<GCMinorMarkerPayload>(
|
||||
self->mLatestNurseryCollectionStart,
|
||||
TimeStamp::Now(), JS::MinorGcToJSON(aContext)));
|
||||
|
||||
@@ -412,7 +412,7 @@ class LogModuleManager {
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
if (mAddProfilerMarker && profiler_is_active()) {
|
||||
profiler_add_marker(
|
||||
"LogMessages", js::ProfilingStackFrame::Category::OTHER,
|
||||
"LogMessages", JS::ProfilingCategoryPair::OTHER,
|
||||
MakeUnique<LogMarkerPayload>(aName, buffToWrite, TimeStamp::Now()));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1177,7 +1177,7 @@ nsThread::ProcessNextEvent(bool aMayWait, bool* aResult) {
|
||||
profiler_add_marker(
|
||||
(priority != EventQueuePriority::Idle) ? "LongTask"
|
||||
: "LongIdleTask",
|
||||
js::ProfilingStackFrame::Category::OTHER,
|
||||
JS::ProfilingCategoryPair::OTHER,
|
||||
MakeUnique<LongTaskMarkerPayload>(mCurrentEventStart, now));
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user