diff --git a/tools/profiler/core/ProfileBufferEntry.cpp b/tools/profiler/core/ProfileBufferEntry.cpp index cf9ee5059b2b..26be68cc7de6 100644 --- a/tools/profiler/core/ProfileBufferEntry.cpp +++ b/tools/profiler/core/ProfileBufferEntry.cpp @@ -309,8 +309,7 @@ uint32_t UniqueStacks::FrameKey::Hash() const return hash; } -UniqueStacks::UniqueStacks(JSContext* aContext) - : mContext(aContext) +UniqueStacks::UniqueStacks() { mFrameTableWriter.StartBareList(); mStackTableWriter.StartBareList(); @@ -331,19 +330,19 @@ uint32_t UniqueStacks::GetOrAddStackIndex(const StackKey& aStack) } MOZ_MUST_USE nsTArray -UniqueStacks::GetOrAddJITFrameKeysForAddress(void* aJITAddress) +UniqueStacks::GetOrAddJITFrameKeysForAddress(JSContext* aContext, + void* aJITAddress) { nsTArray& frameKeys = *mAddressToJITFrameKeysMap.LookupOrAdd(aJITAddress); if (frameKeys.IsEmpty()) { - MOZ_RELEASE_ASSERT(mContext); - for (JS::ProfiledFrameHandle handle : JS::GetProfiledFrames(mContext, + for (JS::ProfiledFrameHandle handle : JS::GetProfiledFrames(aContext, aJITAddress)) { // JIT frames with the same canonical address should be treated as the // same frame, so set the frame key's address to the canonical address. FrameKey frameKey(handle.canonicalAddress(), frameKeys.Length()); - MaybeAddJITFrameIndex(frameKey, handle); + MaybeAddJITFrameIndex(aContext, frameKey, handle); frameKeys.AppendElement(frameKey); } MOZ_ASSERT(frameKeys.Length() > 0); @@ -354,7 +353,8 @@ UniqueStacks::GetOrAddJITFrameKeysForAddress(void* aJITAddress) } void -UniqueStacks::MaybeAddJITFrameIndex(const FrameKey& aFrame, +UniqueStacks::MaybeAddJITFrameIndex(JSContext* aContext, + const FrameKey& aFrame, const JS::ProfiledFrameHandle& aJITFrame) { uint32_t index; @@ -365,7 +365,7 @@ UniqueStacks::MaybeAddJITFrameIndex(const FrameKey& aFrame, index = mFrameToIndexMap.Count(); mFrameToIndexMap.Put(aFrame, index); - StreamJITFrame(aJITFrame); + StreamJITFrame(aContext, aJITFrame); } uint32_t @@ -525,7 +525,8 @@ StreamJITFrameOptimizations(SpliceableJSONWriter& aWriter, } void -UniqueStacks::StreamJITFrame(const JS::ProfiledFrameHandle& aJITFrame) +UniqueStacks::StreamJITFrame(JSContext* aContext, + const JS::ProfiledFrameHandle& aJITFrame) { enum Schema : uint32_t { LOCATION = 0, @@ -550,7 +551,7 @@ UniqueStacks::StreamJITFrame(const JS::ProfiledFrameHandle& aJITFrame) if (aJITFrame.hasTrackedOptimizations()) { writer.FreeFormElement(OPTIMIZATIONS, [&](SpliceableJSONWriter& aWriter, UniqueJSONStrings& aUniqueStrings) { - StreamJITFrameOptimizations(aWriter, aUniqueStrings, mContext, + StreamJITFrameOptimizations(aWriter, aUniqueStrings, aContext, aJITFrame); }); } @@ -873,10 +874,13 @@ ProfileBuffer::StreamSamplesToJSON(SpliceableJSONWriter& aWriter, int aThreadId, } else if (e.Get().IsJitReturnAddr()) { numFrames++; + // We can only process JitReturnAddr entries if we have a JSContext. + MOZ_RELEASE_ASSERT(aContext); + // A JIT frame may expand to multiple frames due to inlining. void* pc = e.Get().u.mPtr; nsTArray frameKeys = - aUniqueStacks.GetOrAddJITFrameKeysForAddress(pc); + aUniqueStacks.GetOrAddJITFrameKeysForAddress(aContext, pc); for (const UniqueStacks::FrameKey& frameKey : frameKeys) { stack = aUniqueStacks.AppendFrame(stack, frameKey); } diff --git a/tools/profiler/core/ProfileBufferEntry.h b/tools/profiler/core/ProfileBufferEntry.h index 5fc2e0eb16e9..d2991c92aacd 100644 --- a/tools/profiler/core/ProfileBufferEntry.h +++ b/tools/profiler/core/ProfileBufferEntry.h @@ -218,7 +218,7 @@ public: uint32_t mHash; }; - explicit UniqueStacks(JSContext* aContext); + explicit UniqueStacks(); // Return a StackKey for aFrame as the stack's root frame (no prefix). MOZ_MUST_USE StackKey BeginStack(const FrameKey& aFrame); @@ -228,7 +228,7 @@ public: const FrameKey& aFrame); MOZ_MUST_USE nsTArray - GetOrAddJITFrameKeysForAddress(void* aJITAddress); + GetOrAddJITFrameKeysForAddress(JSContext* aContext, void* aJITAddress); MOZ_MUST_USE uint32_t GetOrAddFrameIndex(const FrameKey& aFrame); MOZ_MUST_USE uint32_t GetOrAddStackIndex(const StackKey& aStack); @@ -239,19 +239,19 @@ public: private: // Make sure that there exists a frame index for aFrame, and if there isn't // one already, create one and call StreamJITFrame for the frame. - void MaybeAddJITFrameIndex(const FrameKey& aFrame, + void MaybeAddJITFrameIndex(JSContext* aContext, + const FrameKey& aFrame, const JS::ProfiledFrameHandle& aJITFrame); void StreamNonJITFrame(const FrameKey& aFrame); - void StreamJITFrame(const JS::ProfiledFrameHandle& aJITFrame); + void StreamJITFrame(JSContext* aContext, + const JS::ProfiledFrameHandle& aJITFrame); void StreamStack(const StackKey& aStack); public: UniqueJSONStrings mUniqueStrings; private: - JSContext* mContext; - // To avoid incurring JitcodeGlobalTable lookup costs for every JIT frame, // we cache the frame keys of frames keyed by JIT code address. All FrameKeys // in mAddressToJITFrameKeysMap are guaranteed to be in mFrameToIndexMap. diff --git a/tools/profiler/core/ThreadInfo.cpp b/tools/profiler/core/ThreadInfo.cpp index 98d61c44e2c9..8ed1b3d53b90 100644 --- a/tools/profiler/core/ThreadInfo.cpp +++ b/tools/profiler/core/ThreadInfo.cpp @@ -81,7 +81,7 @@ ThreadInfo::StreamJSON(const ProfileBuffer& aBuffer, UniquePtr uniqueStacks = partialProfile ? Move(partialProfile->mUniqueStacks) - : MakeUnique(mContext); + : MakeUnique(); UniquePtr partialSamplesJSON; UniquePtr partialMarkersJSON; @@ -247,7 +247,7 @@ ThreadInfo::FlushSamplesAndMarkers(const TimeStamp& aProcessStartTime, // mapping is stable across JS shutdown. UniquePtr uniqueStacks = mPartialProfile ? Move(mPartialProfile->mUniqueStacks) - : MakeUnique(mContext); + : MakeUnique(); UniquePtr samplesJSON; UniquePtr markersJSON;