129 lines
4.3 KiB
JavaScript
129 lines
4.3 KiB
JavaScript
/* 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";
|
|
|
|
// The functions in the class use standard functions called from tracer.js but we want to keep the
|
|
// arguments intact.
|
|
/* eslint "no-unused-vars": ["error", {args: "none"} ]*/
|
|
|
|
class ProfilerTracingListener {
|
|
constructor({ targetActor, traceActor }) {
|
|
this.targetActor = targetActor;
|
|
this.traceActor = traceActor;
|
|
}
|
|
|
|
/**
|
|
* Stop the record and return the gecko profiler data.
|
|
*
|
|
* @param {Object} nativeTrace
|
|
* If we're using native tracing, this contains a table of what the
|
|
* native tracer has collected.
|
|
* @return {Object}
|
|
* The Gecko profile object.
|
|
*/
|
|
async stop(nativeTrace) {
|
|
// Pause profiler before we collect the profile, so that we don't capture
|
|
// more samples while the parent process or android threads wait for subprocess profiles.
|
|
Services.profiler.Pause();
|
|
|
|
let profile;
|
|
try {
|
|
// Attempt to pull out the data.
|
|
profile = await Services.profiler.getProfileDataAsync();
|
|
|
|
if (Object.keys(profile).length === 0) {
|
|
console.error(
|
|
"An empty object was received from getProfileDataAsync.getProfileDataAsync(), " +
|
|
"meaning that a profile could not successfully be serialized and captured."
|
|
);
|
|
profile = null;
|
|
}
|
|
} catch (e) {
|
|
// Explicitly set the profile to null if there as an error.
|
|
profile = null;
|
|
console.error(`There was an error fetching a profile`, e);
|
|
}
|
|
|
|
Services.profiler.StopProfiler();
|
|
|
|
return profile;
|
|
}
|
|
|
|
/**
|
|
* Be notified by the underlying JavaScriptTracer class
|
|
* in case it stops by itself, instead of being stopped when the Actor's stopTracing
|
|
* method is called by the user.
|
|
*
|
|
* @param {Boolean} enabled
|
|
* True if the tracer starts tracing, false it it stops.
|
|
* @return {Boolean}
|
|
* Return true, if the JavaScriptTracer should log a message to stdout.
|
|
*/
|
|
onTracingToggled(enabled) {
|
|
if (!enabled) {
|
|
this.traceActor.stopTracing();
|
|
} else {
|
|
Services.profiler.StartProfiler(
|
|
// Note that this is the same default as profiler ones defined in:
|
|
// devtools/client/performance-new/shared/background.sys.mjs
|
|
128 * 1024 * 1024,
|
|
1,
|
|
["screenshots", "tracing"],
|
|
["GeckoMain", "DOM Worker"],
|
|
this.targetActor.sessionContext.browserId,
|
|
0
|
|
);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Called when "trace on next user interaction" is enabled, to notify the user
|
|
* that the tracer is initialized but waiting for the user first input.
|
|
*/
|
|
onTracingPending() {
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Called by JavaScriptTracer class when a new mutation happened on any DOM Element.
|
|
*
|
|
* @param {Object} options
|
|
* @param {Number} options.depth
|
|
* Represents the depth of the frame in the call stack.
|
|
* @param {String} options.prefix
|
|
* A string to be displayed as a prefix of any logged frame.
|
|
* @param {nsIStackFrame} options.caller
|
|
* The JS Callsite which caused this mutation.
|
|
* @param {String} options.type
|
|
* Type of DOM Mutation:
|
|
* - "add": Node being added,
|
|
* - "attributes": Node whose attributes changed,
|
|
* - "remove": Node being removed,
|
|
* @param {DOMNode} options.element
|
|
* The DOM Node related to the current mutation.
|
|
* @return {Boolean}
|
|
* Return true, if the JavaScriptTracer should log a message to stdout.
|
|
*/
|
|
onTracingDOMMutation({ depth, prefix, type, caller, element }) {
|
|
let elementDescription = element.tagName?.toLowerCase();
|
|
if (element.id) {
|
|
elementDescription += `#${element.id}`;
|
|
}
|
|
if (element.className) {
|
|
elementDescription += `.${element.className.trim().replace(/ +/g, ".")}`;
|
|
}
|
|
|
|
const description = `${type} on ${elementDescription}`;
|
|
|
|
// Bug 1904602: we need a tweak in profiler frontend before being able to show
|
|
// dom mutation in the stack chart. Until then, add a custom marker.
|
|
ChromeUtils.addProfilerMarker("DOM-Mutation", undefined, description);
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
exports.ProfilerTracingListener = ProfilerTracingListener;
|