Bug 1923903 - [devtools] Instantiate only one object actor per JS object in the JS Tracer. r=devtools-reviewers,bomsy

This will allow to compare Object Actor's IDs in order to track any JS Object
recorded in the trace.

Differential Revision: https://phabricator.services.mozilla.com/D223782
This commit is contained in:
Alexandre Poirot 2024-10-17 12:24:12 +00:00
parent b3de682266
commit ab3f8953cb
2 changed files with 36 additions and 7 deletions

View File

@ -14,6 +14,10 @@ ChromeUtils.defineESModuleGetters(
);
const { Actor } = require("resource://devtools/shared/protocol.js");
const { createValueGrip } = require("devtools/server/actors/object/utils");
const {
ObjectActorPool,
} = require("resource://devtools/server/actors/object/ObjectActorPool.js");
const {
tracerSpec,
TRACER_LOG_METHODS,
@ -82,6 +86,14 @@ class TracerActor extends Actor {
// This is used by the profiler log method and the getProfile method.
#stopResult = null;
// A Pool for all JS values emitted by the Tracer Actor.
// This helps instantiate a unique Object Actor per JS Object communicated to the client.
// This also helps share the same Object Actor instances when evaluating JS via
// the console actor.
// This pool is created lazily, only once we start a new trace.
// We also clear the pool before starting the trace.
#tracerPool = null;
destroy() {
this.stopTracing();
}
@ -152,6 +164,14 @@ class TracerActor extends Actor {
return;
}
// Flush any previous recorded data only when we start a new tracer
// as we may still analyse trace data after stopping the trace.
// The pool will then be re-created on demand from createValueGrip.
if (this.#tracerPool) {
this.#tracerPool.destroy();
this.#tracerPool = null;
}
this.logMethod = options.logMethod || TRACER_LOG_METHODS.STDOUT;
let ListenerClass = null;
@ -240,5 +260,17 @@ class TracerActor extends Actor {
}
return null;
}
createValueGrip(value) {
if (!this.#tracerPool) {
this.#tracerPool = new ObjectActorPool(
this.targetActor.threadActor,
"tracer",
true
);
this.manage(this.#tracerPool);
}
return createValueGrip(this, value, this.#tracerPool);
}
}
exports.TracerActor = TracerActor;

View File

@ -6,10 +6,7 @@
const { throttle } = require("resource://devtools/shared/throttle.js");
const {
makeDebuggeeValue,
createValueGripForTarget,
} = require("devtools/server/actors/object/utils");
const { makeDebuggeeValue } = require("devtools/server/actors/object/utils");
const {
TYPES,
@ -163,7 +160,7 @@ class ResourcesTracingListener {
ChromeUtils.dateNow(),
depth,
type,
createValueGripForTarget(this.targetActor, dbgObj),
this.traceActor.createValueGrip(dbgObj),
]);
this.throttleEmitTraces();
return false;
@ -324,7 +321,7 @@ class ResourcesTracingListener {
}
// Instantiate a object actor so that the tools can easily inspect these objects
const dbgObj = makeDebuggeeValue(this.targetActor, arg);
args.push(createValueGripForTarget(this.targetActor, dbgObj));
args.push(this.traceActor.createValueGrip(dbgObj));
}
argNames = frame.callee.script.parameterNames;
}
@ -415,7 +412,7 @@ class ResourcesTracingListener {
}
// Instantiate a object actor so that the tools can easily inspect these objects
const dbgObj = makeDebuggeeValue(this.targetActor, rv);
returnedValue = createValueGripForTarget(this.targetActor, dbgObj);
returnedValue = this.traceActor.createValueGrip(dbgObj);
}
const frameIndex = this.#getFrameIndex(