Skip to content

Commit 20da66f

Browse files
committed
WIP traced value support
1 parent b5ea860 commit 20da66f

File tree

13 files changed

+457
-9
lines changed

13 files changed

+457
-9
lines changed

package.json

-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@
120120
"babel-loader": "^9.2.1",
121121
"babel-plugin-module-resolver": "^5.0.2",
122122
"browserslist": "^4.24.3",
123-
"caniuse-lite": "^1.0.30001690",
124123
"circular-dependency-plugin": "^5.2.1",
125124
"codecov": "^3.8.3",
126125
"copy-webpack-plugin": "^12.0.2",

src/components/stack-chart/Canvas.js

+9
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
typeof changeMouseTimePosition as ChangeMouseTimePosition,
2121
} from '../../actions/profile-view';
2222
import { mapCategoryColorNameToStackChartStyles } from '../../utils/colors';
23+
import { getArgvSummaries } from '../../utils/value-summaries';
2324
import { TooltipCallNode } from '../tooltip/CallNode';
2425
import { TooltipMarker } from '../tooltip/Marker';
2526

@@ -97,6 +98,7 @@ const TEXT_CSS_PIXELS_OFFSET_TOP = 11;
9798
const FONT_SIZE = 10;
9899
const BORDER_OPACITY = 0.4;
99100

101+
100102
class StackChartCanvasImpl extends React.PureComponent<Props> {
101103
_textMeasurement: null | TextMeasurement;
102104
_textMeasurementCssToDeviceScale: number = 1;
@@ -467,12 +469,18 @@ class StackChartCanvasImpl extends React.PureComponent<Props> {
467469
);
468470
}
469471

472+
470473
const callNodeIndex = timing.callNode[stackTimingIndex];
471474
if (callNodeIndex === undefined) {
472475
return null;
473476
}
474477
const duration =
475478
timing.end[stackTimingIndex] - timing.start[stackTimingIndex];
479+
const argv = timing.argv[stackTimingIndex];
480+
let argvSummaries = undefined;
481+
if (argv != -1) {
482+
argvSummaries = getArgvSummaries(thread, argv);
483+
}
476484

477485
return (
478486
<TooltipCallNode
@@ -487,6 +495,7 @@ class StackChartCanvasImpl extends React.PureComponent<Props> {
487495
callTreeSummaryStrategy="timing"
488496
durationText={formatMilliseconds(duration)}
489497
displayStackType={displayStackType}
498+
argv={JSON.stringify(argvSummaries, null, 2) || null}
490499
/>
491500
);
492501
};

src/components/tooltip/CallNode.js

+15
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ type Props = {|
129129
+timings?: TimingsForPath,
130130
+callTreeSummaryStrategy: CallTreeSummaryStrategy,
131131
+displayStackType: boolean,
132+
+argv?: string | null,
132133
|};
133134

134135
/**
@@ -358,6 +359,7 @@ export class TooltipCallNode extends React.PureComponent<Props> {
358359
thread,
359360
durationText,
360361
categories,
362+
argv,
361363
displayData,
362364
timings,
363365
callTreeSummaryStrategy,
@@ -424,6 +426,18 @@ export class TooltipCallNode extends React.PureComponent<Props> {
424426
];
425427
}
426428

429+
let argvEl = null;
430+
if (argv) {
431+
argvEl = [
432+
<div className="tooltipLabel" key="resource">
433+
Arguments:
434+
</div>,
435+
];
436+
for (let line of argv.split("\n")) {
437+
argvEl.push(line);
438+
}
439+
}
440+
427441
// Finding current frame and parent frame URL(if there is).
428442
let pageAndParentPageURL;
429443
if (innerWindowIDToPageMap) {
@@ -538,6 +552,7 @@ export class TooltipCallNode extends React.PureComponent<Props> {
538552
{pageAndParentPageURL}
539553
{fileName}
540554
{resource}
555+
{argvEl}
541556
</div>
542557
{this._renderCategoryTimings(timings)}
543558
</div>

src/profile-logic/data-structures.js

+2
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ export function getEmptySamplesTableWithEventDelay(): RawSamplesTable {
8989
eventDelay: [],
9090
stack: [],
9191
time: [],
92+
argv: [],
9293
length: 0,
9394
};
9495
}
@@ -109,6 +110,7 @@ export function getEmptySamplesTableWithResponsiveness(): SamplesTable {
109110
responsiveness: [],
110111
stack: [],
111112
time: [],
113+
argv: [],
112114
length: 0,
113115
};
114116
}

src/profile-logic/process-profile.js

+16
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
} from './data-structures';
2020
import { immutableUpdate, ensureExists, coerce } from '../utils/flow';
2121
import { verifyMagic, SIMPLEPERF as SIMPLEPERF_MAGIC } from '../utils/magic';
22+
import { base64StringToArrayBuffer } from '../utils/value-summaries';
2223
import { attemptToUpgradeProcessedProfileThroughMutation } from './processed-profile-versioning';
2324
import { upgradeGeckoProfileToCurrentVersion } from './gecko-profile-versioning';
2425
import {
@@ -967,6 +968,10 @@ function _processSamples(geckoSamples: GeckoSampleStruct): RawSamplesTable {
967968
}
968969
}
969970

971+
if (geckoSamples.argv) {
972+
samples.argv = geckoSamples.argv;
973+
}
974+
970975
if (geckoSamples.eventDelay) {
971976
samples.eventDelay = geckoSamples.eventDelay;
972977
} else if (geckoSamples.responsiveness) {
@@ -1204,6 +1209,17 @@ function _processThread(
12041209
newThread.nativeAllocations = nativeAllocations;
12051210
}
12061211

1212+
if (thread.values) {
1213+
var buffer = base64StringToArrayBuffer(thread.values);
1214+
if (buffer) {
1215+
newThread.argvBuffer = buffer;
1216+
}
1217+
}
1218+
1219+
if (thread.shapes) {
1220+
newThread.shapes = thread.shapes;
1221+
}
1222+
12071223
function processJsTracer() {
12081224
// Optionally extract the JS Tracer information, if they exist.
12091225
const { jsTracerEvents } = thread;

src/profile-logic/profile-data.js

+24
Original file line numberDiff line numberDiff line change
@@ -1673,6 +1673,13 @@ export function filterThreadSamplesToRange(
16731673
);
16741674
}
16751675

1676+
if (samples.argv) {
1677+
newSamples.argv = samples.argv.slice(
1678+
beginSampleIndex,
1679+
endSampleIndex
1680+
);
1681+
}
1682+
16761683
if (samples.threadId) {
16771684
newSamples.threadId = samples.threadId.slice(
16781685
beginSampleIndex,
@@ -1799,6 +1806,13 @@ export function filterRawThreadSamplesToRange(
17991806
);
18001807
}
18011808

1809+
if (samples.argv) {
1810+
newSamples.argv = samples.argv.slice(
1811+
beginSampleIndex,
1812+
endSampleIndex
1813+
);
1814+
}
1815+
18021816
if (samples.threadId) {
18031817
newSamples.threadId = samples.threadId.slice(
18041818
beginSampleIndex,
@@ -1907,6 +1921,10 @@ export function filterCounterSamplesToRange(
19071921
: undefined,
19081922
};
19091923

1924+
if (samples.argv) {
1925+
newCounter.argv = samples.argv.slice(beginSampleIndex, endSampleIndex);
1926+
}
1927+
19101928
return newCounter;
19111929
}
19121930

@@ -2345,6 +2363,7 @@ export function computeSamplesTableFromRawSamplesTable(
23452363
const {
23462364
responsiveness,
23472365
eventDelay,
2366+
argv,
23482367
stack,
23492368
weight,
23502369
weightType,
@@ -2371,6 +2390,7 @@ export function computeSamplesTableFromRawSamplesTable(
23712390
// These fields are copied from the raw samples table:
23722391
responsiveness,
23732392
eventDelay,
2393+
argv,
23742394
stack,
23752395
weight,
23762396
weightType,
@@ -2417,6 +2437,8 @@ export function createThreadFromDerivedTables(
24172437
jsTracer,
24182438
isPrivateBrowsing,
24192439
userContextId,
2440+
argvBuffer,
2441+
shapes,
24202442
} = rawThread;
24212443

24222444
const thread: Thread = {
@@ -2445,6 +2467,8 @@ export function createThreadFromDerivedTables(
24452467
jsTracer,
24462468
isPrivateBrowsing,
24472469
userContextId,
2470+
argvBuffer,
2471+
shapes,
24482472

24492473
// These fields are derived:
24502474
samples,

src/profile-logic/stack-timing.js

+12
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export type StackTiming = {|
5151
start: Milliseconds[],
5252
end: Milliseconds[],
5353
callNode: IndexIntoCallNodeTable[],
54+
argv: number[],
5455
length: number,
5556
|};
5657

@@ -76,6 +77,7 @@ export function getStackTimingByDepth(
7677
start: [],
7778
end: [],
7879
callNode: [],
80+
argv: [],
7981
length: 0,
8082
}));
8183

@@ -105,9 +107,14 @@ export function getStackTimingByDepth(
105107
let deepestOpenBoxCallNodeIndex = -1;
106108
let deepestOpenBoxDepth = -1;
107109
const openBoxStartTimeByDepth = new Float64Array(maxDepthPlusOne);
110+
const openBoxArgvByDepth = new Int32Array(maxDepthPlusOne);
108111

109112
for (let sampleIndex = 0; sampleIndex < samples.length; sampleIndex++) {
110113
const sampleTime = samples.time[sampleIndex];
114+
let sampleArgv : number = -1;
115+
if (samples.argv) {
116+
sampleArgv = samples.argv[sampleIndex];
117+
}
111118
const thisCallNodeIndex = sampleCallNodes[sampleIndex] ?? -1;
112119
if (thisCallNodeIndex === deepestOpenBoxCallNodeIndex) {
113120
continue;
@@ -134,10 +141,12 @@ export function getStackTimingByDepth(
134141
// deepestOpenBoxCallNodeIndex is *not* an ancestors of thisCallNodeIndex.
135142
// Commit this box.
136143
const start = openBoxStartTimeByDepth[deepestOpenBoxDepth];
144+
const argv = openBoxArgvByDepth[deepestOpenBoxDepth];
137145
const stackTimingForThisDepth = stackTimingByDepth[deepestOpenBoxDepth];
138146
const index = stackTimingForThisDepth.length++;
139147
stackTimingForThisDepth.start[index] = start;
140148
stackTimingForThisDepth.end[index] = sampleTime;
149+
stackTimingForThisDepth.argv[index] = argv;
141150
stackTimingForThisDepth.callNode[index] = deepestOpenBoxCallNodeIndex;
142151
deepestOpenBoxCallNodeIndex =
143152
callNodeTablePrefixColumn[deepestOpenBoxCallNodeIndex];
@@ -153,6 +162,7 @@ export function getStackTimingByDepth(
153162
while (deepestOpenBoxDepth < thisCallNodeDepth) {
154163
deepestOpenBoxDepth++;
155164
openBoxStartTimeByDepth[deepestOpenBoxDepth] = sampleTime;
165+
openBoxArgvByDepth[deepestOpenBoxDepth] = sampleArgv;
156166
}
157167
}
158168

@@ -166,8 +176,10 @@ export function getStackTimingByDepth(
166176
const stackTimingForThisDepth = stackTimingByDepth[deepestOpenBoxDepth];
167177
const index = stackTimingForThisDepth.length++;
168178
const start = openBoxStartTimeByDepth[deepestOpenBoxDepth];
179+
const argv = openBoxArgvByDepth[deepestOpenBoxDepth];
169180
stackTimingForThisDepth.start[index] = start;
170181
stackTimingForThisDepth.end[index] = endTime;
182+
stackTimingForThisDepth.argv[index] = argv;
171183
stackTimingForThisDepth.callNode[index] = deepestOpenBoxCallNodeIndex;
172184
deepestOpenBoxCallNodeIndex =
173185
callNodeTablePrefixColumn[deepestOpenBoxCallNodeIndex];

src/test/fixtures/profiles/processed-profile.js

+3
Original file line numberDiff line numberDiff line change
@@ -2117,6 +2117,9 @@ export function addInnerWindowIdToStacks(
21172117
if (samples.responsiveness) {
21182118
samples.responsiveness.push(samples.responsiveness[sampleIndex]);
21192119
}
2120+
if (samples.argv) {
2121+
samples.argv.push(samples.argv[sampleIndex]);
2122+
}
21202123
if (samples.threadCPUDelta) {
21212124
samples.threadCPUDelta.push(samples.threadCPUDelta[sampleIndex]);
21222125
}

src/types/gecko-profile.js

+5
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ export type GeckoSamples = {|
120120
stack: 0,
121121
time: 1,
122122
eventDelay: 2,
123+
argv?: 3,
123124
threadCPUDelta?: 3,
124125
|},
125126
data: Array<
@@ -154,6 +155,7 @@ export type GeckoSampleStructWithResponsiveness = {|
154155
// versions may not have it or that feature could be disabled. No upgrader was
155156
// written for this change because it's a completely new data source.
156157
threadCPUDelta?: Array<number | null>,
158+
argv?: Array<number | null>,
157159
length: number,
158160
|};
159161

@@ -168,6 +170,7 @@ export type GeckoSampleStructWithEventDelay = {|
168170
// versions may not have it or that feature could be disabled. No upgrader was
169171
// written for this change because it's a completely new data source.
170172
threadCPUDelta?: Array<number | null>,
173+
argv?: Array<number | null>,
171174
length: number,
172175
|};
173176

@@ -276,6 +279,8 @@ export type GeckoThread = {|
276279
stackTable: GeckoStackTable,
277280
stringTable: string[],
278281
jsTracerEvents?: JsTracerTable,
282+
values?: string,
283+
shapes?: Array<?Array<string>>,
279284
|};
280285

281286
export type GeckoExtensionMeta = {|

src/types/profile-derived.js

+1
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ export type SamplesTable = {|
132132
// This property isn't present in normal threads. However it's present for
133133
// merged threads, so that we know the origin thread for these samples.
134134
threadId?: Tid[],
135+
argv?: Array<number | null>,
135136
length: number,
136137
|};
137138

src/types/profile.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ export type RawSamplesTable = {|
118118
time?: Milliseconds[],
119119
// If the `time` column is not present, then the `timeDeltas` column must be present.
120120
timeDeltas?: Milliseconds[],
121+
argv?: Array<number | null>,
121122
// An optional weight array. If not present, then the weight is assumed to be 1.
122123
// See the WeightType type for more information.
123124
weight: null | number[],
@@ -133,6 +134,7 @@ export type RawSamplesTable = {|
133134
// This property isn't present in normal threads. However it's present for
134135
// merged threads, so that we know the origin thread for these samples.
135136
threadId?: Tid[],
137+
argv?: Array<number | null>,
136138
length: number,
137139
|};
138140

@@ -636,7 +638,9 @@ export type RawThread = {|
636638
// It's absent in Firefox 97 and before, or in Firefox 98+ when this thread
637639
// had no extra attribute at all.
638640
userContextId?: number,
639-
|};
641+
argvBuffer?: ArrayBuffer,
642+
shapes?: Array<?Array<string>>,
643+
|};
640644

641645
export type ExtensionTable = {|
642646
baseURL: string[],

0 commit comments

Comments
 (0)