michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: "use strict"; michael@0: michael@0: const {Cc, Ci, Cu} = require("chrome"); michael@0: let protocol = require("devtools/server/protocol"); michael@0: let {method, RetVal} = protocol; michael@0: michael@0: /** michael@0: * An actor that returns memory usage data for its parent actor's window. michael@0: * A tab-scoped instance of this actor will measure the memory footprint of its michael@0: * parent tab. A global-scoped instance however, will measure the memory michael@0: * footprint of the chrome window referenced by the root actor. michael@0: */ michael@0: let MemoryActor = protocol.ActorClass({ michael@0: typeName: "memory", michael@0: michael@0: initialize: function(conn, tabActor) { michael@0: protocol.Actor.prototype.initialize.call(this, conn); michael@0: this.tabActor = tabActor; michael@0: this._mgr = Cc["@mozilla.org/memory-reporter-manager;1"] michael@0: .getService(Ci.nsIMemoryReporterManager); michael@0: }, michael@0: michael@0: destroy: function() { michael@0: this._mgr = null; michael@0: protocol.Actor.prototype.destroy.call(this); michael@0: }, michael@0: michael@0: /** michael@0: * A method that returns a detailed breakdown of the memory consumption of the michael@0: * associated window. michael@0: * michael@0: * @returns object michael@0: */ michael@0: measure: method(function() { michael@0: let result = {}; michael@0: michael@0: let jsObjectsSize = {}; michael@0: let jsStringsSize = {}; michael@0: let jsOtherSize = {}; michael@0: let domSize = {}; michael@0: let styleSize = {}; michael@0: let otherSize = {}; michael@0: let totalSize = {}; michael@0: let jsMilliseconds = {}; michael@0: let nonJSMilliseconds = {}; michael@0: michael@0: try { michael@0: this._mgr.sizeOfTab(this.tabActor.window, jsObjectsSize, jsStringsSize, jsOtherSize, michael@0: domSize, styleSize, otherSize, totalSize, jsMilliseconds, nonJSMilliseconds); michael@0: result.total = totalSize.value; michael@0: result.domSize = domSize.value; michael@0: result.styleSize = styleSize.value; michael@0: result.jsObjectsSize = jsObjectsSize.value; michael@0: result.jsStringsSize = jsStringsSize.value; michael@0: result.jsOtherSize = jsOtherSize.value; michael@0: result.otherSize = otherSize.value; michael@0: result.jsMilliseconds = jsMilliseconds.value.toFixed(1); michael@0: result.nonJSMilliseconds = nonJSMilliseconds.value.toFixed(1); michael@0: } catch (e) { michael@0: console.error(e); michael@0: let url = this.tabActor.url; michael@0: console.error("Error getting size of "+url); michael@0: } michael@0: michael@0: return result; michael@0: }, { michael@0: request: {}, michael@0: response: RetVal("json"), michael@0: }) michael@0: }); michael@0: michael@0: exports.MemoryActor = MemoryActor; michael@0: michael@0: exports.MemoryFront = protocol.FrontClass(MemoryActor, { michael@0: initialize: function(client, form) { michael@0: protocol.Front.prototype.initialize.call(this, client, form); michael@0: this.actorID = form.memoryActor; michael@0: client.addActorPool(this); michael@0: this.manage(this); michael@0: } michael@0: }); michael@0: michael@0: exports.register = function(handle) { michael@0: handle.addGlobalActor(MemoryActor, "memoryActor"); michael@0: handle.addTabActor(MemoryActor, "memoryActor"); michael@0: }; michael@0: michael@0: exports.unregister = function(handle) { michael@0: handle.removeGlobalActor(MemoryActor, "memoryActor"); michael@0: handle.removeTabActor(MemoryActor, "memoryActor"); michael@0: };