tor-browser

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

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

Bug 1979114 - Collect the JS sources during profile serialization r=mstange,profiler-reviewers

Finally, we implement the place where we actually request the JS sources
from the JS engine to the profiler land.

We find the JSContext for the main thread just for being able to access
the GeckoProfilerRuntime in the JS engine. Sources are shared across
threads and JSContexts. Otherwise the JSContext is not used for other
things.

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

Diffstat:
Mtools/profiler/core/platform.cpp | 47+++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 45 insertions(+), 2 deletions(-)

diff --git a/tools/profiler/core/platform.cpp b/tools/profiler/core/platform.cpp @@ -49,6 +49,9 @@ #include "mozilla/Maybe.h" #include "mozilla/MozPromise.h" #include "mozilla/Perfetto.h" +#include "nsID.h" +#include "nsIDUtils.h" +#include "nsString.h" #include "nsCExternalHandlerService.h" #include "nsCOMPtr.h" #include "nsDebug.h" @@ -1597,6 +1600,44 @@ class ActivePS { return array; } + // Collect JS sources from the main thread, since script source storage is + // shared between all threads. + static nsTArray<mozilla::JSSourceEntry> GatherJSSources(PSLockRef aLock) { + nsTArray<mozilla::JSSourceEntry> jsSourceEntries; + if (!ProfilerFeature::HasJSSources(ActivePS::Features(aLock))) { + return jsSourceEntries; + } + + ThreadRegistry::LockedRegistry lockedRegistry; + ActivePS::ProfiledThreadList threads = + ActivePS::ProfiledThreads(lockedRegistry, aLock); + + // Get the JS context of the main thread. We don't need to get the + // JSContext of others because the script source storage is shared between + // threads. + auto* mainThread = + std::find_if(threads.begin(), threads.end(), [](const auto& thread) { + return thread.mProfiledThreadData->Info().IsMainThread(); + }); + + if (mainThread == threads.end() || !mainThread->mJSContext) { + return jsSourceEntries; + } + JSContext* jsContext = mainThread->mJSContext; + + js::ProfilerJSSources threadSources = + js::GetProfilerScriptSources(JS_GetRuntime(jsContext)); + + // Generate UUIDs and build mappings for each source + for (ProfilerJSSourceData& sourceData : threadSources) { + // Generate UUID for this source and store it in the global array. + jsSourceEntries.AppendElement(JSSourceEntry( + NSID_TrimBracketsASCII(nsID::GenerateUUID()), std::move(sourceData))); + } + + return jsSourceEntries; + } + static ProfiledThreadData* AddLiveProfiledThread( PSLockRef, UniquePtr<ProfiledThreadData>&& aProfiledThreadData) { MOZ_ASSERT(sInstance); @@ -3828,8 +3869,10 @@ locked_profiler_stream_json_for_this_process( } SLOW_DOWN_FOR_TESTING(); - // FIXME: Build the JS sources - nsTArray<mozilla::JSSourceEntry> jsSourceEntries; + // Collect JS sources from the main thread, since script source storage is + // shared between all threads. + nsTArray<mozilla::JSSourceEntry> jsSourceEntries = + ActivePS::GatherJSSources(aLock); // Lists the samples for each thread profile aWriter.StartArrayProperty("threads");