Skip to content

Commit

Permalink
Share stringTable between threads.
Browse files Browse the repository at this point in the history
  • Loading branch information
mstange committed Jan 3, 2025
1 parent 1fda449 commit 5f8c157
Show file tree
Hide file tree
Showing 58 changed files with 64,191 additions and 67,664 deletions.
31 changes: 17 additions & 14 deletions src/actions/receive-profile.js
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ export function finalizeFullProfileView(
const thread = profile.threads[threadIndex];
const { samples, jsAllocations, nativeAllocations } = thread;
hasSamples = [samples, jsAllocations, nativeAllocations].some((table) =>
hasUsefulSamples(table?.stack, thread)
hasUsefulSamples(table?.stack, thread, profile.shared)
);
if (hasSamples) {
break;
Expand Down Expand Up @@ -798,20 +798,23 @@ export function bulkProcessSymbolicationSteps(
symbolicationStepsPerThread: Map<ThreadIndex, SymbolicationStepInfo[]>
): ThunkAction<void> {
return (dispatch, getState) => {
const { threads } = getProfile(getState());
const profile = getProfile(getState());
const oldFuncToNewFuncsMaps: Map<ThreadIndex, FuncToFuncsMap> = new Map();
const symbolicatedThreads = threads.map((oldThread, threadIndex) => {
const symbolicationSteps = symbolicationStepsPerThread.get(threadIndex);
if (symbolicationSteps === undefined) {
return oldThread;
const symbolicatedThreads = profile.threads.map(
(oldThread, threadIndex) => {
const symbolicationSteps = symbolicationStepsPerThread.get(threadIndex);
if (symbolicationSteps === undefined) {
return oldThread;

Check warning on line 807 in src/actions/receive-profile.js

View check run for this annotation

Codecov / codecov/patch

src/actions/receive-profile.js#L807

Added line #L807 was not covered by tests
}
const { thread, oldFuncToNewFuncsMap } = applySymbolicationSteps(
oldThread,
profile.shared,
symbolicationSteps
);
oldFuncToNewFuncsMaps.set(threadIndex, oldFuncToNewFuncsMap);
return thread;
}
const { thread, oldFuncToNewFuncsMap } = applySymbolicationSteps(
oldThread,
symbolicationSteps
);
oldFuncToNewFuncsMaps.set(threadIndex, oldFuncToNewFuncsMap);
return thread;
});
);
dispatch({
type: 'BULK_SYMBOLICATION',
oldFuncToNewFuncsMaps,
Expand Down Expand Up @@ -1904,7 +1907,7 @@ export function changeTabFilter(tabID: TabID | null): ThunkAction<void> {
const thread = profile.threads[threadIndex];
const { samples, jsAllocations, nativeAllocations } = thread;
hasSamples = [samples, jsAllocations, nativeAllocations].some((table) =>
hasUsefulSamples(table?.stack, thread)
hasUsefulSamples(table?.stack, thread, profile.shared)
);
if (hasSamples) {
break;
Expand Down
2 changes: 1 addition & 1 deletion src/app-logic/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const GECKO_PROFILE_VERSION = 31;
// The current version of the "processed" profile format.
// Please don't forget to update the processed profile format changelog in
// `docs-developer/CHANGELOG-formats.md`.
export const PROCESSED_PROFILE_VERSION = 52;
export const PROCESSED_PROFILE_VERSION = 53;

// The following are the margin sizes for the left and right of the timeline. Independent
// components need to share these values.
Expand Down
3 changes: 2 additions & 1 deletion src/components/js-tracer/Chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { JsTracerCanvas } from './Canvas';
import {
getCommittedRange,
getPreviewSelection,
getStringTable,
} from 'firefox-profiler/selectors/profile';
import { selectedThreadSelectors } from 'firefox-profiler/selectors/per-thread';
import { getSelectedThreadsKey } from 'firefox-profiler/selectors/url-state';
Expand Down Expand Up @@ -136,7 +137,7 @@ const JsTracerExpensiveChart = explicitConnect<
>({
mapStateToProps: (state, ownProps) => ({
timeRange: getCommittedRange(state),
stringTable: selectedThreadSelectors.getStringTable(state),
stringTable: getStringTable(state),
threadsKey: getSelectedThreadsKey(state),
previewSelection: getPreviewSelection(state),
jsTracerTimingRows: ensureExists(
Expand Down
3 changes: 2 additions & 1 deletion src/profile-logic/active-tab.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,15 @@ export function computeActiveTabTracks(
const screenshots = [];
const topmostInnerWindowIDs = getTopmostInnerWindowIDs(relevantPages);
const innerWindowIDToPageMap = _getInnerWindowIDToPageMap(relevantPages);
const { stringArray } = profile.shared;

for (
let threadIndex = 0;
threadIndex < profile.threads.length;
threadIndex++
) {
const thread = profile.threads[threadIndex];
const { markers, stringArray } = thread;
const { markers } = thread;

if (thread.isMainThread) {
// This is a main thread, there is a possibility that it can be a global
Expand Down
4 changes: 3 additions & 1 deletion src/profile-logic/data-structures.js
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,6 @@ export function getEmptyThread(overrides?: $Shape<RawThread>): RawThread {
markers: getEmptyRawMarkerTable(),
stackTable: getEmptyRawStackTable(),
frameTable: getEmptyFrameTable(),
stringArray: [],
funcTable: getEmptyFuncTable(),
resourceTable: getEmptyResourceTable(),
nativeSymbols: getEmptyNativeSymbolTable(),
Expand Down Expand Up @@ -424,6 +423,9 @@ export function getEmptyProfile(): Profile {
},
libs: [],
pages: [],
shared: {
stringArray: [],
},
threads: [],
};
}
Expand Down
12 changes: 6 additions & 6 deletions src/profile-logic/import/chrome.js
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,8 @@ async function processTracingEvents(
// new samples on our target interval of 500us.
profile.meta.interval = 0.5;

const stringTable = StringTable.withBackingArray(profile.shared.stringArray);

let profileEvents: (ProfileEvent | CpuProfileEvent)[] =
(eventsByName.get('Profile'): any) || [];

Expand Down Expand Up @@ -579,13 +581,10 @@ async function processTracingEvents(
funcTable,
frameTable,
stackTable,
stringArray,
samples: samplesTable,
resourceTable,
} = thread;

const stringTable = StringTable.withBackingArray(stringArray);

if (nodes) {
const parentMap = new Map();
for (const node of nodes) {
Expand Down Expand Up @@ -842,7 +841,7 @@ async function extractScreenshots(
screenshots[0]
);

const stringTable = StringTable.withBackingArray(thread.stringArray);
const stringTable = StringTable.withBackingArray(profile.shared.stringArray);

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

const stringTable = StringTable.withBackingArray(profile.shared.stringArray);

profile.meta.markerSchema = [
{
name: 'EventDispatch',
Expand Down Expand Up @@ -999,8 +1000,7 @@ function extractMarkers(
event
);
const { thread } = threadInfo;
const { markers, stringArray } = thread;
const stringTable = StringTable.withBackingArray(stringArray);
const { markers } = thread;
let argData: MixedObject | null = null;
if (event.args && typeof event.args === 'object') {
argData = (event.args: any).data || null;
Expand Down
5 changes: 2 additions & 3 deletions src/profile-logic/import/dhat.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,10 +180,10 @@ export function attemptToConvertDhat(json: mixed): Profile | null {
const profile = getEmptyProfile();
profile.meta.product = dhat.cmd + ' (dhat)';
profile.meta.importedFrom = `dhat`;
const stringTable = StringTable.withBackingArray(profile.shared.stringArray);

const allocationsTable = getEmptyUnbalancedNativeAllocationsTable();
const { funcTable, stringArray, stackTable, frameTable } = getEmptyThread();
const stringTable = StringTable.withBackingArray(stringArray);
const { funcTable, stackTable, frameTable } = getEmptyThread();

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

Expand Down Expand Up @@ -373,7 +373,6 @@ export function attemptToConvertDhat(json: mixed): Profile | null {
thread.pid = dhat.pid;
thread.tid = i;
thread.name = name;
thread.stringArray = stringTable.getBackingArray();

thread.funcTable.name = funcTable.name.slice();
thread.funcTable.isJS = funcTable.isJS.slice();
Expand Down
4 changes: 2 additions & 2 deletions src/profile-logic/js-tracer.js
Original file line number Diff line number Diff line change
Expand Up @@ -772,10 +772,10 @@ export function getJsTracerFixed(jsTracer: JsTracerTable): JsTracerFixed {
export function convertJsTracerToThread(
fromThread: RawThread,
jsTracer: JsTracerTable,
categories: CategoryList
categories: CategoryList,
stringTable: StringTable
): RawThread {
const jsTracerFixed = getJsTracerFixed(jsTracer);
const stringTable = StringTable.withBackingArray(fromThread.stringArray);
const { thread, stackMap } = convertJsTracerToThreadWithoutSamples(
fromThread,
stringTable,
Expand Down
27 changes: 25 additions & 2 deletions src/profile-logic/marker-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
import type {
SamplesTable,
RawThread,
RawProfileSharedData,
RawMarkerTable,
IndexIntoStringTable,
IndexIntoRawMarkerTable,
Expand Down Expand Up @@ -409,7 +410,8 @@ export class IPCMarkerCorrelations {
* (or main thread in receiver process if they are not profiled)
*/
export function correlateIPCMarkers(
threads: RawThread[]
threads: RawThread[],
shared: RawProfileSharedData
): IPCMarkerCorrelations {
// Create a unique ID constructed from the source PID, destination PID,
// message seqno, and message type. Since the seqno is only unique for each
Expand Down Expand Up @@ -474,6 +476,8 @@ export function correlateIPCMarkers(
}
}

const stringTable = StringTable.withBackingArray(shared.stringArray);

// First, construct a mapping of marker IDs to an array of markers with that
// ID for faster lookup. We also collect the friendly thread names while we
// have access to all the threads. It's considerably more difficult to do
Expand All @@ -485,7 +489,6 @@ export function correlateIPCMarkers(
const threadNames: Map<number, string> = new Map();
for (let threadIndex = 0; threadIndex < threads.length; threadIndex++) {
const thread = threads[threadIndex];
const stringTable = StringTable.withBackingArray(thread.stringArray);
// Don't bother checking for IPC markers if this thread's string table
// doesn't have the string "IPC". This lets us avoid looping over all the
// markers when we don't have to.
Expand Down Expand Up @@ -1638,3 +1641,23 @@ export const stringsToMarkerRegExps = (
fieldMap,
};
};

export function computeStringIndexMarkerFieldsByDataType(
markerSchemas: MarkerSchema[]
): Map<string, string[]> {
const stringIndexMarkerFieldsByDataType = new Map();
stringIndexMarkerFieldsByDataType.set('CompositorScreenshot', ['url']);
for (const schema of markerSchemas) {
const { name, data } = schema;
const stringIndexFields = [];
for (const field of data) {
if (field.format === 'unique-string' && field.key) {
stringIndexFields.push(field.key);
}
}
if (stringIndexFields.length !== 0) {
stringIndexMarkerFieldsByDataType.set(name, stringIndexFields);
}
}
return stringIndexMarkerFieldsByDataType;
}
Loading

0 comments on commit 5f8c157

Please sign in to comment.