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 { 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 { const {
tracerSpec, tracerSpec,
TRACER_LOG_METHODS, TRACER_LOG_METHODS,
@ -82,6 +86,14 @@ class TracerActor extends Actor {
// This is used by the profiler log method and the getProfile method. // This is used by the profiler log method and the getProfile method.
#stopResult = null; #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() { destroy() {
this.stopTracing(); this.stopTracing();
} }
@ -152,6 +164,14 @@ class TracerActor extends Actor {
return; 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; this.logMethod = options.logMethod || TRACER_LOG_METHODS.STDOUT;
let ListenerClass = null; let ListenerClass = null;
@ -240,5 +260,17 @@ class TracerActor extends Actor {
} }
return null; 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; exports.TracerActor = TracerActor;

View File

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