From 812a4bd4c1c149577a1cd4dc00375634e928ed56 Mon Sep 17 00:00:00 2001 From: nirmaladvani Date: Sun, 26 Jul 2026 12:51:46 +0500 Subject: [PATCH] remove unused collectSourceIndicesFromThreads #6086 --- src/profile-logic/profile-data.ts | 65 -------- src/test/unit/profile-data.test.ts | 243 ----------------------------- 2 files changed, 308 deletions(-) diff --git a/src/profile-logic/profile-data.ts b/src/profile-logic/profile-data.ts index fd210b62ca..b5401f17f6 100644 --- a/src/profile-logic/profile-data.ts +++ b/src/profile-logic/profile-data.ts @@ -4108,71 +4108,6 @@ export function _gatherSingleThreadStackReferences( } } -/** - * Collect all source table indices referenced by the given threads. - * Walks samples, jsAllocations, and nativeAllocations, following stack prefix - * chains. Includes both compiled sources (funcTable.source) and - * post-symbolication original sources (via sourceLocationTable). - */ -export function collectSourceIndicesFromThreads( - threadIndexes: Iterable, - threads: RawThread[], - shared: RawProfileSharedData -): Set { - const { stackTable, frameTable, funcTable, sourceLocationTable } = shared; - const sourceIndices = new Set(); - const visitedStacks = makeBitSet(stackTable.length); - - const addStackChain = (stackIndex: IndexIntoStackTable | null) => { - let current = stackIndex; - while (current !== null && !checkBit(visitedStacks, current)) { - setBit(visitedStacks, current); - const frameIndex = stackTable.frame[current]; - const funcIndex = frameTable.func[frameIndex]; - - const compiledSource = funcTable.source[funcIndex]; - if (compiledSource !== null) { - sourceIndices.add(compiledSource); - } - - const frameOriginalLocationIdx = frameTable.originalLocation[frameIndex]; - if (frameOriginalLocationIdx !== null) { - sourceIndices.add(sourceLocationTable.source[frameOriginalLocationIdx]); - } - - const funcOriginalLocationIdx = funcTable.originalLocation[funcIndex]; - if (funcOriginalLocationIdx !== null) { - sourceIndices.add(sourceLocationTable.source[funcOriginalLocationIdx]); - } - - const prefixOffset = stackTable.prefixOffset[current]; - current = prefixOffset !== 0 ? current - prefixOffset : null; - } - }; - - for (const threadIndex of threadIndexes) { - if (threadIndex >= threads.length) { - continue; - } - const thread = threads[threadIndex]; - for (const s of thread.samples.stack) { - addStackChain(s); - } - if (thread.jsAllocations !== undefined) { - for (const s of thread.jsAllocations.stack) { - addStackChain(s); - } - } - if (thread.nativeAllocations !== undefined) { - for (const s of thread.nativeAllocations.stack) { - addStackChain(s); - } - } - } - - return sourceIndices; -} - /** * Creates a new thread with modified frame and stack tables for "nudged" return addresses: * All return addresses are moved backwards by one byte, to point into the "call" diff --git a/src/test/unit/profile-data.test.ts b/src/test/unit/profile-data.test.ts index 206e8a07b6..37dc87cc83 100644 --- a/src/test/unit/profile-data.test.ts +++ b/src/test/unit/profile-data.test.ts @@ -28,7 +28,6 @@ import { computeTimeColumnForRawSamplesTable, getCallNodeFramePerStack, getTotalNativeSymbolTimingsForCallNode, - collectSourceIndicesFromThreads, } from '../../profile-logic/profile-data'; import { createGeckoProfile, @@ -1845,245 +1844,3 @@ describe('getBacktraceItemsForStack', function () { `); }); }); - -describe('collectSourceIndicesFromThreads', function () { - // Helper to find a source index by filename string. - function sourceIndexForFile( - profile: Profile, - fileName: string - ): IndexIntoSourceTable { - const { sources, stringArray } = profile.shared; - for (let i = 0; i < sources.length; i++) { - if (stringArray[sources.filename[i]] === fileName) { - return i; - } - } - throw new Error(`No source for ${fileName}`); - } - - // Helper to append a new entry to sourceLocationTable and return its index. - function addOriginalLocation( - profile: Profile, - source: IndexIntoSourceTable, - line: number, - column: number - ): number { - const { sourceLocationTable } = profile.shared; - const idx = sourceLocationTable.length; - sourceLocationTable.source.push(source); - sourceLocationTable.line.push(line); - sourceLocationTable.column.push(column); - sourceLocationTable.length++; - return idx; - } - - // Helper to add an "original" source that has no compiled-side references. - function addOriginalSource(profile: Profile, fileName: string): number { - const { sources, stringArray } = profile.shared; - const filenameIdx = stringArray.length; - stringArray.push(fileName); - const idx = sources.length; - sources.id.push(null); - sources.filename.push(filenameIdx); - sources.startLine.push(1); - sources.startColumn.push(1); - sources.sourceMapURL.push(null); - sources.content.push(null); - sources.length++; - return idx; - } - - it('collects compiled sources only from the requested threads', function () { - const { profile } = getProfileFromTextSamples( - ` - A[file:a.js] - B[file:b.js] - `, - ` - C[file:c.js] - D[file:d.js] - `, - ` - E[file:e.js] - ` - ); - - const aJs = sourceIndexForFile(profile, 'a.js'); - const bJs = sourceIndexForFile(profile, 'b.js'); - const cJs = sourceIndexForFile(profile, 'c.js'); - const dJs = sourceIndexForFile(profile, 'd.js'); - const eJs = sourceIndexForFile(profile, 'e.js'); - - expect( - collectSourceIndicesFromThreads([0], profile.threads, profile.shared) - ).toEqual(new Set([aJs, bJs])); - expect( - collectSourceIndicesFromThreads([1], profile.threads, profile.shared) - ).toEqual(new Set([cJs, dJs])); - expect( - collectSourceIndicesFromThreads([0, 2], profile.threads, profile.shared) - ).toEqual(new Set([aJs, bJs, eJs])); - }); - - it('walks the full stack chain via the prefix pointer', function () { - // Top-of-stack is "C", but A and B are in the prefix chain. All three - // must be collected even though only the top frame is referenced from - // samples.stack. - const { profile } = getProfileFromTextSamples(` - A[file:a.js] - B[file:b.js] - C[file:c.js] - `); - - const result = collectSourceIndicesFromThreads( - [0], - profile.threads, - profile.shared - ); - - expect(result).toEqual( - new Set([ - sourceIndexForFile(profile, 'a.js'), - sourceIndexForFile(profile, 'b.js'), - sourceIndexForFile(profile, 'c.js'), - ]) - ); - }); - - it('includes both frame originalLocation and func originalLocation entries', function () { - const { profile } = getProfileFromTextSamples(` - A[file:bundle.js] - B[file:bundle.js] - `); - - const bundle = sourceIndexForFile(profile, 'bundle.js'); - const originalA = addOriginalSource(profile, 'original-a.ts'); - const originalB = addOriginalSource(profile, 'original-b.ts'); - const originalBInline = addOriginalSource(profile, 'inlined.ts'); - - // Func A is mapped to original-a.ts. - const funcA = profile.shared.funcTable.name.findIndex( - (n) => profile.shared.stringArray[n] === 'A' - ); - profile.shared.funcTable.originalLocation[funcA] = addOriginalLocation( - profile, - originalA, - 10, - 1 - ); - - // Func B is mapped to original-b.ts, but one of its frames is inlined - // from inlined.ts (frame originalLocation differs from func originalLocation). - const funcB = profile.shared.funcTable.name.findIndex( - (n) => profile.shared.stringArray[n] === 'B' - ); - profile.shared.funcTable.originalLocation[funcB] = addOriginalLocation( - profile, - originalB, - 20, - 1 - ); - const frameB = profile.shared.frameTable.func.findIndex((f) => f === funcB); - profile.shared.frameTable.originalLocation[frameB] = addOriginalLocation( - profile, - originalBInline, - 5, - 2 - ); - - const result = collectSourceIndicesFromThreads( - [0], - profile.threads, - profile.shared - ); - - expect(result).toEqual( - new Set([bundle, originalA, originalB, originalBInline]) - ); - }); - - it('skips threadIndex values that are out of range', function () { - const { profile } = getProfileFromTextSamples(` - A[file:a.js] - `); - const aJs = sourceIndexForFile(profile, 'a.js'); - - expect( - collectSourceIndicesFromThreads( - [0, 5, 99], - profile.threads, - profile.shared - ) - ).toEqual(new Set([aJs])); - }); - - it('includes sources reached via jsAllocations and nativeAllocations stacks', function () { - const { profile } = getProfileFromTextSamples( - // Samples have one source... - ` - A[file:samples.js] - `, - // ...and the other thread has two unrelated stacks we'll re-attach as - // allocation stacks below. - ` - B[file:alloc-js.js] - C[file:alloc-native.js] - ` - ); - - const samplesJs = sourceIndexForFile(profile, 'samples.js'); - const allocJs = sourceIndexForFile(profile, 'alloc-js.js'); - const allocNative = sourceIndexForFile(profile, 'alloc-native.js'); - - // Grab two distinct stack indices from thread 1 to use as the allocation - // sample stacks for thread 0. - const thread1 = profile.threads[1]; - const allocJsStack = thread1.samples.stack[0]; // top frame = B (alloc-js.js) - // For the native one, walk to a stack whose top is C. - const { stackTable, frameTable, funcTable, stringArray } = profile.shared; - const cFunc = funcTable.name.findIndex((n) => stringArray[n] === 'C'); - let allocNativeStack: number | null = null; - for (let i = 0; i < stackTable.length; i++) { - if (funcTable.source[frameTable.func[stackTable.frame[i]]] !== null) { - if (frameTable.func[stackTable.frame[i]] === cFunc) { - allocNativeStack = i; - break; - } - } - } - if (allocNativeStack === null) { - throw new Error('Could not find a stack for func C'); - } - - profile.threads[0].jsAllocations = { - time: [0], - className: [0], - typeName: [0], - coarseType: [0], - weight: [1], - weightType: 'bytes', - inNursery: [false], - stack: [allocJsStack], - length: 1, - } as any; - profile.threads[0].nativeAllocations = { - time: [0], - weight: [1], - weightType: 'bytes', - stack: [allocNativeStack], - length: 1, - } as any; - - // Only collecting from thread 0. But allocations point into thread 1's - // stacks, which live in the shared stack table. - const result = collectSourceIndicesFromThreads( - [0], - profile.threads, - profile.shared - ); - - expect(result.has(samplesJs)).toBe(true); - expect(result.has(allocJs)).toBe(true); - expect(result.has(allocNative)).toBe(true); - }); -});