diff --git a/mozglue/baseprofiler/core/ProfileBufferEntry.cpp b/mozglue/baseprofiler/core/ProfileBufferEntry.cpp index 4915b400ded0..9894ee6c9235 100644 --- a/mozglue/baseprofiler/core/ProfileBufferEntry.cpp +++ b/mozglue/baseprofiler/core/ProfileBufferEntry.cpp @@ -326,7 +326,8 @@ void UniqueStacks::StreamNonJITFrame(const FrameKey& aFrame) { OPTIMIZATIONS = 3, LINE = 4, COLUMN = 5, - CATEGORY = 6 + CATEGORY = 6, + SUBCATEGORY = 7 }; AutoArraySchemaWriter writer(mFrameTableWriter, *mUniqueStrings); @@ -344,6 +345,7 @@ void UniqueStacks::StreamNonJITFrame(const FrameKey& aFrame) { const ProfilingCategoryPairInfo& info = GetProfilingCategoryPairInfo(*data.mCategoryPair); writer.IntElement(CATEGORY, uint32_t(info.mCategory)); + writer.IntElement(SUBCATEGORY, info.mSubcategoryIndex); } } diff --git a/mozglue/baseprofiler/core/ProfileBufferEntry.h b/mozglue/baseprofiler/core/ProfileBufferEntry.h index 78cf8384c47e..4f63c65caf9c 100644 --- a/mozglue/baseprofiler/core/ProfileBufferEntry.h +++ b/mozglue/baseprofiler/core/ProfileBufferEntry.h @@ -344,11 +344,14 @@ class UniqueStacks { // "schema": // { // "location": 0, /* index into stringTable */ -// "implementation": 1, /* index into stringTable */ -// "optimizations": 2, /* arbitrary JSON */ -// "line": 3, /* number */ -// "column": 4, /* number */ -// "category": 5 /* number */ +// "relevantForJS": 1, /* bool */ +// "implementation": 2, /* index into stringTable */ +// "optimizations": 3, /* arbitrary JSON */ +// "line": 4, /* number */ +// "column": 5, /* number */ +// "category": 6 /* index into profile.meta.categories */ +// "subcategory": 7 /* index into +// profile.meta.categories[category].subcategories */ // }, // "data": // [ diff --git a/mozglue/baseprofiler/core/ProfiledThreadData.cpp b/mozglue/baseprofiler/core/ProfiledThreadData.cpp index 505350e3914b..f4ed9a784ba5 100644 --- a/mozglue/baseprofiler/core/ProfiledThreadData.cpp +++ b/mozglue/baseprofiler/core/ProfiledThreadData.cpp @@ -64,6 +64,7 @@ void ProfiledThreadData::StreamJSON(const ProfileBuffer& aBuffer, schema.WriteField("line"); schema.WriteField("column"); schema.WriteField("category"); + schema.WriteField("subcategory"); } aWriter.StartArrayProperty("data"); diff --git a/mozglue/baseprofiler/core/platform.cpp b/mozglue/baseprofiler/core/platform.cpp index a50e7a1bf197..fe2ec1a74db7 100644 --- a/mozglue/baseprofiler/core/platform.cpp +++ b/mozglue/baseprofiler/core/platform.cpp @@ -1497,14 +1497,35 @@ void AppendSharedLibraries(JSONWriter& aWriter) { } static void StreamCategories(SpliceableJSONWriter& aWriter) { - // Same order as ProfilingCategory. + // Same order as ProfilingCategory. Format: + // [ + // { + // name: "Idle", + // color: "transparent", + // subcategories: ["Other"], + // }, + // { + // name: "Other", + // color: "grey", + // subcategories: [ + // "JSM loading", + // "Subprocess launching", + // "DLL loading" + // ] + // }, + // ... + // ] # 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(); + aWriter.StringProperty("color", color); \ + aWriter.StartArrayProperty("subcategories"); +# define CATEGORY_JSON_SUBCATEGORY(supercategory, name, labelAsString) \ + aWriter.StringElement(labelAsString); +# define CATEGORY_JSON_END_CATEGORY \ + aWriter.EndArray(); \ + aWriter.EndObject(); BASE_PROFILING_CATEGORY_LIST(CATEGORY_JSON_BEGIN_CATEGORY, CATEGORY_JSON_SUBCATEGORY, @@ -1522,7 +1543,7 @@ static void StreamMetaJSCustomObject(PSLockRef aLock, bool aIsShuttingDown) { MOZ_RELEASE_ASSERT(CorePS::Exists() && ActivePS::Exists(aLock)); - aWriter.IntProperty("version", 15); + aWriter.IntProperty("version", 16); // The "startTime" field holds the number of milliseconds since midnight // January 1, 1970 GMT. This grotty code computes (Now - (Now - diff --git a/tools/profiler/core/ProfileBufferEntry.cpp b/tools/profiler/core/ProfileBufferEntry.cpp index e5ac69880601..c370e47902db 100644 --- a/tools/profiler/core/ProfileBufferEntry.cpp +++ b/tools/profiler/core/ProfileBufferEntry.cpp @@ -484,7 +484,8 @@ void UniqueStacks::StreamNonJITFrame(const FrameKey& aFrame) { OPTIMIZATIONS = 3, LINE = 4, COLUMN = 5, - CATEGORY = 6 + CATEGORY = 6, + SUBCATEGORY = 7 }; AutoArraySchemaWriter writer(mFrameTableWriter, *mUniqueStrings); @@ -502,6 +503,7 @@ void UniqueStacks::StreamNonJITFrame(const FrameKey& aFrame) { const JS::ProfilingCategoryPairInfo& info = JS::GetProfilingCategoryPairInfo(*data.mCategoryPair); writer.IntElement(CATEGORY, uint32_t(info.mCategory)); + writer.IntElement(SUBCATEGORY, info.mSubcategoryIndex); } } @@ -603,7 +605,8 @@ static void StreamJITFrame(JSContext* aContext, SpliceableJSONWriter& aWriter, OPTIMIZATIONS = 3, LINE = 4, COLUMN = 5, - CATEGORY = 6 + CATEGORY = 6, + SUBCATEGORY = 7 }; AutoArraySchemaWriter writer(aWriter, aUniqueStrings); @@ -626,6 +629,11 @@ static void StreamJITFrame(JSContext* aContext, SpliceableJSONWriter& aWriter, aJITFrame); }); } + + const JS::ProfilingCategoryPairInfo& info = + JS::GetProfilingCategoryPairInfo(JS::ProfilingCategoryPair::JS); + writer.IntElement(CATEGORY, uint32_t(info.mCategory)); + writer.IntElement(SUBCATEGORY, info.mSubcategoryIndex); } struct CStringWriteFunc : public JSONWriteFunc { diff --git a/tools/profiler/core/ProfileBufferEntry.h b/tools/profiler/core/ProfileBufferEntry.h index d63a77c2f5a5..a1757b45e6c9 100644 --- a/tools/profiler/core/ProfileBufferEntry.h +++ b/tools/profiler/core/ProfileBufferEntry.h @@ -469,11 +469,14 @@ class UniqueStacks { // "schema": // { // "location": 0, /* index into stringTable */ -// "implementation": 1, /* index into stringTable */ -// "optimizations": 2, /* arbitrary JSON */ -// "line": 3, /* number */ -// "column": 4, /* number */ -// "category": 5 /* number */ +// "relevantForJS": 1, /* bool */ +// "implementation": 2, /* index into stringTable */ +// "optimizations": 3, /* arbitrary JSON */ +// "line": 4, /* number */ +// "column": 5, /* number */ +// "category": 6 /* index into profile.meta.categories */ +// "subcategory": 7 /* index into +// profile.meta.categories[category].subcategories */ // }, // "data": // [ diff --git a/tools/profiler/core/ProfiledThreadData.cpp b/tools/profiler/core/ProfiledThreadData.cpp index c140a99db596..1f3be57dbc6f 100644 --- a/tools/profiler/core/ProfiledThreadData.cpp +++ b/tools/profiler/core/ProfiledThreadData.cpp @@ -87,6 +87,7 @@ void ProfiledThreadData::StreamJSON(const ProfileBuffer& aBuffer, schema.WriteField("line"); schema.WriteField("column"); schema.WriteField("category"); + schema.WriteField("subcategory"); } aWriter.StartArrayProperty("data"); diff --git a/tools/profiler/core/platform.cpp b/tools/profiler/core/platform.cpp index d5bf859cae73..3d85120814fb 100644 --- a/tools/profiler/core/platform.cpp +++ b/tools/profiler/core/platform.cpp @@ -1842,14 +1842,35 @@ static void StreamTaskTracer(PSLockRef aLock, SpliceableJSONWriter& aWriter) { } static void StreamCategories(SpliceableJSONWriter& aWriter) { - // Same order as ProfilingCategory. + // Same order as ProfilingCategory. Format: + // [ + // { + // name: "Idle", + // color: "transparent", + // subcategories: ["Other"], + // }, + // { + // name: "Other", + // color: "grey", + // subcategories: [ + // "JSM loading", + // "Subprocess launching", + // "DLL loading" + // ] + // }, + // ... + // ] #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(); + aWriter.StringProperty("color", color); \ + aWriter.StartArrayProperty("subcategories"); +#define CATEGORY_JSON_SUBCATEGORY(supercategory, name, labelAsString) \ + aWriter.StringElement(labelAsString); +#define CATEGORY_JSON_END_CATEGORY \ + aWriter.EndArray(); \ + aWriter.EndObject(); PROFILING_CATEGORY_LIST(CATEGORY_JSON_BEGIN_CATEGORY, CATEGORY_JSON_SUBCATEGORY, CATEGORY_JSON_END_CATEGORY) @@ -1864,7 +1885,7 @@ static void StreamMetaJSCustomObject(PSLockRef aLock, bool aIsShuttingDown) { MOZ_RELEASE_ASSERT(CorePS::Exists() && ActivePS::Exists(aLock)); - aWriter.IntProperty("version", 15); + aWriter.IntProperty("version", 16); // The "startTime" field holds the number of milliseconds since midnight // January 1, 1970 GMT. This grotty code computes (Now - (Now -