From ab3f8953cbd306099cb34f300e4e8d70fa030425 Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Thu, 17 Oct 2024 12:24:12 +0000 Subject: [PATCH] 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 --- devtools/server/actors/tracer.js | 32 ++++++++++++++++++++++ devtools/server/actors/tracer/resources.js | 11 +++----- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/devtools/server/actors/tracer.js b/devtools/server/actors/tracer.js index c133f8eebbc6..3993596306f6 100644 --- a/devtools/server/actors/tracer.js +++ b/devtools/server/actors/tracer.js @@ -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; diff --git a/devtools/server/actors/tracer/resources.js b/devtools/server/actors/tracer/resources.js index 3364be82be30..972b3dce486d 100644 --- a/devtools/server/actors/tracer/resources.js +++ b/devtools/server/actors/tracer/resources.js @@ -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(