--- a/.eslintignore
+++ b/.eslintignore
@@ -109,17 +109,16 @@ devtools/server/actors/*.js
!devtools/server/actors/inspector.js
!devtools/server/actors/layout.js
!devtools/server/actors/string.js
!devtools/server/actors/styles.js
!devtools/server/actors/tab.js
!devtools/server/actors/webbrowser.js
!devtools/server/actors/webextension.js
!devtools/server/actors/webextension-inspected-window.js
-devtools/server/performance/**
devtools/server/tests/browser/**
!devtools/server/tests/browser/browser_webextension_inspected_window.js
devtools/server/tests/mochitest/**
devtools/server/tests/unit/**
devtools/shared/apps/**
devtools/shared/client/**
devtools/shared/discovery/**
devtools/shared/gcli/**
--- a/devtools/server/performance/framerate.js
+++ b/devtools/server/performance/framerate.js
@@ -1,22 +1,22 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
-const { on, once, off, emit } = require("sdk/event/core");
+const { on, off } = require("sdk/event/core");
const { Class } = require("sdk/core/heritage");
/**
* A very simple utility for monitoring framerate. Takes a `tabActor`
* and monitors framerate over time. The actor wrapper around this
* can be found at devtools/server/actors/framerate.js
*/
-var Framerate = exports.Framerate = Class({
+exports.Framerate = Class({
initialize: function (tabActor) {
this.tabActor = tabActor;
this._contentWin = tabActor.window;
this._onRefreshDriverTick = this._onRefreshDriverTick.bind(this);
this._onGlobalCreated = this._onGlobalCreated.bind(this);
on(this.tabActor, "window-ready", this._onGlobalCreated);
},
destroy: function (conn) {
--- a/devtools/server/performance/memory.js
+++ b/devtools/server/performance/memory.js
@@ -27,17 +27,17 @@ loader.lazyRequireGetter(this, "ChildPro
* Using a tab-scoped actor with this instance will measure the memory footprint of its
* parent tab. Using a global-scoped actor instance however, will measure the memory
* footprint of the chrome window referenced by its root actor.
*
* To be consumed by actor's, like MemoryActor using this module to
* send information over RDP, and TimelineActor for using more light-weight
* utilities like GC events and measuring memory consumption.
*/
-var Memory = exports.Memory = Class({
+exports.Memory = Class({
extends: EventTarget,
/**
* Requires a root actor and a StackFrameCache.
*/
initialize: function (parent, frameCache = new StackFrameCache()) {
this.parent = parent;
this._mgr = Cc["@mozilla.org/memory-reporter-manager;1"]
@@ -143,19 +143,22 @@ var Memory = exports.Memory = Class({
* @param {Object|null} boundaries
*
* @returns {String} The snapshot id.
*/
saveHeapSnapshot: expectState("attached", function (boundaries = null) {
// If we are observing the whole process, then scope the snapshot
// accordingly. Otherwise, use the debugger's debuggees.
if (!boundaries) {
- boundaries = this.parent instanceof ChromeActor || this.parent instanceof ChildProcessActor
- ? { runtime: true }
- : { debugger: this.dbg };
+ if (this.parent instanceof ChromeActor ||
+ this.parent instanceof ChildProcessActor) {
+ boundaries = { runtime: true };
+ } else {
+ boundaries = { debugger: this.dbg };
+ }
}
const path = ThreadSafeChromeUtils.saveHeapSnapshot(boundaries);
return HeapSnapshotFileUtils.getSnapshotIdFromPath(path);
}, "saveHeapSnapshot"),
/**
* Take a census of the heap. See js/src/doc/Debugger/Debugger.Memory.md for
* more information.
@@ -163,50 +166,52 @@ var Memory = exports.Memory = Class({
takeCensus: expectState("attached", function () {
return this.dbg.memory.takeCensus();
}, "taking census"),
/**
* Start recording allocation sites.
*
* @param {number} options.probability
- * The probability we sample any given allocation when recording allocations.
- * Must be between 0 and 1 -- defaults to 1.
+ * The probability we sample any given allocation when recording
+ * allocations. Must be between 0 and 1 -- defaults to 1.
* @param {number} options.maxLogLength
* The maximum number of allocation events to keep in the
* log. If new allocs occur while at capacity, oldest
* allocations are lost. Must fit in a 32 bit signed integer.
* @param {number} options.drainAllocationsTimeout
- * A number in milliseconds of how often, at least, an `allocation` event
- * gets emitted (and drained), and also emits and drains on every GC event,
- * resetting the timer.
+ * A number in milliseconds of how often, at least, an `allocation`
+ * event gets emitted (and drained), and also emits and drains on every
+ * GC event, resetting the timer.
*/
- startRecordingAllocations: expectState("attached", function (options = {}) {
+ startRecordingAllocations: expectState("attached", function ({
+ probability = 1,
+ drainAllocationsTimeout = null,
+ maxLogLength = null
+ }) {
if (this.isRecordingAllocations()) {
return this._getCurrentTime();
}
this._frameCache.initFrames();
- this.dbg.memory.allocationSamplingProbability = options.probability != null
- ? options.probability
- : 1.0;
-
- this.drainAllocationsTimeoutTimer = typeof options.drainAllocationsTimeout === "number" ? options.drainAllocationsTimeout : null;
+ this.dbg.memory.allocationSamplingProbability = probability;
+ this.drainAllocationsTimeoutTimer = drainAllocationsTimeout;
if (this.drainAllocationsTimeoutTimer != null) {
if (this._poller) {
this._poller.disarm();
}
- this._poller = new DeferredTask(this._emitAllocations, this.drainAllocationsTimeoutTimer);
+ this._poller = new DeferredTask(this._emitAllocations,
+ this.drainAllocationsTimeoutTimer);
this._poller.arm();
}
- if (options.maxLogLength != null) {
- this.dbg.memory.maxAllocationsLogLength = options.maxLogLength;
+ if (maxLogLength != null) {
+ this.dbg.memory.maxAllocationsLogLength = maxLogLength;
}
this.dbg.memory.trackingAllocationSites = true;
return this._getCurrentTime();
}, "starting recording allocations"),
/**
* Stop recording allocation sites.
@@ -257,17 +262,18 @@ var Memory = exports.Memory = Class({
* <bytesize for allocations[1]>,
* ...
* ],
* frames: [
* {
* line: <line number for this frame>,
* column: <column number for this frame>,
* source: <filename string for this frame>,
- * functionDisplayName: <this frame's inferred function name function or null>,
+ * functionDisplayName:
+ * <this frame's inferred function name function or null>,
* parent: <index into "frames">
* },
* ...
* ],
* }
*
* The timestamps' unit is microseconds since the epoch.
*
@@ -364,17 +370,18 @@ var Memory = exports.Memory = Class({
let styleSize = {};
let otherSize = {};
let totalSize = {};
let jsMilliseconds = {};
let nonJSMilliseconds = {};
try {
this._mgr.sizeOfTab(this.parent.window, jsObjectsSize, jsStringsSize, jsOtherSize,
- domSize, styleSize, otherSize, totalSize, jsMilliseconds, nonJSMilliseconds);
+ domSize, styleSize, otherSize, totalSize, jsMilliseconds,
+ nonJSMilliseconds);
result.total = totalSize.value;
result.domSize = domSize.value;
result.styleSize = styleSize.value;
result.jsObjectsSize = jsObjectsSize.value;
result.jsStringsSize = jsStringsSize.value;
result.jsOtherSize = jsOtherSize.value;
result.otherSize = otherSize.value;
result.jsMilliseconds = jsMilliseconds.value.toFixed(1);
@@ -399,27 +406,28 @@ var Memory = exports.Memory = Class({
// If `drainAllocationsTimeout` set, fire an allocations event with the drained log,
// which will restart the timer.
if (this._poller) {
this._poller.disarm();
this._emitAllocations();
}
},
-
/**
- * Called on `drainAllocationsTimeoutTimer` interval if and only if set during `startRecordingAllocations`,
- * or on a garbage collection event if drainAllocationsTimeout was set.
+ * Called on `drainAllocationsTimeoutTimer` interval if and only if set
+ * during `startRecordingAllocations`, or on a garbage collection event if
+ * drainAllocationsTimeout was set.
* Drains allocation log and emits as an event and restarts the timer.
*/
_emitAllocations: function () {
events.emit(this, "allocations", this.getAllocations());
this._poller.arm();
},
/**
* Accesses the docshell to return the current process time.
*/
_getCurrentTime: function () {
- return (this.parent.isRootActor ? this.parent.docShell : this.parent.originalDocShell).now();
+ return (this.parent.isRootActor ? this.parent.docShell :
+ this.parent.originalDocShell).now();
},
});
--- a/devtools/server/performance/profiler.js
+++ b/devtools/server/performance/profiler.js
@@ -14,18 +14,18 @@ loader.lazyRequireGetter(this, "Task", "
// Events piped from system observers to Profiler instances.
const PROFILER_SYSTEM_EVENTS = [
"console-api-profiler",
"profiler-started",
"profiler-stopped"
];
-// How often the "profiler-status" is emitted by default
-const BUFFER_STATUS_INTERVAL_DEFAULT = 5000; // ms
+// How often the "profiler-status" is emitted by default (in ms)
+const BUFFER_STATUS_INTERVAL_DEFAULT = 5000;
loader.lazyGetter(this, "nsIProfilerModule", () => {
return Cc["@mozilla.org/tools/profiler;1"].getService(Ci.nsIProfiler);
});
var DEFAULT_PROFILER_OPTIONS = {
// When using the DevTools Performance Tools, this will be overridden
// by the pref `devtools.performance.profiler.buffer-size`.
@@ -169,22 +169,22 @@ const ProfilerManager = (function () {
* time: number
* } ... ]
* } ... ]
* }
*
*
* @param number startTime
* Since the circular buffer will only grow as long as the profiler lives,
- * the buffer can contain unwanted samples. Pass in a `startTime` to only retrieve
- * samples that took place after the `startTime`, with 0 being when the profiler
- * just started.
+ * the buffer can contain unwanted samples. Pass in a `startTime` to only
+ * retrieve samples that took place after the `startTime`, with 0 being
+ * when the profiler just started.
* @param boolean stringify
- * Whether or not the returned profile object should be a string or not to save
- * JSON parse/stringify cycle if emitting over RDP.
+ * Whether or not the returned profile object should be a string or not to
+ * save JSON parse/stringify cycle if emitting over RDP.
*/
getProfile: function (options) {
let startTime = options.startTime || 0;
let profile = options.stringify ?
nsIProfilerModule.GetProfile(startTime) :
nsIProfilerModule.getProfileData(startTime);
return { profile: profile, currentTime: nsIProfilerModule.getElapsedTime() };
@@ -233,26 +233,34 @@ const ProfilerManager = (function () {
* If already active, the current time is also returned.
*
* @return {object}
*/
isActive: function () {
let isActive = nsIProfilerModule.IsActive();
let elapsedTime = isActive ? nsIProfilerModule.getElapsedTime() : undefined;
let { position, totalSize, generation } = this.getBufferInfo();
- return { isActive: isActive, currentTime: elapsedTime, position, totalSize, generation };
+ return {
+ isActive,
+ currentTime: elapsedTime,
+ position,
+ totalSize,
+ generation
+ };
},
/**
* Returns a stringified JSON object that describes the shared libraries
* which are currently loaded into our process. Can be called while the
* profiler is stopped.
*/
getSharedLibraryInformation: function () {
- return { sharedLibraryInformation: nsIProfilerModule.getSharedLibraryInformation() };
+ return {
+ sharedLibraryInformation: nsIProfilerModule.getSharedLibraryInformation()
+ };
},
/**
* Number of profiler instances.
*
* @return {number}
*/
get length() {
@@ -271,28 +279,28 @@ const ProfilerManager = (function () {
// An optional label may be specified when calling `console.profile`.
// If that's the case, stringify it and send it over with the response.
let { action, arguments: args } = subject || {};
let profileLabel = args && args.length > 0 ? `${args[0]}` : void 0;
// If the event was generated from `console.profile` or `console.profileEnd`
// we need to start the profiler right away and then just notify the client.
// Otherwise, we'll lose precious samples.
- if (topic === "console-api-profiler" && (action === "profile" || action === "profileEnd")) {
+ if (topic === "console-api-profiler" &&
+ (action === "profile" || action === "profileEnd")) {
let { isActive, currentTime } = this.isActive();
// Start the profiler only if it wasn't already active. Otherwise, any
// samples that might have been accumulated so far will be discarded.
if (!isActive && action === "profile") {
this.start();
details = { profileLabel, currentTime: 0 };
- }
- // Otherwise, if inactive and a call to profile end, do nothing
- // and don't emit event.
- else if (!isActive) {
+ } else if (!isActive) {
+ // Otherwise, if inactive and a call to profile end, do nothing
+ // and don't emit event.
return;
}
// Otherwise, the profiler is already active, so just send
// to the front the current time, label, and the notification
// adds the action as well.
details = { profileLabel, currentTime };
}
@@ -335,17 +343,19 @@ const ProfilerManager = (function () {
/**
* Takes an event name and additional data and emits them
* through each profiler instance that is subscribed to the event.
*
* @param {string} eventName
* @param {object} data
*/
emitEvent: function (eventName, data) {
- let subscribers = Array.from(consumers).filter(c => c.subscribedEvents.has(eventName));
+ let subscribers = Array.from(consumers).filter(c => {
+ return c.subscribedEvents.has(eventName);
+ });
for (let subscriber of subscribers) {
events.emit(subscriber, eventName, data);
}
},
/**
* Updates the frequency that the "profiler-status" event is emitted
@@ -372,22 +382,22 @@ const ProfilerManager = (function () {
/**
* Will enable or disable "profiler-status" events depending on
* if there are subscribers and if the profiler is current recording.
*/
_updateProfilerStatusPolling: function () {
if (this._profilerStatusSubscribers > 0 && nsIProfilerModule.IsActive()) {
if (!this._poller) {
- this._poller = new DeferredTask(this._emitProfilerStatus.bind(this), this._profilerStatusInterval);
+ this._poller = new DeferredTask(this._emitProfilerStatus.bind(this),
+ this._profilerStatusInterval);
}
this._poller.arm();
- }
- // No subscribers; turn off if it exists.
- else if (this._poller) {
+ } else if (this._poller) {
+ // No subscribers; turn off if it exists.
this._poller.disarm();
}
},
_emitProfilerStatus: function () {
this.emitEvent("profiler-status", this.isActive());
this._poller.arm();
}
@@ -409,57 +419,75 @@ var Profiler = exports.Profiler = Class(
this.unregisterEventNotifications({ events: Array.from(this.subscribedEvents) });
this.subscribedEvents = null;
ProfilerManager.removeInstance(this);
},
/**
* @see ProfilerManager.start
*/
- start: function (options) { return ProfilerManager.start(options); },
+ start: function (options) {
+ return ProfilerManager.start(options);
+ },
/**
* @see ProfilerManager.stop
*/
- stop: function () { return ProfilerManager.stop(); },
+ stop: function () {
+ return ProfilerManager.stop();
+ },
/**
* @see ProfilerManager.getProfile
*/
- getProfile: function (request = {}) { return ProfilerManager.getProfile(request); },
+ getProfile: function (request = {}) {
+ return ProfilerManager.getProfile(request);
+ },
/**
* @see ProfilerManager.getFeatures
*/
- getFeatures: function () { return ProfilerManager.getFeatures(); },
+ getFeatures: function () {
+ return ProfilerManager.getFeatures();
+ },
/**
* @see ProfilerManager.getBufferInfo
*/
- getBufferInfo: function () { return ProfilerManager.getBufferInfo(); },
+ getBufferInfo: function () {
+ return ProfilerManager.getBufferInfo();
+ },
/**
* @see ProfilerManager.getStartOptions
*/
- getStartOptions: function () { return ProfilerManager.getStartOptions(); },
+ getStartOptions: function () {
+ return ProfilerManager.getStartOptions();
+ },
/**
* @see ProfilerManager.isActive
*/
- isActive: function () { return ProfilerManager.isActive(); },
+ isActive: function () {
+ return ProfilerManager.isActive();
+ },
/**
* @see ProfilerManager.isActive
*/
- getSharedLibraryInformation: function () { return ProfilerManager.getSharedLibraryInformation(); },
+ getSharedLibraryInformation: function () {
+ return ProfilerManager.getSharedLibraryInformation();
+ },
/**
* @see ProfilerManager.setProfilerStatusInterval
*/
- setProfilerStatusInterval: function (interval) { return ProfilerManager.setProfilerStatusInterval(interval); },
+ setProfilerStatusInterval: function (interval) {
+ return ProfilerManager.setProfilerStatusInterval(interval);
+ },
/**
* Subscribes this instance to one of several events defined in
* an events array.
* - "console-api-profiler",
* - "profiler-started",
* - "profiler-stopped"
* - "profiler-status"
@@ -530,17 +558,18 @@ function cycleBreaker(key, value) {
*
* @TODO Also wraps it in a `makeInfallible` -- is this still necessary?
*
* @param {function} handler
* @return {function}
*/
function sanitizeHandler(handler, identifier) {
return DevToolsUtils.makeInfallible(function (subject, topic, data) {
- subject = (subject && !Cu.isXrayWrapper(subject) && subject.wrappedJSObject) || subject;
+ subject = (subject && !Cu.isXrayWrapper(subject) && subject.wrappedJSObject)
+ || subject;
subject = JSON.parse(JSON.stringify(subject, cycleBreaker));
data = (data && !Cu.isXrayWrapper(data) && data.wrappedJSObject) || data;
data = JSON.parse(JSON.stringify(data, cycleBreaker));
// Pass in clean data to the underlying handler
return handler.call(this, subject, topic, data);
}, identifier);
}
--- a/devtools/server/performance/recorder.js
+++ b/devtools/server/performance/recorder.js
@@ -1,14 +1,14 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
-const { Cc, Ci, Cu, Cr } = require("chrome");
+const { Cu } = require("chrome");
const { Task } = require("devtools/shared/task");
loader.lazyRequireGetter(this, "Services");
loader.lazyRequireGetter(this, "promise");
loader.lazyRequireGetter(this, "extend",
"sdk/util/object", true);
loader.lazyRequireGetter(this, "Class",
"sdk/core/heritage", true);
@@ -47,17 +47,17 @@ const DRAIN_ALLOCATIONS_TIMEOUT = 2000;
/**
* A connection to underlying actors (profiler, memory, framerate, etc.)
* shared by all tools in a target.
*
* @param Target target
* The target owning this connection.
*/
-const PerformanceRecorder = exports.PerformanceRecorder = Class({
+exports.PerformanceRecorder = Class({
extends: EventTarget,
initialize: function (conn, tabActor) {
this.conn = conn;
this.tabActor = tabActor;
this._pendingConsoleRecordings = [];
this._recordings = [];
@@ -166,29 +166,29 @@ const PerformanceRecorder = exports.Perf
* Invoked whenever `console.profile` is called.
*
* @param string profileLabel
* The provided string argument if available; undefined otherwise.
* @param number currentTime
* The time (in milliseconds) when the call was made, relative to when
* the nsIProfiler module was started.
*/
- _onConsoleProfileStart: Task.async(function* ({ profileLabel, currentTime: startTime }) {
+ _onConsoleProfileStart: Task.async(function* ({ profileLabel, currentTime }) {
let recordings = this._recordings;
// Abort if a profile with this label already exists.
if (recordings.find(e => e.getLabel() === profileLabel)) {
return;
}
// Immediately emit this so the client can start setting things up,
// expecting a recording very soon.
events.emit(this, "console-profile-start");
- let model = yield this.startRecording(extend({}, getPerformanceRecordingPrefs(), {
+ yield this.startRecording(extend({}, getPerformanceRecordingPrefs(), {
console: true,
label: profileLabel
}));
}),
/**
* Invoked whenever `console.profileEnd` is called.
*
@@ -199,38 +199,38 @@ const PerformanceRecorder = exports.Perf
* the nsIProfiler module was started.
*/
_onConsoleProfileEnd: Task.async(function* (data) {
// If no data, abort; can occur if profiler isn't running and we get a surprise
// call to console.profileEnd()
if (!data) {
return;
}
- let { profileLabel, currentTime: endTime } = data;
+ let { profileLabel } = data;
let pending = this._recordings.filter(r => r.isConsole() && r.isRecording());
if (pending.length === 0) {
return;
}
let model;
// Try to find the corresponding `console.profile` call if
// a label was used in profileEnd(). If no matches, abort.
if (profileLabel) {
model = pending.find(e => e.getLabel() === profileLabel);
- }
- // If no label supplied, pop off the most recent pending console recording
- else {
+ } else {
+ // If no label supplied, pop off the most recent pending console recording
model = pending[pending.length - 1];
}
// If `profileEnd()` was called with a label, and there are no matching
// sessions, abort.
if (!model) {
- Cu.reportError("console.profileEnd() called with label that does not match a recording.");
+ Cu.reportError(
+ "console.profileEnd() called with label that does not match a recording.");
return;
}
yield this.stopRecording(model);
}),
/**
* TODO handle bug 1144438
@@ -286,17 +286,17 @@ const PerformanceRecorder = exports.Perf
* Checks whether or not recording is currently supported. At the moment,
* this is only influenced by private browsing mode and the profiler.
*/
canCurrentlyRecord: function () {
let success = true;
let reasons = [];
if (!Profiler.canProfile()) {
- success = false,
+ success = false;
reasons.push("profiler-unavailable");
}
// Check other factors that will affect the possibility of successfully
// starting a recording here.
return { success, reasons };
},
@@ -321,17 +321,19 @@ const PerformanceRecorder = exports.Perf
startRecording: Task.async(function* (options) {
let profilerStart, timelineStart, memoryStart;
profilerStart = Task.spawn(function* () {
let data = yield this._profiler.isActive();
if (data.isActive) {
return data;
}
- let startData = yield this._profiler.start(mapRecordingOptions("profiler", options));
+ let startData = yield this._profiler.start(
+ mapRecordingOptions("profiler", options)
+ );
// If no current time is exposed from starting, set it to 0 -- this is an
// older Gecko that does not return its starting time, and uses an epoch based
// on the profiler's start time.
if (startData.currentTime == null) {
startData.currentTime = 0;
}
return startData;
@@ -342,29 +344,34 @@ const PerformanceRecorder = exports.Perf
if (options.withMarkers || options.withTicks || options.withMemory) {
timelineStart = this._timeline.start(mapRecordingOptions("timeline", options));
}
if (options.withAllocations) {
if (this._memory.getState() === "detached") {
this._memory.attach();
}
- memoryStart = this._memory.startRecordingAllocations(extend(mapRecordingOptions("memory", options), {
+ let recordingOptions = extend(mapRecordingOptions("memory", options), {
drainAllocationsTimeout: DRAIN_ALLOCATIONS_TIMEOUT
- }));
+ });
+ memoryStart = this._memory.startRecordingAllocations(recordingOptions);
}
let [profilerStartData, timelineStartData, memoryStartData] = yield promise.all([
profilerStart, timelineStart, memoryStart
]);
let data = Object.create(null);
// Filter out start times that are not actually used (0 or undefined), and
// find the earliest time since all sources use same epoch.
- let startTimes = [profilerStartData.currentTime, memoryStartData, timelineStartData].filter(Boolean);
+ let startTimes = [
+ profilerStartData.currentTime,
+ memoryStartData,
+ timelineStartData
+ ].filter(Boolean);
data.startTime = Math.min(...startTimes);
data.position = profilerStartData.position;
data.generation = profilerStartData.generation;
data.totalSize = profilerStartData.totalSize;
data.systemClient = this._systemClient;
data.systemHost = yield getSystemInfo();
@@ -374,32 +381,32 @@ const PerformanceRecorder = exports.Perf
events.emit(this, "recording-started", model);
return model;
}),
/**
* Manually ends the recording session for the corresponding PerformanceRecording.
*
* @param PerformanceRecording model
- * The corresponding PerformanceRecording that belongs to the recording session wished to stop.
+ * The corresponding PerformanceRecording that belongs to the recording
+ * session wished to stop.
* @return PerformanceRecording
* Returns the same model, populated with the profiling data.
*/
stopRecording: Task.async(function* (model) {
// If model isn't in the Recorder's internal store,
// then do nothing, like if this was a console.profileEnd
// from a different target.
if (this._recordings.indexOf(model) === -1) {
return model;
}
// Flag the recording as no longer recording, so that `model.isRecording()`
// is false. Do this before we fetch all the data, and then subsequently
// the recording can be considered "completed".
- let endTime = Date.now();
events.emit(this, "recording-stopping", model);
// Currently there are two ways profiles stop recording. Either manually in the
// performance tool, or via console.profileEnd. Once a recording is done,
// we want to deliver the model to the performance tool (either as a return
// from the PerformanceFront or via `console-profile-stop` event) and then
// remove it from the internal store.
//
@@ -475,20 +482,24 @@ const PerformanceRecorder = exports.Perf
return extend({}, allocationSettings, this._profiler.getStartOptions());
},
toString: () => "[object PerformanceRecorder]"
});
/**
- * Creates an object of configurations based off of preferences for a PerformanceRecording.
+ * Creates an object of configurations based off of
+ * preferences for a PerformanceRecording.
*/
function getPerformanceRecordingPrefs() {
return {
withMarkers: true,
withMemory: Services.prefs.getBoolPref("devtools.performance.ui.enable-memory"),
withTicks: Services.prefs.getBoolPref("devtools.performance.ui.enable-framerate"),
- withAllocations: Services.prefs.getBoolPref("devtools.performance.ui.enable-allocations"),
- allocationsSampleProbability: +Services.prefs.getCharPref("devtools.performance.memory.sample-probability"),
- allocationsMaxLogLength: Services.prefs.getIntPref("devtools.performance.memory.max-log-length")
+ withAllocations:
+ Services.prefs.getBoolPref("devtools.performance.ui.enable-allocations"),
+ allocationsSampleProbability:
+ +Services.prefs.getCharPref("devtools.performance.memory.sample-probability"),
+ allocationsMaxLogLength:
+ Services.prefs.getIntPref("devtools.performance.memory.max-log-length")
};
}
--- a/devtools/server/performance/timeline.js
+++ b/devtools/server/performance/timeline.js
@@ -28,23 +28,23 @@ loader.lazyRequireGetter(this, "events",
loader.lazyRequireGetter(this, "Task", "devtools/shared/task", true);
loader.lazyRequireGetter(this, "Memory", "devtools/server/performance/memory", true);
loader.lazyRequireGetter(this, "Framerate", "devtools/server/performance/framerate", true);
loader.lazyRequireGetter(this, "StackFrameCache", "devtools/server/actors/utils/stack", true);
loader.lazyRequireGetter(this, "EventTarget", "sdk/event/target", true);
// How often do we pull markers from the docShells, and therefore, how often do
// we send events to the front (knowing that when there are no markers in the
-// docShell, no event is sent).
-const DEFAULT_TIMELINE_DATA_PULL_TIMEOUT = 200; // ms
+// docShell, no event is sent). In milliseconds.
+const DEFAULT_TIMELINE_DATA_PULL_TIMEOUT = 200;
/**
* The timeline actor pops and forwards timeline markers registered in docshells.
*/
-var Timeline = exports.Timeline = Class({
+exports.Timeline = Class({
extends: EventTarget,
/**
* Initializes this actor with the provided connection and tab actor.
*/
initialize: function (tabActor) {
this.tabActor = tabActor;
@@ -130,17 +130,19 @@ var Timeline = exports.Timeline = Class(
// frames to the client. We must waive xrays here because Firefox
// doesn't understand that the Debugger.Frame object is safe to
// use from chrome. See Tutorial-Alloc-Log-Tree.md.
if (this._withFrames) {
if (marker.stack) {
marker.stack = this._stackFrames.addFrame(Cu.waiveXrays(marker.stack));
}
if (marker.endStack) {
- marker.endStack = this._stackFrames.addFrame(Cu.waiveXrays(marker.endStack));
+ marker.endStack = this._stackFrames.addFrame(
+ Cu.waiveXrays(marker.endStack)
+ );
}
}
// Emit some helper events for "DOMContentLoaded" and "Load" markers.
if (this._withDocLoadingEvents) {
if (marker.name == "document::DOMContentLoaded" ||
marker.name == "document::Load") {
events.emit(this, "doc-loading", marker, endTime);
@@ -325,29 +327,33 @@ var Timeline = exports.Timeline = Class(
}
},
/**
* Fired when the Memory component emits a `garbage-collection` event. Used to
* take the data and make it look like the rest of our markers.
*
* A GC "marker" here represents a full GC cycle, which may contain several incremental
- * events within its `collection` array. The marker contains a `reason` field, indicating
- * why there was a GC, and may contain a `nonincrementalReason` when SpiderMonkey could
- * not incrementally collect garbage.
+ * events within its `collection` array. The marker contains a `reason` field,
+ * indicating why there was a GC, and may contain a `nonincrementalReason` when
+ * SpiderMonkey could not incrementally collect garbage.
*/
- _onGarbageCollection: function ({ collections, gcCycleNumber, reason, nonincrementalReason }) {
+ _onGarbageCollection: function ({
+ collections, gcCycleNumber, reason, nonincrementalReason
+ }) {
let docShells = this.docShells;
if (!this._isRecording || !docShells.length) {
return;
}
let endTime = docShells[0].now();
- events.emit(this, "markers", collections.map(({ startTimestamp: start, endTimestamp: end }) => {
+ events.emit(this, "markers", collections.map(({
+ startTimestamp: start, endTimestamp: end
+ }) => {
return {
name: "GarbageCollection",
causeName: reason,
nonincrementalReason: nonincrementalReason,
cycle: gcCycleNumber,
start,
end,
};