diff --git a/devtools/client/shared/test/shared-head.js b/devtools/client/shared/test/shared-head.js index 92eab4d97671..4f419abd30bd 100644 --- a/devtools/client/shared/test/shared-head.js +++ b/devtools/client/shared/test/shared-head.js @@ -25,7 +25,7 @@ if (DEBUG_ALLOCATIONS) { loader.invisibleToDebugger = true; const { allocationTracker } = loader.require("devtools/shared/test-helpers/allocation-tracker"); - const tracker = allocationTracker(); + const tracker = allocationTracker({ watchAllGlobals: true }); registerCleanupFunction(() => { if (DEBUG_ALLOCATIONS == "normal") { tracker.logCount(); diff --git a/devtools/shared/test-helpers/allocation-tracker.js b/devtools/shared/test-helpers/allocation-tracker.js index 7b9b1293a32b..b855c74752bc 100644 --- a/devtools/shared/test-helpers/allocation-tracker.js +++ b/devtools/shared/test-helpers/allocation-tracker.js @@ -42,7 +42,18 @@ const global = Cu.getGlobalForObject(this); const {addDebuggerToGlobal} = ChromeUtils.import("resource://gre/modules/jsdebugger.jsm"); addDebuggerToGlobal(global); -exports.allocationTracker = function() { +/** + * Start recording JS object allocations. + * + * @param Object watchGlobal + * One global object to observe. Only allocation made from this global + * will be recorded. + * @param Boolean watchAllGlobals + * If true, allocations from everywhere are going to be recorded. + * @param Boolean watchAllGlobals + * If true, only allocations made from DevTools contexts are going to be recorded. + */ +exports.allocationTracker = function({ watchGlobal, watchAllGlobals, watchDevToolsGlobals } = {}) { dump("DEVTOOLS ALLOCATION: Start logging allocations\n"); let dbg = new global.Debugger(); @@ -53,8 +64,37 @@ exports.allocationTracker = function() { // Bumps the default buffer size, which may prevent recording all the test allocations dbg.memory.maxAllocationsLogLength = 5000000; + let acceptGlobal; + if (watchGlobal) { + acceptGlobal = () => false; + dbg.addDebuggee(watchGlobal); + } else if (watchAllGlobals) { + acceptGlobal = () => true; + } else if (watchDevToolsGlobals) { + // Only accept globals related to DevTools + acceptGlobal = g => { + // self-hosting-global crashes when trying to call unsafeDereference + if (g.class == "self-hosting-global") { + return false; + } + let ref = g.unsafeDereference(); + let location = Cu.getRealmLocation(ref); + let accept = !!location.match(/devtools/i); + dump("NEW GLOBAL: " + (accept ? "+" : "-") + " : " + location + "\n"); + return accept; + }; + } + // Watch all globals - dbg.addAllGlobalsAsDebuggees(); + if (watchAllGlobals || watchDevToolsGlobals) { + dbg.addAllGlobalsAsDebuggees(); + + for(let g of dbg.getDebuggees()) { + if (!acceptGlobal(g)) { + dbg.removeDebuggee(g); + } + } + } // Remove this global to ignore all its object/JS dbg.removeDebuggee(global); @@ -62,7 +102,9 @@ exports.allocationTracker = function() { // addAllGlobalsAsDebuggees won't automatically track new ones, // so ensure tracking all new globals dbg.onNewGlobalObject = function(g) { - dbg.addDebuggee(g); + if (acceptGlobal(g)) { + dbg.addDebuggee(g); + } }; return {