Bug 1509571 - Fix profiling for the sessionrestore_no_auto_restore Talos test. r=aswan
authorMike Conley <mconley@mozilla.com>
Tue, 27 Nov 2018 18:36:40 +0000
changeset 504780 f78fcb8e46d46dc15b1eead4a817b8f3d1f981dc
parent 504779 708326aa806a5a2976ed2eb42ced1dbdfaa2a669
child 504781 b09a44bf41cb77963e1adbd15adfbd3996dcabb2
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaswan
bugs1509571
milestone65.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 1509571 - Fix profiling for the sessionrestore_no_auto_restore Talos test. r=aswan Differential Revision: https://phabricator.services.mozilla.com/D12789
browser/components/sessionstore/StartupPerformance.jsm
testing/talos/talos/startup_test/sessionrestore/addon/api.js
--- a/browser/components/sessionstore/StartupPerformance.jsm
+++ b/browser/components/sessionstore/StartupPerformance.jsm
@@ -71,16 +71,17 @@ var StartupPerformance = {
   get isRestored() {
     return this._isRestored;
   },
 
   // Called when restoration starts.
   // Record the start timestamp, setup the timer and `this._promiseFinished`.
   // Behavior is unspecified if there was already an ongoing measure.
   _onRestorationStarts(isAutoRestore) {
+    Services.profiler.AddMarker("_onRestorationStarts");
     this._latestRestoredTimeStamp = this._startTimeStamp = Date.now();
     this._totalNumberOfEagerTabs = 0;
     this._totalNumberOfTabs = 0;
     this._totalNumberOfWindows = 0;
 
     // While we may restore several sessions in a single run of the browser,
     // that's a very unusual case, and not really worth measuring, so let's
     // stop listening for further restorations.
@@ -193,16 +194,17 @@ var StartupPerformance = {
 
           let observer = (event) => {
             // We don't care about tab restorations that are due to
             // a browser flipping from out-of-main-process to in-main-process
             // or vice-versa. We only care about restorations that are due
             // to the user switching to a lazily restored tab, or for tabs
             // that are restoring eagerly.
             if (!event.detail.isRemotenessUpdate) {
+              Services.profiler.AddMarker("SSTabRestored");
               this._latestRestoredTimeStamp = Date.now();
               this._totalNumberOfEagerTabs += 1;
             }
           };
           win.gBrowser.tabContainer.addEventListener("SSTabRestored", observer);
           this._totalNumberOfTabs += win.gBrowser.tabContainer.itemCount;
 
           // Once we have finished collecting the results, clean up the observers.
--- a/testing/talos/talos/startup_test/sessionrestore/addon/api.js
+++ b/testing/talos/talos/startup_test/sessionrestore/addon/api.js
@@ -9,68 +9,95 @@
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
   Services: "resource://gre/modules/Services.jsm",
   SessionStartup: "resource:///modules/sessionstore/SessionStartup.jsm",
   setTimeout: "resource://gre/modules/Timer.jsm",
   StartupPerformance: "resource:///modules/sessionstore/StartupPerformance.jsm",
-  TalosParentProfiler: "resource://talos-powers/TalosParentProfiler.jsm",
 });
 
 /* globals ExtensionAPI */
 
 this.sessionrestore = class extends ExtensionAPI {
   onStartup() {
     // run() is async but we don't want to await or return it here,
     // since the extension should be considered started even before
     // run() has finished all its work.
     this.run();
   }
 
+  async ensureTalosParentProfiler() {
+    // TalosParentProfiler is part of TalosPowers, which is a separate WebExtension
+    // that may or may not already have finished loading at this point. getTalosParentProfiler
+    // is used to wait for TalosPowers to be around before continuing. This should
+    // not be used to delay the execution of the test, but to delay the dumping of
+    // the profile to disk.
+    async function getTalosParentProfiler() {
+      try {
+        ChromeUtils.import("resource://talos-powers/TalosParentProfiler.jsm");
+        return TalosParentProfiler;
+      } catch (err) {
+        await new Promise(resolve => setTimeout(resolve, 500));
+        return getTalosParentProfiler();
+      }
+    }
+
+    this.TalosParentProfiler = await getTalosParentProfiler();
+  }
+
+  async finishProfiling(msg) {
+    await this.ensureTalosParentProfiler();
+
+    let win = BrowserWindowTracker.getTopWindow();
+    let args = win.arguments[0];
+    if (args && args instanceof Ci.nsIArray) {
+      // For start-up tests Gecko Profiler arguments are passed to the first URL in
+      // the query string, with the presumption that some tab that is loaded at start-up
+      // will want to use them in the TalosContentProfiler.js script.
+      //
+      // Because we're running this part of the test in the parent process, we
+      // pull those arguments from the top window directly. This is mainly so
+      // that TalosParentProfiler knows where to save the profile.
+      Cu.importGlobalProperties(["URL"]);
+      let url = new URL(args.queryElementAt(0, Ci.nsISupportsString).data);
+      this.TalosParentProfiler.initFromURLQueryParams(url.search);
+    }
+
+    await this.TalosParentProfiler.pause(msg);
+    await this.TalosParentProfiler.finishStartupProfiling();
+  }
+
   async run() {
     try {
       let didRestore = true;
 
       if (!StartupPerformance.isRestored) {
         await SessionStartup.onceInitialized;
 
         if (SessionStartup.sessionType == SessionStartup.NO_SESSION ||
             SessionStartup.sessionType == SessionStartup.DEFER_SESSION) {
           // We should only hit this patch in sessionrestore_no_auto_restore
           if (!Services.prefs.getBoolPref("talos.sessionrestore.norestore", false)) {
             throw new Error("Session was not restored!");
           }
+          await this.finishProfiling("This test measures the time between sessionRestoreInit " +
+                                     "and sessionRestored, ignore everything around that");
+
           didRestore = false;
         } else {
           await new Promise(resolve => {
-            async function observe() {
+            let observe = async () => {
               Services.obs.removeObserver(observe, StartupPerformance.RESTORED_TOPIC);
-
-              let win = BrowserWindowTracker.getTopWindow();
-              let args = win.arguments[0];
-              if (args && args instanceof Ci.nsIArray) {
-                // For start-up tests Gecko Profiler arguments are passed to the first URL in
-                // the query string, with the presumption that some tab that is loaded at start-up
-                // will want to use them in the TalosContentProfiler.js script.
-                //
-                // Because we're running this part of the test in the parent process, we
-                // pull those arguments from the top window directly. This is mainly so
-                // that TalosParentProfiler knows where to save the profile.
-                Cu.importGlobalProperties(["URL"]);
-                let url = new URL(args.queryElementAt(0, Ci.nsISupportsString).data);
-                TalosParentProfiler.initFromURLQueryParams(url.search);
-              }
-
-              await TalosParentProfiler.pause("This test measures the time between sessionRestoreInit and sessionRestored, ignore everything around that");
-              await TalosParentProfiler.finishStartupProfiling();
+              await this.finishProfiling("This test measures the time between sessionRestoreInit " +
+                                         "and the last restored tab, ignore everything around that");
 
               resolve();
-            }
+            };
             Services.obs.addObserver(observe, StartupPerformance.RESTORED_TOPIC);
           });
         }
       }
 
       let startup_info = Services.startup.getStartupInfo();
       let restoreTime = didRestore
                       ? StartupPerformance.latestRestoredTimeStamp