tor-browser

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

commit 6aa12707844be7bb5b4dd76f1774b5d19ac35e1e
parent 477afbe49a7133e97af0a73f21a99a0a77ebfbc5
Author: Nazım Can Altınova <canaltinova@gmail.com>
Date:   Fri, 28 Nov 2025 09:42:33 +0000

Bug 2002825 - Add a test for the sourceId of JIT frames inside marker stacks r=mstange,profiler-reviewers

This test checks if we have sourceIds in the JIT frame of testFunction
when they are captured from markers. Previously, we were incorrectly
not collecting the sourceId if the samples are collected for the marker
stacks. Now, we properly collect them.

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

Diffstat:
Atools/profiler/tests/xpcshell/test_marker_jit_sourceindex.js | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtools/profiler/tests/xpcshell/xpcshell.toml | 2++
2 files changed, 99 insertions(+), 0 deletions(-)

diff --git a/tools/profiler/tests/xpcshell/test_marker_jit_sourceindex.js b/tools/profiler/tests/xpcshell/test_marker_jit_sourceindex.js @@ -0,0 +1,97 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Check if the JIT frames inside marker stacks contain source information. +add_task(async () => { + const entries = 10000; + const interval = 1; + const threads = ["GeckoMain"]; + // We need the jssources feature for sourceId to be included in the profile. + const features = ["js", "nostacksampling", "jssources"]; + + await Services.profiler.StartProfiler(entries, interval, features, threads); + + const markerName = "TestMarkerWithJITFrames"; + + function testFunction(last) { + if (last) { + ChromeUtils.addProfilerMarker(markerName, { captureStack: true }); + } + return Math.sqrt(Math.random() * 100); + } + + // Make sure that it gets JIT compiled. + const iterCount = 1000; + for (let i = 0; i < iterCount; i++) { + testFunction(i === iterCount - 1); + } + + const profile = await ProfilerTestUtils.stopNowAndGetProfile(); + const mainThread = profile.threads.find(({ name }) => name === "GeckoMain"); + + const markers = ProfilerTestUtils.getInflatedMarkerData(mainThread).filter( + m => m.name === markerName + ); + + Assert.equal( + markers.length, + 1, + "Should find exactly one marker with the test name" + ); + + const marker = markers[0]; + Assert.ok(marker.data, "Marker should have data"); + Assert.ok(marker.data.stack, "Marker should have a stack"); + + const stack = marker.data.stack; + Assert.ok(stack.samples, "Marker stack should have samples"); + Assert.ok(stack.samples.data, "Marker stack samples should have data"); + + const stackIndex = stack.samples.data[0][stack.samples.schema.stack]; + Assert.notEqual(stackIndex, null, "Should have a valid stack index"); + + const stackPrefixCol = mainThread.stackTable.schema.prefix; + const stackFrameCol = mainThread.stackTable.schema.frame; + const frameLocationCol = mainThread.frameTable.schema.location; + const sourceUuidCol = profile.sources.schema.uuid; + + let foundJITFrame = false; + let currentStackIndex = stackIndex; + + while (currentStackIndex !== null) { + const stack = mainThread.stackTable.data[currentStackIndex]; + const frameIndex = stack[stackFrameCol]; + const frame = mainThread.frameTable.data[frameIndex]; + const location = mainThread.stringTable[frame[frameLocationCol]]; + + if (location.includes("testFunction")) { + foundJITFrame = true; + + // sourceIndex is included in the location string, inside brackets. + const sourceIndexMatch = location.match(/\[(\d+)\]/); + Assert.ok(sourceIndexMatch, "JIT frame should have a sourceIndex"); + + const sourceIndex = Number(sourceIndexMatch[1]); + const source = profile.sources.data[sourceIndex]; + Assert.ok( + source, + "Source index should correspond to a valid source entry" + ); + + const sourceUuid = source[sourceUuidCol]; + Assert.ok(sourceUuid, "JIT frame sourceUuid should be non-empty"); + info( + `Found JIT frame with sourceUuid: ${sourceUuid}, location: ${location}` + ); + break; + } + + currentStackIndex = stack[stackPrefixCol]; + } + + Assert.ok( + foundJITFrame, + "Should find at least one JIT frame with 'testFunction' in the marker stack" + ); +}); diff --git a/tools/profiler/tests/xpcshell/xpcshell.toml b/tools/profiler/tests/xpcshell/xpcshell.toml @@ -106,6 +106,8 @@ skip-if = [ ["test_get_features.js"] +["test_marker_jit_sourceindex.js"] + ["test_merged_stacks.js"] skip-if = [ "asan",