Skip to content

Commit 45fbf2d

Browse files
committedJun 12, 2024
Bug 1900982 - [devtools] Migrate JS tracer from Objects to Array as trace payloads. r=devtools-reviewers,perftest-reviewers,kshampur,nchevobbe
Using arrays speeds up the serialization and transmission of traces between the server and the client as it goes through JS Actors/IPC by serializing the JSON RDP packets. This also allows to better align with the profiler data format. Differential Revision: https://phabricator.services.mozilla.com/D212807
1 parent 5a5ec57 commit 45fbf2d

File tree

8 files changed

+335
-148
lines changed

8 files changed

+335
-148
lines changed
 

‎devtools/client/fronts/targets/target-mixin.js

+11
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,17 @@ function TargetMixin(parentClass) {
595595
}
596596
return Promise.resolve();
597597
}
598+
599+
/**
600+
* The tracer actor emits frames which should be collected per target/thread.
601+
* The tracer will emit other resources, refering to the frame indexes in that collected array.
602+
* The indexes and this array in general is specific to a given tracer actor instance
603+
* and so is specific per thread and target.
604+
*/
605+
#jsTracerCollectedFrames = [];
606+
getJsTracerCollectedFramesArray() {
607+
return this.#jsTracerCollectedFrames;
608+
}
598609
}
599610
return Target;
600611
}

‎devtools/client/webconsole/actions/messages.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ const {
3232

3333
const defaultIdGenerator = new IdGenerator();
3434

35-
function messagesAdd(packets, idGenerator = null, persistLogs = false) {
35+
function messagesAdd(resources, idGenerator = null, persistLogs = false) {
3636
if (idGenerator == null) {
3737
idGenerator = defaultIdGenerator;
3838
}
39-
const messages = packets.map(packet =>
40-
prepareMessage(packet, idGenerator, persistLogs)
39+
const messages = resources.map(resource =>
40+
prepareMessage(resource, idGenerator, persistLogs)
4141
);
4242
// Sort the messages by their timestamps.
4343
messages.sort(getNaturalOrder);

‎devtools/client/webconsole/utils/messages.js

+147-67
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ loader.lazyRequireGetter(
1717
true
1818
);
1919

20+
loader.lazyRequireGetter(
21+
this,
22+
"TRACER_FIELDS_INDEXES",
23+
"resource://devtools/server/actors/tracer.js",
24+
true
25+
);
26+
2027
// URL Regex, common idioms:
2128
//
2229
// Lead-in (URL):
@@ -122,10 +129,6 @@ function transformResource(resource, persistLogs) {
122129
return transformNetworkEventResource(resource);
123130
}
124131

125-
case ResourceCommand.TYPES.JSTRACER_TRACE: {
126-
return transformTraceResource(resource);
127-
}
128-
129132
case ResourceCommand.TYPES.JSTRACER_STATE: {
130133
return transformTracerStateResource(resource);
131134
}
@@ -362,71 +365,147 @@ function transformNetworkEventResource(networkEventResource) {
362365
}
363366

364367
function transformTraceResource(traceResource) {
365-
const { targetFront, prefix, timeStamp } = traceResource;
366-
if (traceResource.eventName) {
367-
const { eventName } = traceResource;
368-
369-
return new ConsoleMessage({
370-
targetFront,
371-
source: MESSAGE_SOURCE.JSTRACER,
372-
depth: 0,
373-
eventName,
374-
timeStamp,
375-
prefix,
376-
allowRepeating: false,
377-
});
368+
const { targetFront, traces, exitTraces, domMutations, events, frames } =
369+
traceResource;
370+
const collectedFrames = targetFront.getJsTracerCollectedFramesArray();
371+
if (frames) {
372+
for (const frame of frames) {
373+
collectedFrames.push(frame);
374+
}
375+
}
376+
const messages = [];
377+
for (const trace of traces) {
378+
const [prefix, frameIndex, timeStamp, depth, args] = trace;
379+
const frame = collectedFrames[frameIndex];
380+
messages.push(
381+
new ConsoleMessage({
382+
targetFront,
383+
source: MESSAGE_SOURCE.JSTRACER,
384+
frame: {
385+
source: frame[TRACER_FIELDS_INDEXES.FRAME_URL],
386+
sourceId: frame[TRACER_FIELDS_INDEXES.FRAME_SOURCEID],
387+
line: frame[TRACER_FIELDS_INDEXES.FRAME_LINE],
388+
column: frame[TRACER_FIELDS_INDEXES.FRAME_COLUMN],
389+
},
390+
depth,
391+
implementation: frame[TRACER_FIELDS_INDEXES.FRAME_IMPLEMENTATION],
392+
displayName: frame[TRACER_FIELDS_INDEXES.FRAME_NAME],
393+
parameters: args
394+
? args.map(p =>
395+
p ? getAdHocFrontOrPrimitiveGrip(p, targetFront) : p
396+
)
397+
: null,
398+
messageText: null,
399+
timeStamp,
400+
prefix,
401+
// Allow the identical frames to be coalesced into a unique message
402+
// with a repeatition counter so that we keep the output short in case of loops.
403+
allowRepeating: true,
404+
})
405+
);
378406
}
379-
const {
380-
depth,
381-
implementation,
382-
displayName,
383-
filename,
384-
lineNumber,
385-
columnNumber,
386-
args,
387-
sourceId,
388-
389-
relatedTraceId,
390-
why,
391-
392-
mutationType,
393-
mutationElement,
394-
} = traceResource;
395-
396-
const frame = {
397-
source: filename,
398-
sourceId,
399-
line: lineNumber,
400-
column: columnNumber,
401-
};
402407

403-
return new ConsoleMessage({
404-
targetFront,
405-
source: MESSAGE_SOURCE.JSTRACER,
406-
frame,
407-
depth,
408-
implementation,
409-
displayName,
410-
parameters: args
411-
? args.map(p => (p ? getAdHocFrontOrPrimitiveGrip(p, targetFront) : p))
412-
: null,
413-
returnedValue:
414-
why && "returnedValue" in traceResource
415-
? getAdHocFrontOrPrimitiveGrip(traceResource.returnedValue, targetFront)
416-
: undefined,
417-
relatedTraceId,
418-
why,
419-
messageText: null,
420-
timeStamp,
421-
prefix,
422-
mutationType,
423-
mutationElement: mutationElement
424-
? getAdHocFrontOrPrimitiveGrip(mutationElement, targetFront)
425-
: null,
426-
// Allow the identical frames to be coallesced into a unique message
427-
// with a repeatition counter so that we keep the output short in case of loops.
428-
allowRepeating: true,
429-
});
408+
if (exitTraces) {
409+
for (const trace of exitTraces) {
410+
const [
411+
prefix,
412+
frameIndex,
413+
timeStamp,
414+
depth,
415+
relatedTraceId,
416+
returnedValue,
417+
why,
418+
] = trace;
419+
const frame = collectedFrames[frameIndex];
420+
messages.push(
421+
new ConsoleMessage({
422+
targetFront,
423+
source: MESSAGE_SOURCE.JSTRACER,
424+
frame: {
425+
source: frame[TRACER_FIELDS_INDEXES.FRAME_URL],
426+
sourceId: frame[TRACER_FIELDS_INDEXES.FRAME_SOURCEID],
427+
line: frame[TRACER_FIELDS_INDEXES.FRAME_LINE],
428+
column: frame[TRACER_FIELDS_INDEXES.FRAME_COLUMN],
429+
},
430+
depth,
431+
implementation: frame[TRACER_FIELDS_INDEXES.FRAME_IMPLEMENTATION],
432+
displayName: frame[TRACER_FIELDS_INDEXES.FRAME_NAME],
433+
parameters: null,
434+
returnedValue:
435+
returnedValue != undefined
436+
? getAdHocFrontOrPrimitiveGrip(returnedValue, targetFront)
437+
: null,
438+
relatedTraceId,
439+
why,
440+
messageText: null,
441+
timeStamp,
442+
prefix,
443+
// Allow the identical frames to be coallesced into a unique message
444+
// with a repeatition counter so that we keep the output short in case of loops.
445+
allowRepeating: true,
446+
})
447+
);
448+
}
449+
}
450+
451+
if (domMutations) {
452+
for (const trace of domMutations) {
453+
const [
454+
prefix,
455+
frameIndex,
456+
timeStamp,
457+
depth,
458+
mutationType,
459+
mutationElement,
460+
] = trace;
461+
const frame = collectedFrames[frameIndex];
462+
messages.push(
463+
new ConsoleMessage({
464+
targetFront,
465+
source: MESSAGE_SOURCE.JSTRACER,
466+
frame: {
467+
source: frame[TRACER_FIELDS_INDEXES.FRAME_URL],
468+
sourceId: frame[TRACER_FIELDS_INDEXES.FRAME_SOURCEID],
469+
line: frame[TRACER_FIELDS_INDEXES.FRAME_LINE],
470+
column: frame[TRACER_FIELDS_INDEXES.FRAME_COLUMN],
471+
},
472+
depth,
473+
implementation: frame[TRACER_FIELDS_INDEXES.FRAME_IMPLEMENTATION],
474+
displayName: frame[TRACER_FIELDS_INDEXES.FRAME_NAME],
475+
parameters: null,
476+
messageText: null,
477+
timeStamp,
478+
prefix,
479+
mutationType,
480+
mutationElement: mutationElement
481+
? getAdHocFrontOrPrimitiveGrip(mutationElement, targetFront)
482+
: null,
483+
// Allow the identical frames to be coallesced into a unique message
484+
// with a repeatition counter so that we keep the output short in case of loops.
485+
allowRepeating: true,
486+
})
487+
);
488+
}
489+
}
490+
491+
if (events) {
492+
for (const trace of events) {
493+
const [prefix, timeStamp, eventName] = trace;
494+
messages.push(
495+
new ConsoleMessage({
496+
targetFront,
497+
source: MESSAGE_SOURCE.JSTRACER,
498+
depth: 0,
499+
prefix,
500+
timeStamp,
501+
eventName,
502+
allowRepeating: false,
503+
})
504+
);
505+
}
506+
}
507+
508+
return messages;
430509
}
431510

432511
function transformTracerStateResource(stateResource) {
@@ -1034,4 +1113,5 @@ module.exports = {
10341113
isWarningGroup,
10351114
l10n,
10361115
prepareMessage,
1116+
transformTraceResource,
10371117
};

‎devtools/client/webconsole/webconsole-ui.js

+6
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ class WebConsoleUI {
466466
this._watchedResources.push(resourceCommand.TYPES.CSS_MESSAGE);
467467
}
468468

469+
// eslint-disable-next-line complexity
469470
_onResourceAvailable(resources) {
470471
if (this._destroyed) {
471472
return;
@@ -513,6 +514,11 @@ class WebConsoleUI {
513514
continue;
514515
}
515516

517+
if (resource.resourceType === TYPES.JSTRACER_TRACE) {
518+
this.wrapper.dispatchJsTraces(resource);
519+
continue;
520+
}
521+
516522
if (resource.resourceType === TYPES.NETWORK_EVENT) {
517523
this.networkDataProvider?.onNetworkResourceAvailable(resource);
518524
}

‎devtools/client/webconsole/webconsole-wrapper.js

+9
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const {
2020

2121
const {
2222
isPacketPrivate,
23+
transformTraceResource,
2324
} = require("resource://devtools/client/webconsole/utils/messages.js");
2425
const {
2526
getMutableMessagesById,
@@ -195,6 +196,14 @@ class WebConsoleWrapper {
195196
this.batchedMessagesAdd(messages);
196197
}
197198

199+
// Use a custom codepath for traces as each resource may spawn many messages
200+
dispatchJsTraces(traceResource) {
201+
const messages = transformTraceResource(traceResource);
202+
203+
const { ui } = store.getState();
204+
store.dispatch(actions.messagesAdd(messages, null, ui.persistLogs));
205+
}
206+
198207
dispatchNetworkMessagesDisable() {
199208
const networkMessageIds = Object.keys(
200209
getAllNetworkMessagesUpdateById(store.getState())

0 commit comments

Comments
 (0)
Failed to load comments.