Backed out 7 changesets (bug 1167508) because it depends on bug 1172137, which was backed out.
authorRyan VanderMeulen <ryanvm@gmail.com>
Mon, 08 Jun 2015 14:33:53 -0400
changeset 248037 986f641d87e4115fe9a0a909c7aa698d3b2ec9e0
parent 248036 6034dc30409f9da00973f116b9c0f6ae14fa14b8
child 248038 c9f8f919578ee144371ac12905a9f7c02fb74b80
push id60888
push userkwierso@gmail.com
push dateThu, 11 Jun 2015 01:38:38 +0000
treeherdermozilla-inbound@39e638ed06bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1167508, 1172137
milestone41.0a1
backs out5080433ff6105dcd9b2280319a99406c349af245
97b5372b89506a986eb23f13e91e2ded2ac4e87d
00eb943a27b21e92204c525a656c59ec17e3c50e
c1a16fd640aed3c0fbfacde14bd3bcbfda7adf3d
092037dd209ade86cbe52e765a7d7ac05f8c57bf
b7ed44b4595ff0b35f788af143ab35b9835bc99f
3a4faf863320f5feeaab2a97f5139a5700f63d9e
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
Backed out 7 changesets (bug 1167508) because it depends on bug 1172137, which was backed out. Backed out changeset 5080433ff610 (bug 1167508) Backed out changeset 97b5372b8950 (bug 1167508) Backed out changeset 00eb943a27b2 (bug 1167508) Backed out changeset c1a16fd640ae (bug 1167508) Backed out changeset 092037dd209a (bug 1167508) Backed out changeset b7ed44b4595f (bug 1167508) Backed out changeset 3a4faf863320 (bug 1167508)
browser/base/content/browser.js
browser/base/content/test/general/browser_e10s_chrome_process.js
browser/base/content/test/general/browser_e10s_switchbrowser.js
browser/base/content/test/general/browser_testOpenNewRemoteTabsFromNonRemoteBrowsers.js
browser/components/customizableui/test/browser_934951_zoom_in_toolbar.js
browser/components/sessionstore/SessionStore.jsm
browser/components/sessionstore/TabState.jsm
browser/components/sessionstore/test/browser_async_remove_tab.js
browser/components/sessionstore/test/browser_sessionHistory.js
browser/components/sessionstore/test/head.js
netwerk/test/browser/browser_child_resource.js
testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -215,16 +215,19 @@ XPCOMUtils.defineLazyModuleGetter(this, 
   "resource:///modules/translation/Translation.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "SitePermissions",
   "resource:///modules/SitePermissions.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "SessionStore",
   "resource:///modules/sessionstore/SessionStore.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "TabState",
+  "resource:///modules/sessionstore/TabState.jsm");
+
 XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
   "resource://gre/modules/FxAccounts.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "gWebRTCUI",
   "resource:///modules/webrtcUI.jsm", "webrtcUI");
 
 #ifdef MOZ_CRASHREPORTER
 XPCOMUtils.defineLazyModuleGetter(this, "TabCrashReporter",
@@ -913,17 +916,32 @@ function _loadURIWithFlags(browser, uri,
     }
   }
 }
 
 // Starts a new load in the browser first switching the browser to the correct
 // process
 function LoadInOtherProcess(browser, loadOptions, historyIndex = -1) {
   let tab = gBrowser.getTabForBrowser(browser);
-  SessionStore.navigateAndRestore(tab, loadOptions, historyIndex);
+  // Flush the tab state before getting it
+  TabState.flush(browser);
+  let tabState = JSON.parse(SessionStore.getTabState(tab));
+
+  if (historyIndex < 0) {
+    tabState.userTypedValue = null;
+    // Tell session history the new page to load
+    SessionStore._restoreTabAndLoad(tab, JSON.stringify(tabState), loadOptions);
+  }
+  else {
+    // Update the history state to point to the requested index
+    tabState.index = historyIndex + 1;
+    // SessionStore takes care of setting the browser remoteness before restoring
+    // history into it.
+    SessionStore.setTabState(tab, JSON.stringify(tabState));
+  }
 }
 
 // Called when a docshell has attempted to load a page in an incorrect process.
 // This function is responsible for loading the page in the correct process.
 function RedirectLoad({ target: browser, data }) {
   // We should only start the redirection if the browser window has finished
   // starting up. Otherwise, we should wait until the startup is done.
   if (gBrowserInit.delayedStartupFinished) {
--- a/browser/base/content/test/general/browser_e10s_chrome_process.js
+++ b/browser/base/content/test/general/browser_e10s_chrome_process.js
@@ -117,17 +117,17 @@ let TESTS = [
   ],
 ];
 
 // The different ways to transition from one page to another
 let TRANSITIONS = [
 // Loads the new page by calling browser.loadURI directly
 function* loadURI(browser, uri) {
   info("Calling browser.loadURI");
-  yield BrowserTestUtils.loadURI(browser, uri);
+  browser.loadURI(uri);
   return true;
 },
 
 // Loads the new page by finding a link with the right href in the document and
 // clicking it
 function* clickLink(browser, uri) {
   info("Clicking link");
 
--- a/browser/base/content/test/general/browser_e10s_switchbrowser.js
+++ b/browser/base/content/test/general/browser_e10s_switchbrowser.js
@@ -192,28 +192,28 @@ add_task(function* test_synchronous() {
   let {permanentKey} = gBrowser.selectedBrowser;
   yield waitForLoad("http://example.org/" + DUMMY_PATH);
   is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
   is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
 
   info("2");
   // Load another page
   info("Loading about:robots");
-  yield BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "about:robots");
+  gBrowser.selectedBrowser.loadURI("about:robots");
   is(gBrowser.selectedBrowser.isRemoteBrowser, false, "Remote attribute should be correct");
   is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
 
   yield waitForDocLoadComplete();
   is(gBrowser.selectedBrowser.isRemoteBrowser, false, "Remote attribute should be correct");
   is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
 
   info("3");
   // Load the remote page again
   info("Loading http://example.org/" + DUMMY_PATH);
-  yield BrowserTestUtils.loadURI(gBrowser.selectedBrowser, "http://example.org/" + DUMMY_PATH);
+  gBrowser.loadURI("http://example.org/" + DUMMY_PATH);
   is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
   is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
 
   yield waitForDocLoadComplete();
   is(gBrowser.selectedBrowser.isRemoteBrowser, expectedRemote, "Remote attribute should be correct");
   is(gBrowser.selectedBrowser.permanentKey, permanentKey, "browser.permanentKey is still the same");
 
   info("4");
--- a/browser/base/content/test/general/browser_testOpenNewRemoteTabsFromNonRemoteBrowsers.js
+++ b/browser/base/content/test/general/browser_testOpenNewRemoteTabsFromNonRemoteBrowsers.js
@@ -21,17 +21,17 @@ function frame_script() {
 /**
  * Takes some browser in some window, and forces that browser
  * to become non-remote, and then navigates it to a page that
  * we're not supposed to be displaying remotely. Returns a
  * Promise that resolves when the browser is no longer remote.
  */
 function prepareNonRemoteBrowser(aWindow, browser) {
   browser.loadURI(NON_REMOTE_PAGE);
-  return BrowserTestUtils.browserLoaded(browser);
+  return waitForDocLoadComplete(browser);
 }
 
 registerCleanupFunction(() => {
   Services.prefs.clearUserPref(OPEN_LOCATION_PREF);
 });
 
 /**
  * Test that if we open a new tab from a link in a non-remote
--- a/browser/components/customizableui/test/browser_934951_zoom_in_toolbar.js
+++ b/browser/components/customizableui/test/browser_934951_zoom_in_toolbar.js
@@ -5,19 +5,17 @@
 "use strict";
 
 const kTimeoutInMS = 20000;
 
 // Bug 934951 - Zoom controls percentage label doesn't update when it's in the toolbar and you navigate.
 add_task(function() {
   CustomizableUI.addWidgetToArea("zoom-controls", CustomizableUI.AREA_NAVBAR);
   let tab1 = gBrowser.addTab("about:mozilla");
-  yield BrowserTestUtils.browserLoaded(tab1.linkedBrowser);
-  let tab2 = gBrowser.addTab("about:robots");
-  yield BrowserTestUtils.browserLoaded(tab2.linkedBrowser);
+  let tab2 = gBrowser.addTab("about:newtab");
   gBrowser.selectedTab = tab1;
   let zoomResetButton = document.getElementById("zoom-reset-button");
 
   registerCleanupFunction(() => {
     info("Cleaning up.");
     CustomizableUI.reset();
     gBrowser.removeTab(tab2);
     gBrowser.removeTab(tab1);
@@ -27,17 +25,17 @@ add_task(function() {
   let zoomChangePromise = promiseObserverNotification("browser-fullZoom:zoomChange");
   FullZoom.enlarge();
   yield zoomChangePromise;
   is(parseInt(zoomResetButton.label, 10), 110, "Zoom is changed to 110% for about:mozilla");
 
   let tabSelectPromise = promiseTabSelect();
   gBrowser.selectedTab = tab2;
   yield tabSelectPromise;
-  is(parseInt(zoomResetButton.label, 10), 100, "Default zoom is 100% for about:robots");
+  is(parseInt(zoomResetButton.label, 10), 100, "Default zoom is 100% for about:newtab");
 
   gBrowser.selectedTab = tab1;
   let zoomResetPromise = promiseObserverNotification("browser-fullZoom:zoomReset");
   FullZoom.reset();
   yield zoomResetPromise;
   is(parseInt(zoomResetButton.label, 10), 100, "Default zoom is 100% for about:mozilla");
 
   // Test zoom label updates while navigating pages in the same tab.
@@ -49,17 +47,16 @@ add_task(function() {
   });
   yield promiseTabLoadEvent(tab1, "about:home");
   yield attributeChangePromise;
   is(parseInt(zoomResetButton.label, 10), 100, "Default zoom is 100% for about:home");
   yield promiseTabHistoryNavigation(-1, function() {
     return parseInt(zoomResetButton.label, 10) == 110;
   });
   is(parseInt(zoomResetButton.label, 10), 110, "Zoom is still 110% for about:mozilla");
-  FullZoom.reset();
 });
 
 function promiseObserverNotification(aObserver) {
   let deferred = Promise.defer();
   function notificationCallback(e) {
     Services.obs.removeObserver(notificationCallback, aObserver, false);
     clearTimeout(timeoutId);
     deferred.resolve();
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -209,16 +209,26 @@ this.SessionStore = {
   getTabState: function ss_getTabState(aTab) {
     return SessionStoreInternal.getTabState(aTab);
   },
 
   setTabState: function ss_setTabState(aTab, aState) {
     SessionStoreInternal.setTabState(aTab, aState);
   },
 
+  // This should not be used by external code, the intention is to remove it
+  // once a better fix is in place for process switching in e10s.
+  // See bug 1075658 for context.
+  _restoreTabAndLoad: function ss_restoreTabAndLoad(aTab, aState, aLoadArguments) {
+    SessionStoreInternal.setTabState(aTab, aState, {
+      restoreImmediately: true,
+      loadArguments: aLoadArguments
+    });
+  },
+
   duplicateTab: function ss_duplicateTab(aWindow, aTab, aDelta = 0) {
     return SessionStoreInternal.duplicateTab(aWindow, aTab, aDelta);
   },
 
   getClosedTabCount: function ss_getClosedTabCount(aWindow) {
     return SessionStoreInternal.getClosedTabCount(aWindow);
   },
 
@@ -295,20 +305,16 @@ this.SessionStore = {
   },
 
   getCurrentState: function (aUpdateAll) {
     return SessionStoreInternal.getCurrentState(aUpdateAll);
   },
 
   reviveCrashedTab(aTab) {
     return SessionStoreInternal.reviveCrashedTab(aTab);
-  },
-
-  navigateAndRestore(tab, loadArguments, historyIndex) {
-    return SessionStoreInternal.navigateAndRestore(tab, loadArguments, historyIndex);
   }
 };
 
 // Freeze the SessionStore object. We don't want anyone to modify it.
 Object.freeze(SessionStore);
 
 let SessionStoreInternal = {
   QueryInterface: XPCOMUtils.generateQI([
@@ -619,52 +625,52 @@ let SessionStoreInternal = {
       return;
     }
 
     switch (aMessage.name) {
       case "SessionStore:setupSyncHandler":
         TabState.setSyncHandler(browser, aMessage.objects.handler);
         break;
       case "SessionStore:update":
+        // Ignore messages from <browser> elements that have crashed
+        // and not yet been revived.
+        if (this._crashedBrowsers.has(browser.permanentKey)) {
+          return;
+        }
+
         // |browser.frameLoader| might be empty if the browser was already
         // destroyed and its tab removed. In that case we still have the last
         // frameLoader we know about to compare.
         let frameLoader = browser.frameLoader ||
                           this._lastKnownFrameLoader.get(browser.permanentKey);
 
         // If the message isn't targeting the latest frameLoader discard it.
         if (frameLoader != aMessage.targetFrameLoader) {
           return;
         }
 
+        // Record telemetry measurements done in the child and update the tab's
+        // cached state. Mark the window as dirty and trigger a delayed write.
+        this.recordTelemetry(aMessage.data.telemetry);
+        TabState.update(browser, aMessage.data);
+        this.saveStateDelayed(win);
+
         if (aMessage.data.isFinal) {
           // If this the final message we need to resolve all pending flush
           // requests for the given browser as they might have been sent too
           // late and will never respond. If they have been sent shortly after
           // switching a browser's remoteness there isn't too much data to skip.
           TabStateFlusher.resolveAll(browser);
         } else if (aMessage.data.flushID) {
           // This is an update kicked off by an async flush request. Notify the
           // TabStateFlusher so that it can finish the request and notify its
           // consumer that's waiting for the flush to be done.
           TabStateFlusher.resolve(browser, aMessage.data.flushID);
         }
 
-        // Ignore messages from <browser> elements that have crashed
-        // and not yet been revived.
-        if (this._crashedBrowsers.has(browser.permanentKey)) {
-          return;
-        }
-
-        // Record telemetry measurements done in the child and update the tab's
-        // cached state. Mark the window as dirty and trigger a delayed write.
-        this.recordTelemetry(aMessage.data.telemetry);
-        TabState.update(browser, aMessage.data);
-        this.saveStateDelayed(win);
-
         // Handle any updates sent by the child after the tab was closed. This
         // might be the final update as sent by the "unload" handler but also
         // any async update message that was sent before the child unloaded.
         if (this._closedTabs.has(browser.permanentKey)) {
           let {closedTabs, tabData} = this._closedTabs.get(browser.permanentKey);
 
           // Update the closed tab's state. This will be reflected in its
           // window's list of closed tabs as that refers to the same object.
@@ -815,17 +821,16 @@ let SessionStoreInternal = {
         this.saveStateDelayed(win);
         break;
       case "oop-browser-crashed":
         this.onBrowserCrashed(win, target);
         break;
       case "XULFrameLoaderCreated":
         if (target.tagName == "browser" && target.frameLoader && target.permanentKey) {
           this._lastKnownFrameLoader.set(target.permanentKey, target.frameLoader);
-          this.resetEpoch(target);
         }
         break;
       default:
         throw new Error(`unhandled event ${aEvent.type}?`);
     }
     this._clearRestoringWindows();
   },
 
@@ -1809,23 +1814,16 @@ let SessionStoreInternal = {
     // Flush to get the latest tab state to duplicate.
     let browser = aTab.linkedBrowser;
     TabStateFlusher.flush(browser).then(() => {
       // The new tab might have been closed in the meantime.
       if (newTab.closing || !newTab.linkedBrowser) {
         return;
       }
 
-      let window = newTab.ownerDocument && newTab.ownerDocument.defaultView;
-
-      // The tab or its window might be gone.
-      if (!window || !window.__SSi) {
-        return;
-      }
-
       // Update state with flushed data. We can't use TabState.clone() here as
       // the tab to duplicate may have already been closed. In that case we
       // only have access to the <xul:browser>.
       let options = {includePrivateData: true};
       TabState.copyFromCache(browser, tabState, options);
 
       tabState.index += aDelta;
       tabState.index = Math.max(1, Math.min(tabState.index, tabState.entries.length));
@@ -2165,67 +2163,16 @@ let SessionStoreInternal = {
                       "Somehow a crashed browser is still remote.")
     }
 
     let data = TabState.collect(aTab);
     this.restoreTab(aTab, data);
   },
 
   /**
-   * Navigate the given |tab| by first collecting its current state and then
-   * either changing only the index of the currently shown shistory entry,
-   * or restoring the exact same state again and passing the new URL to load
-   * in |loadArguments|. Use this method to seamlessly switch between pages
-   * loaded in the parent and pages loaded in the child process.
-   */
-  navigateAndRestore(tab, loadArguments, historyIndex) {
-    let window = tab.ownerDocument.defaultView;
-    let browser = tab.linkedBrowser;
-
-    // Set tab title to "Connecting..." and start the throbber to pretend we're
-    // doing something while actually waiting for data from the frame script.
-    window.gBrowser.setTabTitleLoading(tab);
-    tab.setAttribute("busy", "true");
-
-    // Flush to get the latest tab state.
-    TabStateFlusher.flush(browser).then(() => {
-      // The tab might have been closed/gone in the meantime.
-      if (tab.closing || !tab.linkedBrowser) {
-        return;
-      }
-
-      let window = tab.ownerDocument && tab.ownerDocument.defaultView;
-
-      // The tab or its window might be gone.
-      if (!window || !window.__SSi) {
-        return;
-      }
-
-      let tabState = TabState.clone(tab);
-      let options = {restoreImmediately: true};
-
-      if (historyIndex >= 0) {
-        tabState.index = historyIndex + 1;
-        tabState.index = Math.max(1, Math.min(tabState.index, tabState.entries.length));
-      } else {
-        tabState.userTypedValue = null;
-        options.loadArguments = loadArguments;
-      }
-
-      // Need to reset restoring tabs.
-      if (tab.linkedBrowser.__SS_restoreState) {
-        this._resetLocalTabRestoringState(tab);
-      }
-
-      // Restore the state into the tab.
-      this.restoreTab(tab, tabState, options);
-    });
-  },
-
-  /**
    * See if aWindow is usable for use when restoring a previous session via
    * restoreLastSession. If usable, prepare it for use.
    *
    * @param aWindow
    *        the window to inspect & prepare
    * @returns [canUseWindow, canOverwriteTabs]
    *          canUseWindow: can the window be used to restore into
    *          canOverwriteTabs: all of the current tabs are home pages and we
@@ -3724,24 +3671,16 @@ let SessionStoreInternal = {
    * compare the epoch received with the message to the <browser> element's
    * epoch. This function does that, and returns true if |epoch| is up-to-date
    * with respect to |browser|.
    */
   isCurrentEpoch: function (browser, epoch) {
     return this.getCurrentEpoch(browser) == epoch;
   },
 
-  /**
-   * Resets the epoch for a given <browser>. We need to this every time we
-   * receive a hint that a new docShell has been loaded into the browser as
-   * the frame script starts out with epoch=0.
-   */
-  resetEpoch(browser) {
-    this._browserEpochs.delete(browser.permanentKey);
-  }
 };
 
 /**
  * Priority queue that keeps track of a list of tabs to restore and returns
  * the tab we should restore next, based on priority rules. We decide between
  * pinned, visible and hidden tabs in that and FIFO order. Hidden tabs are only
  * restored with restore_hidden_tabs=true.
  */
--- a/browser/components/sessionstore/TabState.jsm
+++ b/browser/components/sessionstore/TabState.jsm
@@ -30,16 +30,20 @@ this.TabState = Object.freeze({
   setSyncHandler: function (browser, handler) {
     TabStateInternal.setSyncHandler(browser, handler);
   },
 
   update: function (browser, data) {
     TabStateInternal.update(browser, data);
   },
 
+  flush: function (browser) {
+    TabStateInternal.flush(browser);
+  },
+
   flushAsync: function (browser) {
     TabStateInternal.flushAsync(browser);
   },
 
   flushWindow: function (window) {
     TabStateInternal.flushWindow(window);
   },
 
@@ -83,36 +87,43 @@ let TabStateInternal = {
     // synchronously.
     if (id > this._latestMessageID.get(browser.permanentKey)) {
       this._latestMessageID.set(browser.permanentKey, id);
       TabStateCache.update(browser, data);
     }
   },
 
   /**
+   * Flushes all data currently queued in the given browser's content script.
+   */
+  flush: function (browser) {
+    if (this._syncHandlers.has(browser.permanentKey)) {
+      let lastID = this._latestMessageID.get(browser.permanentKey);
+      this._syncHandlers.get(browser.permanentKey).flush(lastID);
+    }
+  },
+
+  /**
    * DO NOT USE - DEBUGGING / TESTING ONLY
    *
    * This function is used to simulate certain situations where race conditions
    * can occur by sending data shortly before flushing synchronously.
    */
   flushAsync: function(browser) {
     if (this._syncHandlers.has(browser.permanentKey)) {
       this._syncHandlers.get(browser.permanentKey).flushAsync();
     }
   },
 
   /**
    * Flushes queued content script data for all browsers of a given window.
    */
   flushWindow: function (window) {
     for (let browser of window.gBrowser.browsers) {
-      if (this._syncHandlers.has(browser.permanentKey)) {
-        let lastID = this._latestMessageID.get(browser.permanentKey);
-        this._syncHandlers.get(browser.permanentKey).flush(lastID);
-      }
+      this.flush(browser);
     }
   },
 
   /**
    * Collect data related to a single tab, synchronously.
    *
    * @param tab
    *        tabbrowser tab
--- a/browser/components/sessionstore/test/browser_async_remove_tab.js
+++ b/browser/components/sessionstore/test/browser_async_remove_tab.js
@@ -157,17 +157,17 @@ add_task(function* save_worthy_tabs_remo
 });
 
 add_task(function* save_worthy_tabs_nonremote_final() {
   let {tab, r} = yield createTabWithRandomValue("about:blank");
   let browser = tab.linkedBrowser;
   ok(browser.isRemoteBrowser, "browser is remote");
 
   // Replace about:blank with a non-remote entry.
-  yield BrowserTestUtils.loadURI(browser, "about:robots");
+  browser.loadURI("about:robots");
   ok(!browser.isRemoteBrowser, "browser is not remote anymore");
 
   // Wait until the new entry replaces about:blank.
   yield promiseHistoryEntryReplacedNonRemote(browser);
 
   // Remove the tab before the update arrives.
   let promise = promiseRemoveTab(tab);
 
--- a/browser/components/sessionstore/test/browser_sessionHistory.js
+++ b/browser/components/sessionstore/test/browser_sessionHistory.js
@@ -7,20 +7,18 @@
  * Ensure that starting a load invalidates shistory.
  */
 add_task(function test_load_start() {
   // Create a new tab.
   let tab = gBrowser.addTab("about:blank");
   let browser = tab.linkedBrowser;
   yield promiseBrowserLoaded(browser);
 
-  // Load a new URI.
-  yield BrowserTestUtils.loadURI(browser, "about:mozilla");
-
-  // Remove the tab before it has finished loading.
+  // Load a new URI but remove the tab before it has finished loading.
+  browser.loadURI("about:mozilla");
   yield promiseContentMessage(browser, "ss-test:OnHistoryReplaceEntry");
   yield promiseRemoveTab(tab);
 
   // Undo close the tab.
   tab = ss.undoCloseTab(window, 0);
   browser = tab.linkedBrowser;
   yield promiseTabRestored(tab);
 
--- a/browser/components/sessionstore/test/head.js
+++ b/browser/components/sessionstore/test/head.js
@@ -277,17 +277,24 @@ let promiseForEachSessionRestoreFile = T
 	     && ex.becauseNoSuchFile) {
       // Ignore missing files
     }
     cb(data, key);
   }
 });
 
 function promiseBrowserLoaded(aBrowser, ignoreSubFrames = true) {
-  return BrowserTestUtils.browserLoaded(aBrowser, !ignoreSubFrames);
+  return new Promise(resolve => {
+    aBrowser.messageManager.addMessageListener("ss-test:loadEvent", function onLoad(msg) {
+      if (!ignoreSubFrames || !msg.data.subframe) {
+        aBrowser.messageManager.removeMessageListener("ss-test:loadEvent", onLoad);
+        resolve();
+      }
+    });
+  });
 }
 
 function whenWindowLoaded(aWindow, aCallback = next) {
   aWindow.addEventListener("load", function windowLoadListener() {
     aWindow.removeEventListener("load", windowLoadListener, false);
     executeSoon(function executeWhenWindowLoaded() {
       aCallback(aWindow);
     });
@@ -423,31 +430,18 @@ function whenNewWindowLoaded(aOptions, a
   let url = "about:blank";
 
   if (aOptions && aOptions.private || false) {
     features = ",private";
     url = "about:privatebrowsing";
   }
 
   let win = openDialog(getBrowserURL(), "", "chrome,all,dialog=no" + features, url);
-  let delayedStartup = promiseDelayedStartupFinished(win);
-
-  let browserLoaded = new Promise(resolve => {
-    if (url == "about:blank") {
-      resolve();
-      return;
-    }
-
-    win.addEventListener("load", function onLoad() {
-      win.removeEventListener("load", onLoad);
-      resolve(promiseBrowserLoaded(win.gBrowser.selectedBrowser));
-    });
-  });
-
-  Promise.all([delayedStartup, browserLoaded]).then(() => aCallback(win));
+  whenDelayedStartupFinished(win, () => aCallback(win));
+  return win;
 }
 function promiseNewWindowLoaded(aOptions) {
   return new Promise(resolve => whenNewWindowLoaded(aOptions, resolve));
 }
 
 /**
  * Chrome windows aren't closed synchronously. Provide a helper method to close
  * a window and wait until we received the "domwindowclosed" notification for it.
--- a/netwerk/test/browser/browser_child_resource.js
+++ b/netwerk/test/browser/browser_child_resource.js
@@ -133,17 +133,17 @@ let restart = Task.async(function*() {
   if (browser.getAttribute("remote") != "true")
     return browser;
 
   browser.messageManager.sendAsyncMessage("Test:Crash");
   yield waitForEvent(browser, "AboutTabCrashedLoad", false, true);
 
   browser.reload();
 
-  yield BrowserTestUtils.browserLoaded(browser);
+  yield waitForEvent(browser, "load", true);
   is(browser.getAttribute("remote"), expectedRemote, "Browser should be in the right process");
   browser.messageManager.loadFrameScript("data:,(" + frameScript.toString() + ")();", true);
   return browser;
 });
 
 // Sanity check that this test is going to be useful
 add_task(function*() {
   let browser = yield loadTestTab();
--- a/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
+++ b/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
@@ -23,19 +23,16 @@ Cu.import("resource://gre/modules/Task.j
 Cu.import("resource://gre/modules/Timer.jsm");
 Cu.import("resource://testing-common/TestUtils.jsm");
 
 Cc["@mozilla.org/globalmessagemanager;1"]
   .getService(Ci.nsIMessageListenerManager)
   .loadFrameScript(
     "chrome://mochikit/content/tests/BrowserTestUtils/content-utils.js", true);
 
-XPCOMUtils.defineLazyModuleGetter(this, "E10SUtils",
-  "resource:///modules/E10SUtils.jsm");
-
 this.BrowserTestUtils = {
   /**
    * Loads a page in a new tab, executes a Task and closes the tab.
    *
    * @param options
    *        An object with the following properties:
    *        {
    *          gBrowser:
@@ -138,61 +135,28 @@ this.BrowserTestUtils = {
    * @param {Boolean} includeSubFrames
    *        A boolean indicating if loads from subframes should be included.
    *
    * @return {Promise}
    * @resolves When a load event is triggered for the browser.
    */
   browserLoaded(browser, includeSubFrames=false) {
     return new Promise(resolve => {
-      let mm = browser.ownerDocument.defaultView.messageManager;
-      mm.addMessageListener("browser-test-utils:loadEvent", function onLoad(msg) {
-        if (msg.target == browser && (!msg.data.subframe || includeSubFrames)) {
-          mm.removeMessageListener("browser-test-utils:loadEvent", onLoad);
+      browser.messageManager.addMessageListener("browser-test-utils:loadEvent",
+                                                 function onLoad(msg) {
+        if (!msg.data.subframe || includeSubFrames) {
+          browser.messageManager.removeMessageListener(
+            "browser-test-utils:loadEvent", onLoad);
           resolve();
         }
       });
     });
   },
 
   /**
-   * Loads a new URI in the given browser and waits until we really started
-   * loading. In e10s browser.loadURI() can be an asynchronous operation due
-   * to having to switch the browser's remoteness and keep its shistory data.
-   *
-   * @param {xul:browser} browser
-   *        A xul:browser.
-   * @param {string} uri
-   *        The URI to load.
-   *
-   * @return {Promise}
-   * @resolves When we started loading the given URI.
-   */
-  loadURI: Task.async(function* (browser, uri) {
-    // Load the new URI.
-    browser.loadURI(uri);
-
-    // Nothing to do in non-e10s mode.
-    if (!browser.ownerDocument.defaultView.gMultiProcessBrowser) {
-      return;
-    }
-
-    // Retrieve the given browser's current process type.
-    let process = browser.isRemoteBrowser ? Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT
-                                          : Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
-
-    // If the new URI can't load in the browser's current process then we
-    // should wait for the new frameLoader to be created. This will happen
-    // asynchronously when the browser's remoteness changes.
-    if (!E10SUtils.canLoadURIInProcess(uri, process)) {
-      yield this.waitForEvent(browser, "XULFrameLoaderCreated");
-    }
-  }),
-
-  /**
    * @return {Promise}
    *         A Promise which resolves when a "domwindowopened" notification
    *         has been fired by the window watcher.
    */
   domWindowOpened() {
     return new Promise(resolve => {
       function observer(subject, topic, data) {
         if (topic != "domwindowopened") { return; }