mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 23:35:34 +00:00
Bug 1504133 - Make TalosParentProfiler a singleton module. r=aswan
Differential Revision: https://phabricator.services.mozilla.com/D11259 --HG-- rename : testing/talos/talos/talos-powers/content/TalosParentProfiler.js => testing/talos/talos/talos-powers/content/TalosParentProfiler.jsm extra : moz-landing-system : lando
This commit is contained in:
parent
a4065c4324
commit
983205d86f
@ -8,10 +8,8 @@
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/E10SUtils.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyScriptGetter(this, "TalosParentProfiler",
|
||||
"resource://talos-powers/TalosParentProfiler.js");
|
||||
ChromeUtils.defineModuleGetter(this, "TalosParentProfiler",
|
||||
"resource://talos-powers/TalosParentProfiler.jsm");
|
||||
|
||||
var NUM_CYCLES = 5;
|
||||
var numPageCycles = 1;
|
||||
|
@ -13,11 +13,9 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
SessionStartup: "resource:///modules/sessionstore/SessionStartup.jsm",
|
||||
setTimeout: "resource://gre/modules/Timer.jsm",
|
||||
StartupPerformance: "resource:///modules/sessionstore/StartupPerformance.jsm",
|
||||
TalosParentProfiler: "resource://talos-powers/TalosParentProfiler.jsm",
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyScriptGetter(this, "TalosParentProfiler",
|
||||
"resource://talos-powers/TalosParentProfiler.js");
|
||||
|
||||
/* globals ExtensionAPI */
|
||||
|
||||
this.sessionrestore = class extends ExtensionAPI {
|
||||
|
@ -1,213 +0,0 @@
|
||||
/* 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/. */
|
||||
|
||||
/**
|
||||
* This utility script is for instrumenting your Talos test for
|
||||
* performance profiles while running within the parent process.
|
||||
* Almost all of the functions that this script exposes to the
|
||||
* Gecko Profiler are synchronous, except for finishTest, since that
|
||||
* involves requesting the profiles from any content processes and
|
||||
* then writing to disk.
|
||||
*
|
||||
* If your test is running in the content process, you should use
|
||||
* TalosContentProfiler.js instead.
|
||||
*/
|
||||
|
||||
var TalosParentProfiler;
|
||||
|
||||
(function() {
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// Whether or not this TalosContentProfiler object has had initFromObject
|
||||
// or initFromURLQueryParams called on it. Any functions that change the
|
||||
// state of the Gecko Profiler should only be called after calling either
|
||||
// initFromObject or initFromURLQueryParams.
|
||||
let initted = Services.profiler.IsActive();
|
||||
|
||||
// The subtest name that beginTest() was called with.
|
||||
let currentTest = "unknown";
|
||||
|
||||
// Profiler settings.
|
||||
let interval, entries, threadsArray, profileDir;
|
||||
|
||||
// Use a bit of XPCOM hackery to get at the Talos Powers service
|
||||
// implementation...
|
||||
let TalosPowers =
|
||||
Cc["@mozilla.org/talos/talos-powers-service;1"]
|
||||
.getService(Ci.nsISupports)
|
||||
.wrappedJSObject;
|
||||
|
||||
/**
|
||||
* Parses an url query string into a JS object.
|
||||
*
|
||||
* @param locationSearch (string)
|
||||
* The location string to parse.
|
||||
* @returns Object
|
||||
* The GET params from the location string as
|
||||
* key-value pairs in the Object.
|
||||
*/
|
||||
function searchToObject(locationSearch) {
|
||||
let pairs = locationSearch.substring(1).split("&");
|
||||
let result = {};
|
||||
|
||||
for (let i in pairs) {
|
||||
if (pairs[i] !== "") {
|
||||
let pair = pairs[i].split("=");
|
||||
result[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || "");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TalosParentProfiler = {
|
||||
/**
|
||||
* Initialize the profiler using profiler settings supplied in a JS object.
|
||||
*
|
||||
* @param obj (object)
|
||||
* The following properties on the object are respected:
|
||||
* gecko_profile_interval (int)
|
||||
* gecko_profile_entries (int)
|
||||
* gecko_profile_threads (string, comma separated list of threads to filter with)
|
||||
* gecko_profile_dir (string)
|
||||
*/
|
||||
initFromObject(obj = {}) {
|
||||
if (!initted) {
|
||||
if (("gecko_profile_dir" in obj) && typeof obj.gecko_profile_dir == "string" &&
|
||||
("gecko_profile_interval" in obj) && Number.isFinite(obj.gecko_profile_interval * 1) &&
|
||||
("gecko_profile_entries" in obj) && Number.isFinite(obj.gecko_profile_entries * 1) &&
|
||||
("gecko_profile_threads" in obj) && typeof obj.gecko_profile_threads == "string") {
|
||||
interval = obj.gecko_profile_interval;
|
||||
entries = obj.gecko_profile_entries;
|
||||
threadsArray = obj.gecko_profile_threads.split(",");
|
||||
profileDir = obj.gecko_profile_dir;
|
||||
initted = true;
|
||||
} else {
|
||||
console.error("Profiler could not init with object: " + JSON.stringify(obj));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize the profiler using a string from a location string.
|
||||
*
|
||||
* @param locationSearch (string)
|
||||
* The location string to initialize with.
|
||||
*/
|
||||
initFromURLQueryParams(locationSearch) {
|
||||
this.initFromObject(searchToObject(locationSearch));
|
||||
},
|
||||
|
||||
/**
|
||||
* A Talos test is about to start. Note that the Gecko Profiler will be
|
||||
* paused immediately after starting and that resume() should be called
|
||||
* in order to collect samples.
|
||||
*
|
||||
* @param testName (string)
|
||||
* The name of the test to use in Profiler markers.
|
||||
*/
|
||||
beginTest(testName) {
|
||||
if (initted) {
|
||||
currentTest = testName;
|
||||
TalosPowers.profilerBegin({ entries, interval, threadsArray });
|
||||
} else {
|
||||
let msg = "You should not call beginTest without having first " +
|
||||
"initted the Profiler";
|
||||
console.error(msg);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* A Talos test has finished. This will stop the Gecko Profiler from
|
||||
* sampling, and return a Promise that resolves once the Profiler has
|
||||
* finished dumping the multi-process profile to disk.
|
||||
*
|
||||
* @returns Promise
|
||||
* Resolves once the profile has been dumped to disk. The test should
|
||||
* not try to quit the browser until this has resolved.
|
||||
*/
|
||||
finishTest() {
|
||||
if (initted) {
|
||||
let profileFile = profileDir + "/" + currentTest + ".profile";
|
||||
return TalosPowers.profilerFinish(profileFile);
|
||||
}
|
||||
let msg = "You should not call finishTest without having first " +
|
||||
"initted the Profiler";
|
||||
console.error(msg);
|
||||
return Promise.reject(msg);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* A start-up test has finished. Callers don't need to run beginTest or
|
||||
* finishTest, but should pause the sampler as soon as possible, and call
|
||||
* this function to dump the profile.
|
||||
*
|
||||
* @returns Promise
|
||||
* Resolves once the profile has been dumped to disk. The test should
|
||||
* not try to quit the browser until this has resolved.
|
||||
*/
|
||||
finishStartupProfiling() {
|
||||
if (initted) {
|
||||
let profileFile = profileDir + "/startup.profile";
|
||||
return TalosPowers.profilerFinish(profileFile);
|
||||
}
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
/**
|
||||
* Resumes the Gecko Profiler sampler. Can also simultaneously set a marker.
|
||||
*
|
||||
* @returns Promise
|
||||
* Resolves once the Gecko Profiler has resumed.
|
||||
*/
|
||||
resume(marker = "") {
|
||||
if (initted) {
|
||||
TalosPowers.profilerResume(marker);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Pauses the Gecko Profiler sampler. Can also simultaneously set a marker.
|
||||
*
|
||||
* @returns Promise
|
||||
* Resolves once the Gecko Profiler has paused.
|
||||
*/
|
||||
pause(marker = "") {
|
||||
if (initted) {
|
||||
TalosPowers.profilerPause(marker);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a marker to the profile.
|
||||
*
|
||||
* @returns Promise
|
||||
* Resolves once the marker has been set.
|
||||
*/
|
||||
mark(marker) {
|
||||
if (initted) {
|
||||
// If marker is omitted, just use the test name
|
||||
if (!marker) {
|
||||
marker = currentTest;
|
||||
}
|
||||
|
||||
TalosPowers.profilerMarker(marker);
|
||||
}
|
||||
},
|
||||
|
||||
afterProfileGathered() {
|
||||
if (!initted) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return new Promise(resolve => {
|
||||
Services.obs.addObserver(function onGathered() {
|
||||
Services.obs.removeObserver(onGathered, "talos-profile-gathered");
|
||||
resolve();
|
||||
}, "talos-profile-gathered");
|
||||
});
|
||||
},
|
||||
};
|
||||
})();
|
217
testing/talos/talos/talos-powers/content/TalosParentProfiler.jsm
Normal file
217
testing/talos/talos/talos-powers/content/TalosParentProfiler.jsm
Normal file
@ -0,0 +1,217 @@
|
||||
/* 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/. */
|
||||
|
||||
/**
|
||||
* This module is for instrumenting your Talos test for
|
||||
* performance profiles while running within the parent process.
|
||||
* Almost all of the functions that this script exposes to the
|
||||
* Gecko Profiler are synchronous, except for finishTest, since that
|
||||
* involves requesting the profiles from any content processes and
|
||||
* then writing to disk.
|
||||
*
|
||||
* If your test is running in the content process, you should use the
|
||||
* TalosContentProfiler.js utility script instead.
|
||||
*/
|
||||
|
||||
var EXPORTED_SYMBOLS = ["TalosParentProfiler"];
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const TalosParentProfiler = {
|
||||
// Whether or not this TalosContentProfiler object has had initFromObject
|
||||
// or initFromURLQueryParams called on it. Any functions that change the
|
||||
// state of the Gecko Profiler should only be called after calling either
|
||||
// initFromObject or initFromURLQueryParams.
|
||||
initted: false,
|
||||
// The subtest name that beginTest() was called with.
|
||||
currentTest: "unknown",
|
||||
// Profiler settings.
|
||||
interval: undefined,
|
||||
entries: undefined,
|
||||
threadsArray: undefined,
|
||||
profileDir: undefined,
|
||||
|
||||
get TalosPowers() {
|
||||
// Use a bit of XPCOM hackery to get at the Talos Powers service
|
||||
// implementation...
|
||||
return Cc["@mozilla.org/talos/talos-powers-service;1"]
|
||||
.getService(Ci.nsISupports)
|
||||
.wrappedJSObject;
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize the profiler using profiler settings supplied in a JS object.
|
||||
*
|
||||
* @param obj (object)
|
||||
* The following properties on the object are respected:
|
||||
* gecko_profile_interval (int)
|
||||
* gecko_profile_entries (int)
|
||||
* gecko_profile_threads (string, comma separated list of threads to filter with)
|
||||
* gecko_profile_dir (string)
|
||||
*/
|
||||
initFromObject(obj = {}) {
|
||||
if (!this.initted) {
|
||||
if (("gecko_profile_dir" in obj) && typeof obj.gecko_profile_dir == "string" &&
|
||||
("gecko_profile_interval" in obj) && Number.isFinite(obj.gecko_profile_interval * 1) &&
|
||||
("gecko_profile_entries" in obj) && Number.isFinite(obj.gecko_profile_entries * 1) &&
|
||||
("gecko_profile_threads" in obj) && typeof obj.gecko_profile_threads == "string") {
|
||||
this.interval = obj.gecko_profile_interval;
|
||||
this.entries = obj.gecko_profile_entries;
|
||||
this.threadsArray = obj.gecko_profile_threads.split(",");
|
||||
this.profileDir = obj.gecko_profile_dir;
|
||||
this.initted = true;
|
||||
} else {
|
||||
console.error("Profiler could not init with object: " + JSON.stringify(obj));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize the profiler using a string from a location string.
|
||||
*
|
||||
* @param locationSearch (string)
|
||||
* The location string to initialize with.
|
||||
*/
|
||||
initFromURLQueryParams(locationSearch) {
|
||||
this.initFromObject(this.searchToObject(locationSearch));
|
||||
},
|
||||
|
||||
/**
|
||||
* Parses an url query string into a JS object.
|
||||
*
|
||||
* @param locationSearch (string)
|
||||
* The location string to parse.
|
||||
* @returns Object
|
||||
* The GET params from the location string as
|
||||
* key-value pairs in the Object.
|
||||
*/
|
||||
searchToObject(locationSearch) {
|
||||
let pairs = locationSearch.substring(1).split("&");
|
||||
let result = {};
|
||||
|
||||
for (let i in pairs) {
|
||||
if (pairs[i] !== "") {
|
||||
let pair = pairs[i].split("=");
|
||||
result[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || "");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* A Talos test is about to start. Note that the Gecko Profiler will be
|
||||
* paused immediately after starting and that resume() should be called
|
||||
* in order to collect samples.
|
||||
*
|
||||
* @param testName (string)
|
||||
* The name of the test to use in Profiler markers.
|
||||
*/
|
||||
beginTest(testName) {
|
||||
if (this.initted) {
|
||||
this.currentTest = testName;
|
||||
this.TalosPowers.profilerBegin({
|
||||
entries: this.entries,
|
||||
interval: this.interval,
|
||||
threadsArray: this.threadsArray,
|
||||
});
|
||||
} else {
|
||||
let msg = "You should not call beginTest without having first " +
|
||||
"initted the Profiler";
|
||||
console.error(msg);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* A Talos test has finished. This will stop the Gecko Profiler from
|
||||
* sampling, and return a Promise that resolves once the Profiler has
|
||||
* finished dumping the multi-process profile to disk.
|
||||
*
|
||||
* @returns Promise
|
||||
* Resolves once the profile has been dumped to disk. The test should
|
||||
* not try to quit the browser until this has resolved.
|
||||
*/
|
||||
finishTest() {
|
||||
if (this.initted) {
|
||||
let profileFile = this.profileDir + "/" + this.currentTest + ".profile";
|
||||
return this.TalosPowers.profilerFinish(profileFile);
|
||||
}
|
||||
let msg = "You should not call finishTest without having first " +
|
||||
"initted the Profiler";
|
||||
console.error(msg);
|
||||
return Promise.reject(msg);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* A start-up test has finished. Callers don't need to run beginTest or
|
||||
* finishTest, but should pause the sampler as soon as possible, and call
|
||||
* this function to dump the profile.
|
||||
*
|
||||
* @returns Promise
|
||||
* Resolves once the profile has been dumped to disk. The test should
|
||||
* not try to quit the browser until this has resolved.
|
||||
*/
|
||||
finishStartupProfiling() {
|
||||
if (this.initted) {
|
||||
let profileFile = this.profileDir + "/startup.profile";
|
||||
return this.TalosPowers.profilerFinish(profileFile);
|
||||
}
|
||||
return Promise.resolve();
|
||||
},
|
||||
|
||||
/**
|
||||
* Resumes the Gecko Profiler sampler. Can also simultaneously set a marker.
|
||||
*
|
||||
* @returns Promise
|
||||
* Resolves once the Gecko Profiler has resumed.
|
||||
*/
|
||||
resume(marker = "") {
|
||||
if (this.initted) {
|
||||
this.TalosPowers.profilerResume(marker);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Pauses the Gecko Profiler sampler. Can also simultaneously set a marker.
|
||||
*
|
||||
* @returns Promise
|
||||
* Resolves once the Gecko Profiler has paused.
|
||||
*/
|
||||
pause(marker = "") {
|
||||
if (this.initted) {
|
||||
this.TalosPowers.profilerPause(marker);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a marker to the profile.
|
||||
*
|
||||
* @returns Promise
|
||||
* Resolves once the marker has been set.
|
||||
*/
|
||||
mark(marker) {
|
||||
if (this.initted) {
|
||||
// If marker is omitted, just use the test name
|
||||
if (!marker) {
|
||||
marker = this.currentTest;
|
||||
}
|
||||
|
||||
this.TalosPowers.profilerMarker(marker);
|
||||
}
|
||||
},
|
||||
|
||||
afterProfileGathered() {
|
||||
if (!this.initted) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return new Promise(resolve => {
|
||||
Services.obs.addObserver(function onGathered() {
|
||||
Services.obs.removeObserver(onGathered, "talos-profile-gathered");
|
||||
resolve();
|
||||
}, "talos-profile-gathered");
|
||||
});
|
||||
},
|
||||
};
|
@ -2,9 +2,6 @@
|
||||
* 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/. */
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
|
||||
/**
|
||||
* The purpose of this test it to measure the performance of a
|
||||
* content process startup.
|
||||
@ -18,9 +15,8 @@ ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
* the content side, just the overhead of spawning a new content process.
|
||||
*/
|
||||
|
||||
XPCOMUtils.defineLazyScriptGetter(this, "TalosParentProfiler",
|
||||
"resource://talos-powers/TalosParentProfiler.js");
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "TalosParentProfiler",
|
||||
"resource://talos-powers/TalosParentProfiler.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
|
||||
|
@ -3,7 +3,6 @@ const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm
|
||||
const { AddonManager } = ChromeUtils.import("resource://gre/modules/AddonManager.jsm", {});
|
||||
const env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
|
||||
let scope = {};
|
||||
Services.scriptloader.loadSubScript("resource://talos-powers/TalosParentProfiler.js", scope);
|
||||
const { TalosParentProfiler } = scope;
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "require", function() {
|
||||
|
@ -20,12 +20,10 @@
|
||||
* for certain types of links (_blank links for example) to open new tabs.
|
||||
*/
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyScriptGetter(this, "TalosParentProfiler",
|
||||
"resource://talos-powers/TalosParentProfiler.js");
|
||||
ChromeUtils.defineModuleGetter(this, "TalosParentProfiler",
|
||||
"resource://talos-powers/TalosParentProfiler.jsm");
|
||||
|
||||
const ANIMATION_PREF = "toolkit.cosmeticAnimations.enabled";
|
||||
const MULTI_OPT_OUT_PREF = "dom.ipc.multiOptOut";
|
||||
|
@ -190,7 +190,7 @@ async function test(window) {
|
||||
return;
|
||||
}
|
||||
|
||||
Services.scriptloader.loadSubScript("resource://talos-powers/TalosParentProfiler.js", context);
|
||||
ChromeUtils.import("resource://talos-powers/TalosParentProfiler.jsm", context);
|
||||
TalosParentProfiler = context.TalosParentProfiler;
|
||||
|
||||
let testURLs = [];
|
||||
|
Loading…
Reference in New Issue
Block a user