Bug 1398198 - browser_startup_content.js should show the stack when a JS file was loaded earlier than expected, r=felipe,qdot.
authorFlorian Quèze <florian@queze.net>
Wed, 13 Sep 2017 21:19:55 +0200
changeset 430307 7bf13864b0abd28bbceb612541e4fe340bd0a67f
parent 430306 7030bd97757ee347c92c971e5865d81e05e6d009
child 430308 04077d71603ea4dc9dd47e2ccc8d49d92deaa8dc
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfelipe, qdot
bugs1398198
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1398198 - browser_startup_content.js should show the stack when a JS file was loaded earlier than expected, r=felipe,qdot.
browser/base/content/test/performance/browser_startup_content.js
dom/ipc/ContentPrefs.cpp
--- a/browser/base/content/test/performance/browser_startup_content.js
+++ b/browser/base/content/test/performance/browser_startup_content.js
@@ -9,16 +9,19 @@
  *
  * If your code isn't strictly required to show a page, consider loading it
  * lazily. If you can't, consider delaying its load until after we have started
  * handling user events.
  */
 
 "use strict";
 
+/* Set this to true only for debugging purpose; it makes the output noisy. */
+const kDumpAllStacks = false;
+
 const blacklist = {
   components: new Set([
     "PushComponents.js",
     "TelemetryStartup.js",
   ]),
   modules: new Set([
     "resource:///modules/ContentWebRTC.jsm",
     "resource://gre/modules/InlineSpellChecker.jsm",
@@ -41,40 +44,52 @@ add_task(async function() {
                                                          forceNewProcess: true});
 
   let mm = gBrowser.selectedBrowser.messageManager;
   let promise = BrowserTestUtils.waitForMessage(mm, "Test:LoadedScripts");
 
   // Load a custom frame script to avoid using ContentTask which loads Task.jsm
   mm.loadFrameScript("data:text/javascript,(" + function() {
     /* eslint-env mozilla/frame-script */
-    const {classes: Cc, interfaces: Ci, manager: Cm} = Components;
+    const {classes: Cc, interfaces: Ci, manager: Cm, utils: Cu} = Components;
     Cm.QueryInterface(Ci.nsIServiceManager);
-
+    Cu.import("resource://gre/modules/AppConstants.jsm");
+    let collectStacks = AppConstants.NIGHTLY_BUILD || AppConstants.DEBUG;
     let loader = Cc["@mozilla.org/moz/jsloader;1"].getService(Ci.xpcIJSModuleLoader);
-    sendAsyncMessage("Test:LoadedScripts", {
+    let components = {};
+    for (let component of loader.loadedComponents()) {
       /* Keep only the file name for components, as the path is an absolute file
          URL rather than a resource:// URL like for modules. */
-      components: loader.loadedComponents().map(f => f.replace(/.*\//, "")),
-      modules: loader.loadedModules(),
-      services: Object.keys(Cc).filter(c => {
-        try {
-          return Cm.isServiceInstantiatedByContractID(c, Ci.nsISupports);
-        } catch (e) {
-          return false;
-        }
-      })
-    });
+      components[component.replace(/.*\//, "")] =
+        collectStacks ? loader.getComponentLoadStack(component) : "";
+    }
+    let modules = {};
+    for (let module of loader.loadedModules()) {
+      modules[module] = collectStacks ? loader.getModuleImportStack(module) : "";
+    }
+    let services = {};
+    for (let contractID in Object.keys(Cc)) {
+      try {
+        if (Cm.isServiceInstantiatedByContractID(contractID, Ci.nsISupports))
+          services[contractID] = "";
+      } catch (e) {}
+    }
+    sendAsyncMessage("Test:LoadedScripts", {components, modules, services});
   } + ")()", false);
 
   let loadedList = await promise;
   for (let scriptType in blacklist) {
     info(scriptType);
     for (let file of blacklist[scriptType]) {
-      ok(!loadedList[scriptType].includes(file), `${file} is not allowed`);
+      let loaded = file in loadedList[scriptType];
+      ok(!loaded, `${file} is not allowed`);
+      if (loaded && loadedList[scriptType][file])
+        info(loadedList[scriptType][file]);
     }
-    for (let file of loadedList[scriptType]) {
+    for (let file in loadedList[scriptType]) {
       info(file);
+      if (kDumpAllStacks && loadedList[scriptType][file])
+        info(loadedList[scriptType][file]);
     }
   }
 
   await BrowserTestUtils.removeTab(tab);
 });
--- a/dom/ipc/ContentPrefs.cpp
+++ b/dom/ipc/ContentPrefs.cpp
@@ -21,16 +21,19 @@
 const char* mozilla::dom::ContentPrefs::gInitPrefs[] = {
   "accessibility.monoaudio.enable",
   "accessibility.mouse_focuses_formcontrol",
   "accessibility.tabfocus_applies_to_xul",
   "app.update.channel",
   "browser.dom.window.dump.enabled",
   "browser.sessionhistory.max_entries",
   "browser.sessionhistory.max_total_viewers",
+#if defined(NIGHTLY_BUILD) || defined(DEBUG)
+  "browser.startup.record",
+#endif
   "content.cors.disable",
   "content.cors.no_private_data",
   "content.notify.backoffcount",
   "content.notify.interval",
   "content.notify.ontimer",
   "content.sink.enable_perf_mode",
   "content.sink.event_probe_rate",
   "content.sink.initial_perf_time",