tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit edc1a996fb42b1106098c9604a263285a247098c
parent 597a75d7a4231d5d85a3d0b55b0c7b4cec9b691f
Author: Nazım Can Altınova <canaltinova@gmail.com>
Date:   Wed, 26 Nov 2025 10:52:44 +0000

Bug 2002397 - Add CallStackFrameInfo struct for the JitcodeGlobalEntry::callStackAtAddr return values r=iain

Previously, we were returning multiple return arguments for the label
and sourceId return values. It's better to use a struct to return a
single argument with these values instead, so it'll be easier to extend
in the future.

I would like to add line/column information for the stack frames in the
later patches. That's why having this will be beneficial for that patch.

Differential Revision: https://phabricator.services.mozilla.com/D274056

Diffstat:
Mjs/public/ProfilingFrameIterator.h | 14++++++++++++--
Mjs/src/jit/JitcodeMap.cpp | 60++++++++++++++++++++++++------------------------------------
Mjs/src/jit/JitcodeMap.h | 25+++++++++++--------------
Mjs/src/vm/Stack.cpp | 11+++++------
4 files changed, 52 insertions(+), 58 deletions(-)

diff --git a/js/public/ProfilingFrameIterator.h b/js/public/ProfilingFrameIterator.h @@ -23,6 +23,17 @@ namespace jit { class JitActivation; class JSJitProfilingFrameIterator; class JitcodeGlobalEntry; + +// Information about a single frame in a JIT call stack, returned by +// JitcodeGlobalEntry::callStackAtAddr. +struct CallStackFrameInfo { + // The function name or label for this frame. + const char* label; + // The script source ID for this frame. Used to identify which script source + // this frame belongs to. + uint32_t sourceId; +}; + } // namespace jit namespace wasm { class ProfilingFrameIterator; @@ -295,8 +306,7 @@ class ProfiledFrameRange { void* addr_; js::jit::JitcodeGlobalEntry* entry_; // Assume maximum inlining depth is <64 - const char* labels_[64]; - uint32_t sourceIds_[64]; + js::jit::CallStackFrameInfo frames_[64]; uint32_t depth_; }; diff --git a/js/src/jit/JitcodeMap.cpp b/js/src/jit/JitcodeMap.cpp @@ -45,8 +45,7 @@ void* IonEntry::canonicalNativeAddrFor(void* ptr) const { return (void*)(((uint8_t*)nativeStartAddr()) + region.nativeOffset()); } -uint32_t IonEntry::callStackAtAddr(void* ptr, const char** labelResults, - uint32_t* sourceIdResults, +uint32_t IonEntry::callStackAtAddr(void* ptr, CallStackFrameInfo* results, uint32_t maxResults) const { MOZ_ASSERT(maxResults >= 1); @@ -62,8 +61,8 @@ uint32_t IonEntry::callStackAtAddr(void* ptr, const char** labelResults, locationIter.readNext(&scriptIdx, &pcOffset); MOZ_ASSERT(getStr(scriptIdx)); - labelResults[count] = getStr(scriptIdx); - sourceIdResults[count] = getScriptSource(scriptIdx).scriptSource->id(); + results[count].label = getStr(scriptIdx); + results[count].sourceId = getScriptSource(scriptIdx).scriptSource->id(); count++; if (count >= maxResults) { break; @@ -96,12 +95,10 @@ static IonEntry& IonEntryForIonIC(JSRuntime* rt, const IonICEntry* icEntry) { void* IonICEntry::canonicalNativeAddrFor(void* ptr) const { return ptr; } uint32_t IonICEntry::callStackAtAddr(JSRuntime* rt, void* ptr, - const char** labelResults, - uint32_t* sourceIdResults, + CallStackFrameInfo* results, uint32_t maxResults) const { const IonEntry& entry = IonEntryForIonIC(rt, this); - return entry.callStackAtAddr(rejoinAddr(), labelResults, sourceIdResults, - maxResults); + return entry.callStackAtAddr(rejoinAddr(), results, maxResults); } uint64_t IonICEntry::realmID(JSRuntime* rt) const { @@ -115,14 +112,13 @@ void* BaselineEntry::canonicalNativeAddrFor(void* ptr) const { return ptr; } -uint32_t BaselineEntry::callStackAtAddr(void* ptr, const char** labelResults, - uint32_t* sourceIdResults, +uint32_t BaselineEntry::callStackAtAddr(void* ptr, CallStackFrameInfo* results, uint32_t maxResults) const { MOZ_ASSERT(containsPointer(ptr)); MOZ_ASSERT(maxResults >= 1); - labelResults[0] = str(); - sourceIdResults[0] = scriptSource().scriptSource->id(); + results[0].label = str(); + results[0].sourceId = scriptSource().scriptSource->id(); return 1; } @@ -131,8 +127,7 @@ void* BaselineInterpreterEntry::canonicalNativeAddrFor(void* ptr) const { } uint32_t BaselineInterpreterEntry::callStackAtAddr(void* ptr, - const char** labelResults, - uint32_t* sourceIdResults, + CallStackFrameInfo* results, uint32_t maxResults) const { MOZ_CRASH("shouldn't be called for BaselineInterpreter entries"); } @@ -155,13 +150,12 @@ bool RealmIndependentSharedEntry::callStackAtAddr( } uint32_t RealmIndependentSharedEntry::callStackAtAddr( - void* ptr, const char** labelResults, uint32_t* sourceIdResults, - uint32_t maxResults) const { + void* ptr, CallStackFrameInfo* results, uint32_t maxResults) const { MOZ_ASSERT(containsPointer(ptr)); MOZ_ASSERT(maxResults >= 1); - labelResults[0] = str(); - sourceIdResults[0] = 0; + results[0].label = str(); + results[0].sourceId = 0; return 1; } @@ -337,28 +331,22 @@ bool JitcodeGlobalEntry::isJitcodeMarkedFromAnyThread(JSRuntime* rt) { } uint32_t JitcodeGlobalEntry::callStackAtAddr(JSRuntime* rt, void* ptr, - const char** labelResults, - uint32_t* sourceIdResults, + CallStackFrameInfo* results, uint32_t maxResults) const { switch (kind()) { case Kind::Ion: - return asIon().callStackAtAddr(ptr, labelResults, sourceIdResults, - maxResults); + return asIon().callStackAtAddr(ptr, results, maxResults); case Kind::IonIC: - return asIonIC().callStackAtAddr(rt, ptr, labelResults, sourceIdResults, - maxResults); + return asIonIC().callStackAtAddr(rt, ptr, results, maxResults); case Kind::Baseline: - return asBaseline().callStackAtAddr(ptr, labelResults, sourceIdResults, - maxResults); + return asBaseline().callStackAtAddr(ptr, results, maxResults); case Kind::BaselineInterpreter: - return asBaselineInterpreter().callStackAtAddr( - ptr, labelResults, sourceIdResults, maxResults); + return asBaselineInterpreter().callStackAtAddr(ptr, results, maxResults); case Kind::Dummy: - return asDummy().callStackAtAddr(rt, ptr, labelResults, sourceIdResults, - maxResults); + return asDummy().callStackAtAddr(rt, ptr, results, maxResults); case Kind::RealmIndependentShared: - return asRealmIndependentShared().callStackAtAddr( - ptr, labelResults, sourceIdResults, maxResults); + return asRealmIndependentShared().callStackAtAddr(ptr, results, + maxResults); } MOZ_CRASH("Invalid kind"); } @@ -1016,8 +1004,8 @@ JS_PUBLIC_API JS::ProfiledFrameRange JS::GetProfiledFrames(JSContext* cx, ProfiledFrameRange result(rt, addr, entry); if (entry) { - result.depth_ = entry->callStackAtAddr( - rt, addr, result.labels_, result.sourceIds_, std::size(result.labels_)); + result.depth_ = entry->callStackAtAddr(rt, addr, result.frames_, + std::size(result.frames_)); } return result; } @@ -1027,6 +1015,6 @@ JS::ProfiledFrameHandle JS::ProfiledFrameRange::Iter::operator*() const { // and the depth we need to pass to ProfiledFrameHandle goes down. uint32_t depth = range_.depth_ - 1 - index_; return ProfiledFrameHandle(range_.rt_, *range_.entry_, range_.addr_, - range_.labels_[depth], range_.sourceIds_[depth], - depth); + range_.frames_[depth].label, + range_.frames_[depth].sourceId, depth); } diff --git a/js/src/jit/JitcodeMap.h b/js/src/jit/JitcodeMap.h @@ -16,6 +16,7 @@ #include "jit/CompactBuffer.h" // CompactBufferReader, CompactBufferWriter #include "jit/shared/Assembler-shared.h" // CodeOffset #include "js/AllocPolicy.h" // SystemAllocPolicy +#include "js/ProfilingFrameIterator.h" // CallStackFrameInfo #include "js/TypeDecls.h" // jsbytecode #include "js/Vector.h" // Vector #include "vm/BytecodeLocation.h" // BytecodeLocation @@ -197,8 +198,8 @@ class JitcodeGlobalEntry : public JitCodeRange { // Read the inline call stack at a given point in the native code and append // into the given results buffer. Innermost script will be appended first, and // outermost appended last. - uint32_t callStackAtAddr(JSRuntime* rt, void* ptr, const char** labelResults, - uint32_t* sourceIdResults, + uint32_t callStackAtAddr(JSRuntime* rt, void* ptr, + CallStackFrameInfo* results, uint32_t maxResults) const; }; @@ -286,8 +287,7 @@ class IonEntry : public JitcodeGlobalEntry { void* canonicalNativeAddrFor(void* ptr) const; - uint32_t callStackAtAddr(void* ptr, const char** labelResults, - uint32_t* sourceIdResults, + uint32_t callStackAtAddr(void* ptr, CallStackFrameInfo* results, uint32_t maxResults) const; uint64_t realmID() const { return realmId_; } @@ -312,8 +312,8 @@ class IonICEntry : public JitcodeGlobalEntry { void* canonicalNativeAddrFor(void* ptr) const; - uint32_t callStackAtAddr(JSRuntime* rt, void* ptr, const char** labelResults, - uint32_t* sourceIdResults, + uint32_t callStackAtAddr(JSRuntime* rt, void* ptr, + CallStackFrameInfo* results, uint32_t maxResults) const; uint64_t realmID(JSRuntime* rt) const; @@ -343,8 +343,7 @@ class BaselineEntry : public JitcodeGlobalEntry { void* canonicalNativeAddrFor(void* ptr) const; - uint32_t callStackAtAddr(void* ptr, const char** labelResults, - uint32_t* sourceIdResults, + uint32_t callStackAtAddr(void* ptr, CallStackFrameInfo* results, uint32_t maxResults) const; uint64_t realmID() const { return realmId_; } @@ -371,8 +370,7 @@ class RealmIndependentSharedEntry : public JitcodeGlobalEntry { [[nodiscard]] bool callStackAtAddr(void* ptr, BytecodeLocationVector& results, uint32_t* depth) const; - uint32_t callStackAtAddr(void* ptr, const char** labelResults, - uint32_t* sourceIdResults, + uint32_t callStackAtAddr(void* ptr, CallStackFrameInfo* results, uint32_t maxResults) const; uint64_t realmID() const; @@ -387,8 +385,7 @@ class BaselineInterpreterEntry : public JitcodeGlobalEntry { void* canonicalNativeAddrFor(void* ptr) const; - uint32_t callStackAtAddr(void* ptr, const char** labelResults, - uint32_t* sourceIdResults, + uint32_t callStackAtAddr(void* ptr, CallStackFrameInfo* results, uint32_t maxResults) const; uint64_t realmID() const; @@ -406,8 +403,8 @@ class DummyEntry : public JitcodeGlobalEntry { return nullptr; } - uint32_t callStackAtAddr(JSRuntime* rt, void* ptr, const char** labelResults, - uint32_t* sourceIdResults, + uint32_t callStackAtAddr(JSRuntime* rt, void* ptr, + CallStackFrameInfo* results, uint32_t maxResults) const { return 0; } diff --git a/js/src/vm/Stack.cpp b/js/src/vm/Stack.cpp @@ -762,19 +762,18 @@ uint32_t JS::ProfilingFrameIterator::extractStack(Frame* frames, } // Extract the stack for the entry. Assume maximum inlining depth is <64 - const char* labels[64]; - uint32_t sourceIds[64]; + jit::CallStackFrameInfo frameInfos[64]; uint32_t depth = entry->callStackAtAddr(cx_->runtime(), jsJitIter().resumePCinCurrentFrame(), - labels, sourceIds, std::size(labels)); - MOZ_ASSERT(depth < std::size(labels)); + frameInfos, std::size(frameInfos)); + MOZ_ASSERT(depth < std::size(frameInfos)); for (uint32_t i = 0; i < depth; i++) { if (offset + i >= end) { return i; } frames[offset + i] = physicalFrame.value(); - frames[offset + i].label = labels[i]; - frames[offset + i].sourceId = sourceIds[i]; + frames[offset + i].label = frameInfos[i].label; + frames[offset + i].sourceId = frameInfos[i].sourceId; } return depth;