Skip to content

Commit f036db9

Browse files
committed
Share stringTable between threads.
1 parent 079db2c commit f036db9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+64191
-67664
lines changed

src/actions/receive-profile.js

+17-14
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ export function finalizeFullProfileView(
402402
const thread = profile.threads[threadIndex];
403403
const { samples, jsAllocations, nativeAllocations } = thread;
404404
hasSamples = [samples, jsAllocations, nativeAllocations].some((table) =>
405-
hasUsefulSamples(table?.stack, thread)
405+
hasUsefulSamples(table?.stack, thread, profile.shared)
406406
);
407407
if (hasSamples) {
408408
break;
@@ -798,20 +798,23 @@ export function bulkProcessSymbolicationSteps(
798798
symbolicationStepsPerThread: Map<ThreadIndex, SymbolicationStepInfo[]>
799799
): ThunkAction<void> {
800800
return (dispatch, getState) => {
801-
const { threads } = getProfile(getState());
801+
const profile = getProfile(getState());
802802
const oldFuncToNewFuncsMaps: Map<ThreadIndex, FuncToFuncsMap> = new Map();
803-
const symbolicatedThreads = threads.map((oldThread, threadIndex) => {
804-
const symbolicationSteps = symbolicationStepsPerThread.get(threadIndex);
805-
if (symbolicationSteps === undefined) {
806-
return oldThread;
803+
const symbolicatedThreads = profile.threads.map(
804+
(oldThread, threadIndex) => {
805+
const symbolicationSteps = symbolicationStepsPerThread.get(threadIndex);
806+
if (symbolicationSteps === undefined) {
807+
return oldThread;
808+
}
809+
const { thread, oldFuncToNewFuncsMap } = applySymbolicationSteps(
810+
oldThread,
811+
profile.shared,
812+
symbolicationSteps
813+
);
814+
oldFuncToNewFuncsMaps.set(threadIndex, oldFuncToNewFuncsMap);
815+
return thread;
807816
}
808-
const { thread, oldFuncToNewFuncsMap } = applySymbolicationSteps(
809-
oldThread,
810-
symbolicationSteps
811-
);
812-
oldFuncToNewFuncsMaps.set(threadIndex, oldFuncToNewFuncsMap);
813-
return thread;
814-
});
817+
);
815818
dispatch({
816819
type: 'BULK_SYMBOLICATION',
817820
oldFuncToNewFuncsMaps,
@@ -1904,7 +1907,7 @@ export function changeTabFilter(tabID: TabID | null): ThunkAction<void> {
19041907
const thread = profile.threads[threadIndex];
19051908
const { samples, jsAllocations, nativeAllocations } = thread;
19061909
hasSamples = [samples, jsAllocations, nativeAllocations].some((table) =>
1907-
hasUsefulSamples(table?.stack, thread)
1910+
hasUsefulSamples(table?.stack, thread, profile.shared)
19081911
);
19091912
if (hasSamples) {
19101913
break;

src/app-logic/constants.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export const GECKO_PROFILE_VERSION = 31;
1414
// The current version of the "processed" profile format.
1515
// Please don't forget to update the processed profile format changelog in
1616
// `docs-developer/CHANGELOG-formats.md`.
17-
export const PROCESSED_PROFILE_VERSION = 52;
17+
export const PROCESSED_PROFILE_VERSION = 53;
1818

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

src/components/js-tracer/Chart.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { JsTracerCanvas } from './Canvas';
1515
import {
1616
getCommittedRange,
1717
getPreviewSelection,
18+
getStringTable,
1819
} from 'firefox-profiler/selectors/profile';
1920
import { selectedThreadSelectors } from 'firefox-profiler/selectors/per-thread';
2021
import { getSelectedThreadsKey } from 'firefox-profiler/selectors/url-state';
@@ -136,7 +137,7 @@ const JsTracerExpensiveChart = explicitConnect<
136137
>({
137138
mapStateToProps: (state, ownProps) => ({
138139
timeRange: getCommittedRange(state),
139-
stringTable: selectedThreadSelectors.getStringTable(state),
140+
stringTable: getStringTable(state),
140141
threadsKey: getSelectedThreadsKey(state),
141142
previewSelection: getPreviewSelection(state),
142143
jsTracerTimingRows: ensureExists(

src/profile-logic/active-tab.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,15 @@ export function computeActiveTabTracks(
6666
const screenshots = [];
6767
const topmostInnerWindowIDs = getTopmostInnerWindowIDs(relevantPages);
6868
const innerWindowIDToPageMap = _getInnerWindowIDToPageMap(relevantPages);
69+
const { stringArray } = profile.shared;
6970

7071
for (
7172
let threadIndex = 0;
7273
threadIndex < profile.threads.length;
7374
threadIndex++
7475
) {
7576
const thread = profile.threads[threadIndex];
76-
const { markers, stringArray } = thread;
77+
const { markers } = thread;
7778

7879
if (thread.isMainThread) {
7980
// This is a main thread, there is a possibility that it can be a global

src/profile-logic/data-structures.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,6 @@ export function getEmptyThread(overrides?: $Shape<RawThread>): RawThread {
385385
markers: getEmptyRawMarkerTable(),
386386
stackTable: getEmptyRawStackTable(),
387387
frameTable: getEmptyFrameTable(),
388-
stringArray: [],
389388
funcTable: getEmptyFuncTable(),
390389
resourceTable: getEmptyResourceTable(),
391390
nativeSymbols: getEmptyNativeSymbolTable(),
@@ -424,6 +423,9 @@ export function getEmptyProfile(): Profile {
424423
},
425424
libs: [],
426425
pages: [],
426+
shared: {
427+
stringArray: [],
428+
},
427429
threads: [],
428430
};
429431
}

src/profile-logic/import/chrome.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,8 @@ async function processTracingEvents(
514514
// new samples on our target interval of 500us.
515515
profile.meta.interval = 0.5;
516516

517+
const stringTable = StringTable.withBackingArray(profile.shared.stringArray);
518+
517519
let profileEvents: (ProfileEvent | CpuProfileEvent)[] =
518520
(eventsByName.get('Profile'): any) || [];
519521

@@ -579,13 +581,10 @@ async function processTracingEvents(
579581
funcTable,
580582
frameTable,
581583
stackTable,
582-
stringArray,
583584
samples: samplesTable,
584585
resourceTable,
585586
} = thread;
586587

587-
const stringTable = StringTable.withBackingArray(stringArray);
588-
589588
if (nodes) {
590589
const parentMap = new Map();
591590
for (const node of nodes) {
@@ -842,7 +841,7 @@ async function extractScreenshots(
842841
screenshots[0]
843842
);
844843

845-
const stringTable = StringTable.withBackingArray(thread.stringArray);
844+
const stringTable = StringTable.withBackingArray(profile.shared.stringArray);
846845

847846
const graphicsIndex = ensureExists(profile.meta.categories).findIndex(
848847
(category) => category.name === 'Graphics'
@@ -933,6 +932,8 @@ function extractMarkers(
933932
throw new Error('No "Other" category in empty profile category list');
934933
}
935934

935+
const stringTable = StringTable.withBackingArray(profile.shared.stringArray);
936+
936937
profile.meta.markerSchema = [
937938
{
938939
name: 'EventDispatch',
@@ -999,8 +1000,7 @@ function extractMarkers(
9991000
event
10001001
);
10011002
const { thread } = threadInfo;
1002-
const { markers, stringArray } = thread;
1003-
const stringTable = StringTable.withBackingArray(stringArray);
1003+
const { markers } = thread;
10041004
let argData: MixedObject | null = null;
10051005
if (event.args && typeof event.args === 'object') {
10061006
argData = (event.args: any).data || null;

src/profile-logic/import/dhat.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,10 @@ export function attemptToConvertDhat(json: mixed): Profile | null {
180180
const profile = getEmptyProfile();
181181
profile.meta.product = dhat.cmd + ' (dhat)';
182182
profile.meta.importedFrom = `dhat`;
183+
const stringTable = StringTable.withBackingArray(profile.shared.stringArray);
183184

184185
const allocationsTable = getEmptyUnbalancedNativeAllocationsTable();
185-
const { funcTable, stringArray, stackTable, frameTable } = getEmptyThread();
186-
const stringTable = StringTable.withBackingArray(stringArray);
186+
const { funcTable, stackTable, frameTable } = getEmptyThread();
187187

188188
const funcKeyToFuncIndex = new Map<string, IndexIntoFuncTable>();
189189

@@ -373,7 +373,6 @@ export function attemptToConvertDhat(json: mixed): Profile | null {
373373
thread.pid = dhat.pid;
374374
thread.tid = i;
375375
thread.name = name;
376-
thread.stringArray = stringTable.getBackingArray();
377376

378377
thread.funcTable.name = funcTable.name.slice();
379378
thread.funcTable.isJS = funcTable.isJS.slice();

src/profile-logic/js-tracer.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -772,10 +772,10 @@ export function getJsTracerFixed(jsTracer: JsTracerTable): JsTracerFixed {
772772
export function convertJsTracerToThread(
773773
fromThread: RawThread,
774774
jsTracer: JsTracerTable,
775-
categories: CategoryList
775+
categories: CategoryList,
776+
stringTable: StringTable
776777
): RawThread {
777778
const jsTracerFixed = getJsTracerFixed(jsTracer);
778-
const stringTable = StringTable.withBackingArray(fromThread.stringArray);
779779
const { thread, stackMap } = convertJsTracerToThreadWithoutSamples(
780780
fromThread,
781781
stringTable,

src/profile-logic/marker-data.js

+25-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
import type {
2424
SamplesTable,
2525
RawThread,
26+
RawProfileSharedData,
2627
RawMarkerTable,
2728
IndexIntoStringTable,
2829
IndexIntoRawMarkerTable,
@@ -409,7 +410,8 @@ export class IPCMarkerCorrelations {
409410
* (or main thread in receiver process if they are not profiled)
410411
*/
411412
export function correlateIPCMarkers(
412-
threads: RawThread[]
413+
threads: RawThread[],
414+
shared: RawProfileSharedData
413415
): IPCMarkerCorrelations {
414416
// Create a unique ID constructed from the source PID, destination PID,
415417
// message seqno, and message type. Since the seqno is only unique for each
@@ -474,6 +476,8 @@ export function correlateIPCMarkers(
474476
}
475477
}
476478

479+
const stringTable = StringTable.withBackingArray(shared.stringArray);
480+
477481
// First, construct a mapping of marker IDs to an array of markers with that
478482
// ID for faster lookup. We also collect the friendly thread names while we
479483
// have access to all the threads. It's considerably more difficult to do
@@ -485,7 +489,6 @@ export function correlateIPCMarkers(
485489
const threadNames: Map<number, string> = new Map();
486490
for (let threadIndex = 0; threadIndex < threads.length; threadIndex++) {
487491
const thread = threads[threadIndex];
488-
const stringTable = StringTable.withBackingArray(thread.stringArray);
489492
// Don't bother checking for IPC markers if this thread's string table
490493
// doesn't have the string "IPC". This lets us avoid looping over all the
491494
// markers when we don't have to.
@@ -1638,3 +1641,23 @@ export const stringsToMarkerRegExps = (
16381641
fieldMap,
16391642
};
16401643
};
1644+
1645+
export function computeStringIndexMarkerFieldsByDataType(
1646+
markerSchemas: MarkerSchema[]
1647+
): Map<string, string[]> {
1648+
const stringIndexMarkerFieldsByDataType = new Map();
1649+
stringIndexMarkerFieldsByDataType.set('CompositorScreenshot', ['url']);
1650+
for (const schema of markerSchemas) {
1651+
const { name, data } = schema;
1652+
const stringIndexFields = [];
1653+
for (const field of data) {
1654+
if (field.format === 'unique-string' && field.key) {
1655+
stringIndexFields.push(field.key);
1656+
}
1657+
}
1658+
if (stringIndexFields.length !== 0) {
1659+
stringIndexMarkerFieldsByDataType.set(name, stringIndexFields);
1660+
}
1661+
}
1662+
return stringIndexMarkerFieldsByDataType;
1663+
}

0 commit comments

Comments
 (0)