tor-browser

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

commit 0d00dcebfc31aec0a6b157700029528ba2806b97
parent 821c617b840ccd2fee25fef090fcf6045e8e1f0f
Author: Nazım Can Altınova <canaltinova@gmail.com>
Date:   Tue, 21 Oct 2025 21:15:35 +0000

Bug 1979114 - Stream SourceTable for each process r=mstange,profiler-reviewers

This table keeps [uuid, filename] mapping for each source, and each
location string will include the index into source table for the
individual source for the JS frames.

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

Diffstat:
Mtools/profiler/core/ProfileBuffer.h | 9+++++++++
Mtools/profiler/core/ProfileBufferEntry.cpp | 48++++++++++++++++++++++++++++++++++++++++++++++++
Mtools/profiler/core/ProfileBufferEntry.h | 5+++++
Mtools/profiler/core/platform.cpp | 8++++++++
4 files changed, 70 insertions(+), 0 deletions(-)

diff --git a/tools/profiler/core/ProfileBuffer.h b/tools/profiler/core/ProfileBuffer.h @@ -13,10 +13,13 @@ #include "mozilla/PowerOfTwo.h" #include "mozilla/ProfileBufferChunkManagerSingle.h" #include "mozilla/ProfileChunkedBuffer.h" +#include "nsTHashMap.h" class ProcessStreamingContext; class RunningTimes; +struct ProfilerJSSourceData; + // Class storing most profiling data in a ProfileChunkedBuffer. // // This class is used as a queue of entries which, after construction, never @@ -96,6 +99,12 @@ class ProfileBuffer final { double aSinceTime, mozilla::ProgressLogger aProgressLogger) const; + // Stream JavaScript source table to JSON and return mapping from sourceId + // to index into source table. + nsTHashMap<SourceId, IndexIntoSourceTable> StreamSourceTableToJSON( + SpliceableJSONWriter& aWriter, + const nsTArray<mozilla::JSSourceEntry>& aJSSourceEntries) const; + // Find (via |aLastSample|) the most recent sample for the thread denoted by // |aThreadId| and clone it, patching in the current time as appropriate. // Mutate |aLastSample| to point to the newly inserted sample. diff --git a/tools/profiler/core/ProfileBufferEntry.cpp b/tools/profiler/core/ProfileBufferEntry.cpp @@ -2512,5 +2512,53 @@ void ProfileBuffer::DiscardSamplesBeforeTime(double aTime) { (void)aTime; } +nsTHashMap<SourceId, IndexIntoSourceTable> +ProfileBuffer::StreamSourceTableToJSON( + SpliceableJSONWriter& aWriter, + const nsTArray<mozilla::JSSourceEntry>& aJSSourceEntries) const { + enum Schema : uint32_t { UUID = 0, FILENAME = 1 }; + nsTHashMap<SourceId, IndexIntoSourceTable> sourceIdToIndexMap; + + aWriter.StartObjectProperty("sources"); + { + // Write the schema + { + JSONSchemaWriter schema(aWriter); + schema.WriteField("uuid"); + schema.WriteField("filename"); + } + + // Write data array and build sourceId-to-index mapping + aWriter.StartArrayProperty("data"); + uint32_t index = 0; + for (const auto& entry : aJSSourceEntries) { + // Build sourceId-to-index mapping + if (entry.sourceData.sourceId() != 0) { + MOZ_ASSERT(!sourceIdToIndexMap.Contains(entry.sourceData.sourceId()), + "Duplicate sourceId detected! This indicates sourceId " + "collision between different sources."); + sourceIdToIndexMap.InsertOrUpdate(entry.sourceData.sourceId(), index); + } + + // Write [uuid, filename] entry + aWriter.StartArrayElement(); + { + // TODO: Use AutoArraySchemaWithStringsWriter to write string indexes + // into string table once we have "process global" string table. + // Currently string tables are per-thread. + aWriter.StringElement(MakeStringSpan(entry.uuid.get())); + aWriter.StringElement(MakeStringSpan(entry.sourceData.filePath())); + } + aWriter.EndArray(); + + index++; + } + aWriter.EndArray(); + } + aWriter.EndObject(); + + return sourceIdToIndexMap; +} + // END ProfileBuffer //////////////////////////////////////////////////////////////////////// diff --git a/tools/profiler/core/ProfileBufferEntry.h b/tools/profiler/core/ProfileBufferEntry.h @@ -29,6 +29,11 @@ class ProfilerCodeAddressService; struct JSContext; +// Typedef for process-global identifiers for JS script sources. +using SourceId = uint32_t; +// Typedef for indexes into the source table array. +using IndexIntoSourceTable = uint32_t; + class ProfileBufferEntry { public: using KindUnderlyingType = diff --git a/tools/profiler/core/platform.cpp b/tools/profiler/core/platform.cpp @@ -3874,6 +3874,14 @@ locked_profiler_stream_json_for_this_process( nsTArray<mozilla::JSSourceEntry> jsSourceEntries = ActivePS::GatherJSSources(aLock); + // If there are sources, stream the sources table that is shared between the + // threads, and get the UUID to index mappings needed for frame serialization. + Maybe<nsTHashMap<SourceId, IndexIntoSourceTable>> sourceIdToIndexMap; + if (!jsSourceEntries.IsEmpty()) { + sourceIdToIndexMap.emplace( + buffer.StreamSourceTableToJSON(aWriter, jsSourceEntries)); + } + // Lists the samples for each thread profile aWriter.StartArrayProperty("threads"); {