Skip to content

Commit 4fe7730

Browse files
authored
Add startLine, startColumn, sourceMapURL and rename uuid to id in source table (#5882)
The backend side of this PR: - https://bugzilla.mozilla.org/show_bug.cgi?id=1999953 - https://bugzilla.mozilla.org/show_bug.cgi?id=2016667 This PR improves the source table overall by: - Adding startLine and startColumn to the source table. This is going to be used for showing correct line numbers in the source view when the source is coming from an inline script. And also it will be useful for source map/prettify in the future. - Adding sourceMapURL if the source contains this information. This is needed for us implement the source map resolution. - Renaming `uuid` field to `id`. This field was initially containing uuid fields, but they were replaced to contain hashes instead. It's better to have an implementation agnostic name for this field in general.
2 parents 54536aa + 8f73bab commit 4fe7730

23 files changed

Lines changed: 787 additions & 143 deletions

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.

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
};

src/profile-logic/profile-compacting.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,11 @@ function _gatherReferencesInSources(
746746
}
747747

748748
referencedStrings[sources.filename[i]] = 1;
749+
750+
const sourceMapURL = sources.sourceMapURL[i];
751+
if (sourceMapURL !== null) {
752+
referencedStrings[sourceMapURL] = 1;
753+
}
749754
}
750755
}
751756

@@ -765,7 +770,18 @@ function _createCompactedSources(
765770
const newIndex = newSources.length++;
766771
newSources.filename[newIndex] =
767772
oldStringToNewStringPlusOne[sources.filename[i]] - 1;
768-
newSources.uuid[newIndex] = sources.uuid[i];
773+
newSources.id[newIndex] = sources.id[i];
774+
newSources.startLine[newIndex] = sources.startLine[i];
775+
newSources.startColumn[newIndex] = sources.startColumn[i];
776+
777+
// Translate the sourceMapURL string index if present.
778+
// The old string indexes are no longer valid since we compacted the
779+
// string array. All the indexes that reference them need to be updated.
780+
const oldSourceMapURLIndex = sources.sourceMapURL[i];
781+
newSources.sourceMapURL[newIndex] =
782+
oldSourceMapURLIndex !== null
783+
? oldStringToNewStringPlusOne[oldSourceMapURLIndex] - 1
784+
: null;
769785

770786
oldSourceToNewSourcePlusOne[i] = newIndex + 1;
771787
}

0 commit comments

Comments
 (0)