Skip to content

Commit fae652e

Browse files
authored
Merge branch 'main' into fix-compare-url-upgraders
2 parents 11b80cc + 3d5a1c1 commit fae652e

26 files changed

+1353
-843
lines changed

docs-developer/CHANGELOG-formats.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ Note that this is not an exhaustive list. Processed profile format upgraders can
66

77
## Processed profile format
88

9+
### Version 61
10+
11+
The `SourceTable` in `profile.shared.sources` was updated:
12+
13+
- The `uuid` field was renamed to `id`.
14+
- Two new fields `startLine` and `startColumn` were added (1-based). These describe the start position of the script within its resource, useful for inline scripts. If the source covers the entire file, use `(1, 1)`.
15+
- A new `sourceMapURL` field was added. Use `null` for entries with no source map URL.
16+
917
### Version 60
1018

1119
The following tables have moved into `profile.shared`: `stackTable`, `frameTable`, `funcTable`, `resourceTable`, `nativeSymbols`. They are no longer per-thread.
@@ -137,6 +145,14 @@ Older versions are not documented in this changelog but can be found in [process
137145

138146
## Gecko profile format
139147

148+
### Version 34
149+
150+
The `SourceTable` schema was updated:
151+
152+
- The `uuid` field was renamed to `id`.
153+
- Two new fields `startLine` and `startColumn` were added (1-based). If the source covers the entire file, use `(1, 1)`.
154+
- A new `sourceMapURL` field was added. It can be omitted if it is the last element in the row and there is no source map URL.
155+
140156
### Version 33
141157

142158
The `sources` field in the Gecko profile format is now non-optional. An upgrader was added that creates an empty `SourceTable` for profiles that don't have one.

package.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@
6161
},
6262
"dependencies": {
6363
"@codemirror/lang-cpp": "^6.0.3",
64-
"@codemirror/lang-javascript": "^6.2.4",
64+
"@codemirror/lang-javascript": "^6.2.5",
6565
"@codemirror/lang-rust": "^6.0.2",
66-
"@codemirror/language": "^6.12.1",
66+
"@codemirror/language": "^6.12.2",
6767
"@codemirror/state": "^6.5.4",
6868
"@codemirror/view": "^6.39.14",
6969
"@firefox-devtools/react-contextmenu": "^5.2.3",
@@ -118,15 +118,15 @@
118118
"@babel/preset-env": "^7.29.0",
119119
"@babel/preset-react": "^7.28.5",
120120
"@babel/preset-typescript": "^7.28.5",
121-
"@eslint/js": "^9.39.3",
121+
"@eslint/js": "^9.39.4",
122122
"@testing-library/dom": "^10.4.1",
123123
"@testing-library/jest-dom": "^6.9.1",
124124
"@testing-library/react": "^16.3.2",
125125
"@types/clamp": "^1.0.3",
126126
"@types/common-tags": "^1.8.4",
127127
"@types/jest": "^30.0.0",
128128
"@types/minimist": "^1.2.5",
129-
"@types/node": "^22.19.13",
129+
"@types/node": "^22.19.15",
130130
"@types/query-string": "^6.3.0",
131131
"@types/react": "^18.3.28",
132132
"@types/react-dom": "^18.3.1",
@@ -147,18 +147,18 @@
147147
"esbuild": "^0.27.0",
148148
"esbuild-plugin-copy": "^2.1.1",
149149
"esbuild-plugin-wasm": "^1.1.0",
150-
"eslint": "^9.39.3",
150+
"eslint": "^9.39.4",
151151
"eslint-config-prettier": "^10.1.8",
152152
"eslint-import-resolver-alias": "^1.1.2",
153153
"eslint-plugin-import": "^2.32.0",
154-
"eslint-plugin-jest": "^29.13.0",
154+
"eslint-plugin-jest": "^29.15.0",
155155
"eslint-plugin-jest-dom": "^5.5.0",
156156
"eslint-plugin-jest-formatting": "^3.1.0",
157157
"eslint-plugin-react": "^7.37.5",
158158
"eslint-plugin-testing-library": "^7.16.0",
159159
"fake-indexeddb": "^6.2.5",
160160
"fetch-mock": "^12.6.0",
161-
"globals": "^17.3.0",
161+
"globals": "^17.4.0",
162162
"husky": "^4.3.8",
163163
"jest": "^30.2.0",
164164
"jest-environment-jsdom": "^30.2.0",
@@ -169,7 +169,7 @@
169169
"npm-run-all2": "^8.0.4",
170170
"open": "^11.0.0",
171171
"patch-package": "^8.0.1",
172-
"postcss": "^8.5.6",
172+
"postcss": "^8.5.8",
173173
"postinstall-postinstall": "^2.1.0",
174174
"prettier": "^3.8.1",
175175
"rimraf": "^6.1.3",

src/app-logic/constants.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ import type { MarkerPhase } from 'firefox-profiler/types';
77
// The current version of the Gecko profile format.
88
// Please don't forget to update the gecko profile format changelog in
99
// `docs-developer/CHANGELOG-formats.md`.
10-
export const GECKO_PROFILE_VERSION = 33;
10+
export const GECKO_PROFILE_VERSION = 34;
1111

1212
// The current version of the "processed" profile format.
1313
// Please don't forget to update the processed profile format changelog in
1414
// `docs-developer/CHANGELOG-formats.md`.
15-
export const PROCESSED_PROFILE_VERSION = 60;
15+
export const PROCESSED_PROFILE_VERSION = 61;
1616

1717
// The following are the margin sizes for the left and right of the timeline. Independent
1818
// components need to share these values.

src/components/app/SourceCodeFetcher.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
getSymbolServerUrl,
1212
getSourceViewFile,
1313
getSourceViewSourceIndex,
14-
getSourceViewSourceUuid,
14+
getSourceViewSourceId,
1515
} from 'firefox-profiler/selectors';
1616
import {
1717
beginLoadingSourceCodeFromUrl,
@@ -36,7 +36,7 @@ import type {
3636
type StateProps = {
3737
readonly sourceViewFile: string | null;
3838
readonly sourceViewSourceIndex: IndexIntoSourceTable | null;
39-
readonly sourceViewSourceUuid: string | null;
39+
readonly sourceViewSourceId: string | null;
4040
readonly sourceViewCode: SourceCodeStatus | void;
4141
readonly symbolServerUrl: string;
4242
readonly profile: Profile | null;
@@ -68,7 +68,7 @@ class SourceCodeFetcherImpl extends React.PureComponent<Props> {
6868
sourceViewSourceIndex,
6969
sourceViewCode,
7070
sourceViewFile,
71-
sourceViewSourceUuid,
71+
sourceViewSourceId,
7272
beginLoadingSourceCodeFromUrl,
7373
beginLoadingSourceCodeFromBrowserConnection,
7474
finishLoadingSourceCode,
@@ -105,7 +105,7 @@ class SourceCodeFetcherImpl extends React.PureComponent<Props> {
105105

106106
const fetchSourceResult = await fetchSource(
107107
sourceViewFile,
108-
sourceViewSourceUuid,
108+
sourceViewSourceId,
109109
symbolServerUrl,
110110
addressProof,
111111
this._archiveCache,
@@ -137,7 +137,7 @@ export const SourceCodeFetcher = explicitConnect<{}, StateProps, DispatchProps>(
137137
mapStateToProps: (state) => ({
138138
sourceViewSourceIndex: getSourceViewSourceIndex(state),
139139
sourceViewFile: getSourceViewFile(state),
140-
sourceViewSourceUuid: getSourceViewSourceUuid(state),
140+
sourceViewSourceId: getSourceViewSourceId(state),
141141
sourceViewCode: getSourceViewCode(state),
142142
symbolServerUrl: getSymbolServerUrl(state),
143143
profile: getProfileOrNull(state),

src/profile-logic/data-structures.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,11 @@ export function getEmptySourceTable(): SourceTable {
348348
// If modifying this structure, please update all callers of this function to ensure
349349
// that they are pushing on correctly to the data structure. These pushes may not
350350
// be caught by the type system.
351-
uuid: [],
351+
id: [],
352352
filename: [],
353+
startLine: [],
354+
startColumn: [],
355+
sourceMapURL: [],
353356
length: 0,
354357
};
355358
}

src/profile-logic/gecko-profile-versioning.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,6 +1522,41 @@ const _upgraders: {
15221522
convertToVersion33Recursive(profile);
15231523
},
15241524

1525+
[34]: (profile: any) => {
1526+
// The source table schema was updated:
1527+
// - The "uuid" field was renamed to "id".
1528+
// - startLine and startColumn were added, defaulting to 1 as they are 1-based.
1529+
// - sourceMapURL was added, defaulting to null.
1530+
function convertToVersion34Recursive(p: any) {
1531+
if (p.sources) {
1532+
const schema = p.sources.schema;
1533+
1534+
schema.id = schema.uuid;
1535+
delete schema.uuid;
1536+
1537+
// Set the source table schema indices for the new required fields.
1538+
// These indices specify which array position corresponds to each value.
1539+
// Then fill the arrays with default values.
1540+
// See the GeckoSourceTable type in src/types/gecko-profile.ts to see
1541+
// these values.
1542+
schema.startLine = 2;
1543+
schema.startColumn = 3;
1544+
schema.sourceMapURL = 4;
1545+
1546+
for (const row of p.sources.data) {
1547+
row[2] = 1;
1548+
row[3] = 1;
1549+
row[4] = null;
1550+
}
1551+
}
1552+
1553+
for (const subprocessProfile of p.processes) {
1554+
convertToVersion34Recursive(subprocessProfile);
1555+
}
1556+
}
1557+
convertToVersion34Recursive(profile);
1558+
},
1559+
15251560
// If you add a new upgrader here, please document the change in
15261561
// `docs-developer/CHANGELOG-formats.md`.
15271562
};

src/profile-logic/global-data-collector.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export class GlobalDataCollector {
6161
_libNameToResourceIndex: Map<IndexIntoStringTable, IndexIntoResourceTable> =
6262
new Map();
6363
_originToResourceIndex: Map<string, IndexIntoResourceTable> = new Map();
64-
_uuidToSourceIndex: Map<string, IndexIntoSourceTable> = new Map();
64+
_idToSourceIndex: Map<string, IndexIntoSourceTable> = new Map();
6565
_filenameToSourceIndex: Map<IndexIntoStringTable, IndexIntoSourceTable> =
6666
new Map();
6767

@@ -115,26 +115,39 @@ export class GlobalDataCollector {
115115

116116
// Return the global index for this source, adding it to the global list if
117117
// necessary.
118-
indexForSource(uuid: string | null, filename: string): IndexIntoSourceTable {
118+
indexForSource(
119+
id: string | null,
120+
filename: string,
121+
startLine: number = 1,
122+
startColumn: number = 1,
123+
sourceMapURL: string | null = null
124+
): IndexIntoSourceTable {
119125
let index: IndexIntoSourceTable | undefined;
120126

121-
if (uuid !== null) {
122-
index = this._uuidToSourceIndex.get(uuid);
127+
if (id !== null) {
128+
index = this._idToSourceIndex.get(id);
123129
} else {
124-
// For null UUIDs, use filename-based lookup
130+
// For null IDs, use filename-based lookup.
125131
const filenameIndex = this._stringTable.indexForString(filename);
126132
index = this._filenameToSourceIndex.get(filenameIndex);
127133
}
128134

129135
if (index === undefined) {
130136
index = this._sources.length;
131137
const filenameIndex = this._stringTable.indexForString(filename);
132-
this._sources.uuid[index] = uuid;
138+
const sourceMapURLIndex =
139+
sourceMapURL !== null
140+
? this._stringTable.indexForString(sourceMapURL)
141+
: null;
142+
this._sources.id[index] = id;
133143
this._sources.filename[index] = filenameIndex;
144+
this._sources.startLine[index] = startLine;
145+
this._sources.startColumn[index] = startColumn;
146+
this._sources.sourceMapURL[index] = sourceMapURLIndex;
134147
this._sources.length++;
135148

136-
if (uuid !== null) {
137-
this._uuidToSourceIndex.set(uuid, index);
149+
if (id !== null) {
150+
this._idToSourceIndex.set(id, index);
138151
} else {
139152
this._filenameToSourceIndex.set(filenameIndex, index);
140153
}

src/profile-logic/merge-compare.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -556,17 +556,26 @@ function mergeSources(
556556
const oldStringToNewStringPlusOne = translationMapsForStrings[profileIndex];
557557

558558
for (let i = 0; i < sources.length; i++) {
559-
const uuid = sources.uuid[i];
559+
const id = sources.id[i];
560560
const originalUrlIndex = sources.filename[i];
561561
const newUrlIndex = oldStringToNewStringPlusOne[originalUrlIndex] - 1;
562562

563-
const sourceKey = uuid ?? `null-uuid-${newUrlIndex}`;
563+
const originalSourceMapURLIndex = sources.sourceMapURL[i];
564+
const newSourceMapURLIndex =
565+
originalSourceMapURLIndex !== null
566+
? oldStringToNewStringPlusOne[originalSourceMapURLIndex] - 1
567+
: null;
568+
569+
const sourceKey = id ?? `null-id-${newUrlIndex}`;
564570
let insertedSourceIndex = mapOfInsertedSources.get(sourceKey);
565571
if (insertedSourceIndex === undefined) {
566572
// Add new source
567573
insertedSourceIndex = newSources.length;
568-
newSources.uuid[insertedSourceIndex] = uuid;
574+
newSources.id[insertedSourceIndex] = id;
569575
newSources.filename[insertedSourceIndex] = newUrlIndex;
576+
newSources.startLine[insertedSourceIndex] = sources.startLine[i];
577+
newSources.startColumn[insertedSourceIndex] = sources.startColumn[i];
578+
newSources.sourceMapURL[insertedSourceIndex] = newSourceMapURLIndex;
570579
newSources.length++;
571580
mapOfInsertedSources.set(sourceKey, insertedSourceIndex);
572581
}

src/profile-logic/process-profile.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -431,13 +431,27 @@ function _extractJsFunction(
431431
let processedSourceIndex = null;
432432
if (sourceIndex !== undefined) {
433433
const geckoSourceIdx = parseInt(sourceIndex, 10);
434-
// Look up the UUID for this source index from the process's sources table
434+
// Look up the ID for this source index from the process's sources table.
435435
if (geckoSourceIdx < geckoSourceTable.data.length) {
436-
const uuidIndex = geckoSourceTable.schema.uuid;
436+
const idIndex = geckoSourceTable.schema.id;
437437
const filenameIndex = geckoSourceTable.schema.filename;
438-
const uuid = geckoSourceTable.data[geckoSourceIdx][uuidIndex];
438+
const startLineIndex = geckoSourceTable.schema.startLine;
439+
const startColumnIndex = geckoSourceTable.schema.startColumn;
440+
const sourceMapURLIndex = geckoSourceTable.schema.sourceMapURL;
441+
const id = geckoSourceTable.data[geckoSourceIdx][idIndex];
439442
const filename = geckoSourceTable.data[geckoSourceIdx][filenameIndex];
440-
processedSourceIndex = globalDataCollector.indexForSource(uuid, filename);
443+
const startLine = geckoSourceTable.data[geckoSourceIdx][startLineIndex];
444+
const startColumn =
445+
geckoSourceTable.data[geckoSourceIdx][startColumnIndex];
446+
const sourceMapURL =
447+
geckoSourceTable.data[geckoSourceIdx][sourceMapURLIndex];
448+
processedSourceIndex = globalDataCollector.indexForSource(
449+
id,
450+
filename,
451+
startLine,
452+
startColumn,
453+
sourceMapURL
454+
);
441455
}
442456
}
443457

src/profile-logic/processed-profile-versioning.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2663,7 +2663,7 @@ const _upgraders: {
26632663
// Create the sources table
26642664
const sourceTable = {
26652665
length: 0,
2666-
uuid: [] as Array<string | null>,
2666+
id: [] as Array<string | null>,
26672667
filename: [] as Array<number>,
26682668
};
26692669

@@ -2690,7 +2690,7 @@ const _upgraders: {
26902690
if (sourceIndex === undefined) {
26912691
// Add new entry to sources table
26922692
sourceIndex = sourceTable.length;
2693-
sourceTable.uuid.push(null);
2693+
sourceTable.id.push(null);
26942694
sourceTable.filename.push(fileNameIndex);
26952695
sourceTable.length++;
26962696
fileNameIndexToSourceIndex.set(fileNameIndex, sourceIndex);
@@ -3029,6 +3029,26 @@ const _upgraders: {
30293029
profile.shared.nativeSymbols = newNativeSymbols;
30303030
upgradeInfo.v60 = { threadMappings, newFuncCount: newFuncTable.length };
30313031
},
3032+
3033+
[61]: (profile: any) => {
3034+
// The source table schema was updated:
3035+
// - The "uuid" field was renamed to "id". Profiles stored at v58-60 before
3036+
// this rename may still have the old "uuid" field name.
3037+
// - startLine and startColumn were added, defaulting to 1 as they are 1-based.
3038+
// - sourceMapURL was added, defaulting to null.
3039+
const sources = profile.shared && profile.shared.sources;
3040+
if (sources) {
3041+
if (sources.uuid !== undefined && sources.id === undefined) {
3042+
sources.id = sources.uuid;
3043+
delete sources.uuid;
3044+
}
3045+
const length = sources.length;
3046+
sources.startLine = new Array(length).fill(1);
3047+
sources.startColumn = new Array(length).fill(1);
3048+
sources.sourceMapURL = new Array(length).fill(null);
3049+
}
3050+
},
3051+
30323052
// If you add a new upgrader here, please document the change in
30333053
// `docs-developer/CHANGELOG-formats.md`.
30343054
};

0 commit comments

Comments
 (0)