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:
Markus Stange
2019-02-16 17:37:43 +00:00
parent e80c88ac39
commit beff53a46a
45 changed files with 468 additions and 341 deletions

View File

@@ -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

View File

@@ -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",

View File

@@ -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));

View File

@@ -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
}

View File

@@ -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),

View File

@@ -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));

View File

@@ -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));

View File

@@ -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
{

View File

@@ -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

View File

@@ -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));

View File

@@ -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
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
}

View File

@@ -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

View 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 */

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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(),

View File

@@ -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',

View File

@@ -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

View File

@@ -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

View File

@@ -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();

View File

@@ -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);
}
}

View File

@@ -426,7 +426,7 @@ struct HelperThread {
private:
struct AutoProfilerLabel {
AutoProfilerLabel(HelperThread* helperThread, const char* label,
ProfilingStackFrame::Category category);
JS::ProfilingCategoryPair categoryPair);
~AutoProfilerLabel();
private:

View File

@@ -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,

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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()));
}

View File

@@ -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;

View File

@@ -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++;

View File

@@ -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;

View File

@@ -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>

View File

@@ -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);
}

View File

@@ -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)));
}

View File

@@ -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(),

View File

@@ -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;
}

View File

@@ -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;
};

View File

@@ -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();

View File

@@ -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)));

View File

@@ -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

View File

@@ -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