Backed out changeset 2a7569652090 (bug 1147911)
authorSebastian Hengst <archaeopteryx@coole-files.de>
Wed, 23 Nov 2016 18:32:46 +0100
changeset 324111 e1f172e4d02300d51065d1d8dc985bbd8c4b00d9
parent 324110 aed16e234d2ebf3372564600ff8cd5f3c7a83f3c
child 324112 4c2a78d4a8c38a86bfff8e58255c7b096a6fdf53
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
bugs1147911
milestone53.0a1
backs out2a7569652090bc2ca88c358b1afba087d8a9d861
Backed out changeset 2a7569652090 (bug 1147911)
browser/modules/E10SUtils.jsm
devtools/client/webconsole/test/browser_webconsole_bug_595223_file_uri.js
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
modules/libpref/init/all.js
--- a/browser/modules/E10SUtils.jsm
+++ b/browser/modules/E10SUtils.jsm
@@ -25,30 +25,23 @@ function getAboutModule(aURL) {
     // Either the about module isn't defined or it is broken. In either case
     // ignore it.
     return null;
   }
 }
 
 const NOT_REMOTE = null;
 const WEB_REMOTE_TYPE = "web";
-const FILE_REMOTE_TYPE = "file";
 // This must match the one in ContentParent.h.
 const DEFAULT_REMOTE_TYPE = WEB_REMOTE_TYPE;
 
-function validatedWebRemoteType(aPreferredRemoteType) {
-  return aPreferredRemoteType && aPreferredRemoteType.startsWith(WEB_REMOTE_TYPE)
-         ? aPreferredRemoteType : WEB_REMOTE_TYPE;
-}
-
 this.E10SUtils = {
   DEFAULT_REMOTE_TYPE,
   NOT_REMOTE,
   WEB_REMOTE_TYPE,
-  FILE_REMOTE_TYPE,
 
   canLoadURIInProcess: function(aURL, aProcess) {
     let remoteType = aProcess == Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT
                      ? DEFAULT_REMOTE_TYPE : NOT_REMOTE;
     return remoteType == this.getRemoteTypeForURI(aURL, true, remoteType);
   },
 
   getRemoteTypeForURI: function(aURL, aMultiProcess,
@@ -69,21 +62,16 @@ this.E10SUtils = {
 
     // We need data: URIs to load in any remote process, because some of our
     // tests rely on this.
     if (aURL.startsWith("data:")) {
       return aPreferredRemoteType == NOT_REMOTE ? DEFAULT_REMOTE_TYPE
                                                 : aPreferredRemoteType;
     }
 
-    if (aURL.startsWith("file:")) {
-      return Services.prefs.getBoolPref("browser.tabs.remote.separateFileUriProcess")
-             ? FILE_REMOTE_TYPE : DEFAULT_REMOTE_TYPE;
-    }
-
     if (aURL.startsWith("about:")) {
       // We need to special case about:blank because it needs to load in any.
       if (aURL == "about:blank") {
         return aPreferredRemoteType;
       }
 
       let url = Services.io.newURI(aURL, null, null);
       let module = getAboutModule(url);
@@ -134,17 +122,17 @@ this.E10SUtils = {
       return useRemoteWebExtensions ? WEB_REMOTE_TYPE : NOT_REMOTE;
     }
 
     if (aURL.startsWith("view-source:")) {
       return this.getRemoteTypeForURI(aURL.substr("view-source:".length),
                                       aMultiProcess, aPreferredRemoteType);
     }
 
-    return validatedWebRemoteType(aPreferredRemoteType);
+    return WEB_REMOTE_TYPE;
   },
 
   shouldLoadURIInThisProcess: function(aURI) {
     let remoteType = Services.appinfo.remoteType;
     return remoteType == this.getRemoteTypeForURI(aURI.spec, true, remoteType);
   },
 
   shouldLoadURI: function(aDocShell, aURI, aReferrer) {
--- a/devtools/client/webconsole/test/browser_webconsole_bug_595223_file_uri.js
+++ b/devtools/client/webconsole/test/browser_webconsole_bug_595223_file_uri.js
@@ -18,17 +18,17 @@ add_task(function* () {
             extractJarToTmp(jar) :
             getChromeDir(getResolvedURI(gTestPath));
 
   dir.append(TEST_FILE);
   let uri = Services.io.newFileURI(dir);
 
   // We need a file remote type to make sure we don't switch processes when we
   // load the file:// URI.
-  let { browser } = yield loadTab("about:blank", E10SUtils.FILE_REMOTE_TYPE);
+  let { browser } = yield loadTab("about:blank", "file");
 
   hud = yield openConsole();
   hud.jsterm.clearOutput();
 
   let loaded = loadBrowser(browser);
   BrowserTestUtils.loadURI(gBrowser.selectedBrowser, uri.spec);
   yield loaded;
 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -493,17 +493,18 @@ ContentParentsMemoryReporter::CollectRep
     aHandleReport->Callback(/* process */ EmptyCString(), path,
                             KIND_OTHER, UNITS_COUNT,
                             numQueuedMessages, desc, aData);
   }
 
   return NS_OK;
 }
 
-nsClassHashtable<nsStringHashKey, nsTArray<ContentParent*>>* ContentParent::sBrowserContentParents;
+nsTArray<ContentParent*>* ContentParent::sBrowserContentParents;
+nsTArray<ContentParent*>* ContentParent::sLargeAllocationContentParents;
 nsTArray<ContentParent*>* ContentParent::sPrivateContent;
 StaticAutoPtr<LinkedList<ContentParent> > ContentParent::sContentParents;
 #if defined(XP_LINUX) && defined(MOZ_CONTENT_SANDBOX)
 UniquePtr<SandboxBrokerPolicyFactory> ContentParent::sSandboxBrokerPolicyFactory;
 #endif
 
 // This is true when subprocess launching is enabled.  This is the
 // case between StartUp() and ShutDown() or JoinAllSubprocesses().
@@ -642,32 +643,34 @@ ContentParent::JoinAllSubprocesses()
 }
 
 /*static*/ already_AddRefed<ContentParent>
 ContentParent::GetNewOrUsedBrowserProcess(const nsAString& aRemoteType,
                                           ProcessPriority aPriority,
                                           ContentParent* aOpener,
                                           bool aLargeAllocationProcess)
 {
-  if (!sBrowserContentParents) {
-    sBrowserContentParents =
-      new nsClassHashtable<nsStringHashKey, nsTArray<ContentParent*>>;
-  }
+  nsTArray<ContentParent*>* contentParents;
+  int32_t maxContentParents;
 
   // Decide which pool of content parents we are going to be pulling from based
-  // on the aRemoteType and aLargeAllocationProcess flag.
-  nsAutoString contentProcessType(aLargeAllocationProcess
-                                  ? LARGE_ALLOCATION_REMOTE_TYPE : aRemoteType);
-  nsTArray<ContentParent*>* contentParents =
-    sBrowserContentParents->LookupOrAdd(contentProcessType);
-
-  int32_t maxContentParents;
-  nsAutoCString processCountPref("dom.ipc.processCount.");
-  processCountPref.Append(NS_ConvertUTF16toUTF8(contentProcessType));
-  if (NS_FAILED(Preferences::GetInt(processCountPref.get(), &maxContentParents))) {
+  // on the aLargeAllocationProcess flag.
+  if (aLargeAllocationProcess) {
+    if (!sLargeAllocationContentParents) {
+      sLargeAllocationContentParents = new nsTArray<ContentParent*>();
+    }
+    contentParents = sLargeAllocationContentParents;
+
+    maxContentParents = Preferences::GetInt("dom.ipc.dedicatedProcessCount", 2);
+  } else {
+    if (!sBrowserContentParents) {
+      sBrowserContentParents = new nsTArray<ContentParent*>();
+    }
+    contentParents = sBrowserContentParents;
+
     maxContentParents = Preferences::GetInt("dom.ipc.processCount", 1);
   }
 
   if (maxContentParents < 1) {
     maxContentParents = 1;
   }
 
   if (contentParents->Length() >= uint32_t(maxContentParents)) {
@@ -680,24 +683,26 @@ ContentParent::GetNewOrUsedBrowserProces
       NS_ASSERTION(p->IsAlive(), "Non-alive contentparent in sBrowserContentParents?");
       if (p->mOpener == aOpener) {
         return p.forget();
       }
       currIdx = (currIdx + 1) % maxSelectable;
     } while (currIdx != startIdx);
   }
 
-  RefPtr<ContentParent> p = new ContentParent(aOpener, contentProcessType);
+  RefPtr<ContentParent> p = new ContentParent(aOpener, aRemoteType);
 
   if (!p->LaunchSubprocess(aPriority)) {
     return nullptr;
   }
 
   p->Init();
 
+  p->mLargeAllocationProcess = aLargeAllocationProcess;
+
   contentParents->AppendElement(p);
   return p.forget();
 }
 
 /*static*/ ProcessPriority
 ContentParent::GetInitialProcessPriority(Element* aFrameElement)
 {
   // Frames with mozapptype == critical which are expecting a system message
@@ -1278,27 +1283,28 @@ ContentParent::ShutDownMessageManager()
   mMessageManager->Disconnect();
   mMessageManager = nullptr;
 }
 
 void
 ContentParent::MarkAsDead()
 {
   if (sBrowserContentParents) {
-    nsTArray<ContentParent*>* contentParents =
-      sBrowserContentParents->Get(mRemoteType);
-    if (contentParents) {
-      contentParents->RemoveElement(this);
-      if (contentParents->IsEmpty()) {
-        sBrowserContentParents->Remove(mRemoteType);
-        if (sBrowserContentParents->IsEmpty()) {
-          delete sBrowserContentParents;
-          sBrowserContentParents = nullptr;
-        }
-      }
+    sBrowserContentParents->RemoveElement(this);
+    if (!sBrowserContentParents->Length()) {
+      delete sBrowserContentParents;
+      sBrowserContentParents = nullptr;
+    }
+  }
+
+  if (sLargeAllocationContentParents) {
+    sLargeAllocationContentParents->RemoveElement(this);
+    if (!sLargeAllocationContentParents->Length()) {
+      delete sLargeAllocationContentParents;
+      sLargeAllocationContentParents = nullptr;
     }
   }
 
   if (sPrivateContent) {
     sPrivateContent->RemoveElement(this);
     if (!sPrivateContent->Length()) {
       delete sPrivateContent;
       sPrivateContent = nullptr;
@@ -1596,48 +1602,16 @@ ContentParent::ActorDestroy(ActorDestroy
 
   mBlobURLs.Clear();
 
 #if defined(XP_WIN32) && defined(ACCESSIBILITY)
   a11y::AccessibleWrap::ReleaseContentProcessIdFor(ChildID());
 #endif
 }
 
-bool
-ContentParent::ShouldKeepProcessAlive() const
-{
-  if (!sBrowserContentParents) {
-    return false;
-  }
-
-  // If we have already been marked as dead, don't prevent shutdown.
-  if (!IsAlive()) {
-    return false;
-  }
-
-  // Only keep processes for the default remote type alive.
-  if (!mRemoteType.Equals(DEFAULT_REMOTE_TYPE)) {
-    return false;
-  }
-
-  auto contentParents = sBrowserContentParents->Get(mRemoteType);
-  if (!contentParents) {
-    return false;
-  }
-
-  // We might want to keep alive some content processes for testing, because of
-  // performance reasons.
-  // We don't want to alter behavior if the pref is not set, so default to 0.
-  int32_t processesToKeepAlive =
-    Preferences::GetInt("dom.ipc.keepProcessesAlive", 0);
-  int32_t numberOfAliveProcesses = contentParents->Length();
-
-  return numberOfAliveProcesses <= processesToKeepAlive;
-}
-
 void
 ContentParent::NotifyTabDestroying(const TabId& aTabId,
                                    const ContentParentId& aCpId)
 {
   if (XRE_IsParentProcess()) {
     // There can be more than one PBrowser for a given app process
     // because of popup windows.  PBrowsers can also destroy
     // concurrently.  When all the PBrowsers are destroying, kick off
@@ -1649,17 +1623,19 @@ ContentParent::NotifyTabDestroying(const
         return;
     }
     ++cp->mNumDestroyingTabs;
     nsTArray<TabId> tabIds = cpm->GetTabParentsByProcessId(aCpId);
     if (static_cast<size_t>(cp->mNumDestroyingTabs) != tabIds.Length()) {
         return;
     }
 
-    if (cp->ShouldKeepProcessAlive()) {
+    uint32_t numberOfParents = sBrowserContentParents ? sBrowserContentParents->Length() : 0;
+    int32_t processesToKeepAlive = Preferences::GetInt("dom.ipc.keepProcessesAlive", 0);
+    if (!cp->mLargeAllocationProcess && static_cast<int32_t>(numberOfParents) <= processesToKeepAlive) {
       return;
     }
 
     // We're dying now, so prevent this content process from being
     // recycled during its shutdown procedure.
     cp->MarkAsDead();
     cp->StartForceKillTimer();
   } else {
@@ -1702,17 +1678,24 @@ ContentParent::NotifyTabDestroyed(const 
   }
 
   // There can be more than one PBrowser for a given app process
   // because of popup windows.  When the last one closes, shut
   // us down.
   ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
   nsTArray<TabId> tabIds = cpm->GetTabParentsByProcessId(this->ChildID());
 
-  if (tabIds.Length() == 1 && !ShouldKeepProcessAlive()) {
+  // We might want to keep alive some content processes for testing, because of performance
+  // reasons, but we don't want to alter behavior if the pref is not set.
+  uint32_t numberOfParents = sBrowserContentParents ? sBrowserContentParents->Length() : 0;
+  int32_t processesToKeepAlive = Preferences::GetInt("dom.ipc.keepProcessesAlive", 0);
+  bool shouldKeepAliveAny = !mLargeAllocationProcess && processesToKeepAlive > 0;
+  bool shouldKeepAliveThis = shouldKeepAliveAny && static_cast<int32_t>(numberOfParents) <= processesToKeepAlive;
+
+  if (tabIds.Length() == 1 && !shouldKeepAliveThis) {
     // In the case of normal shutdown, send a shutdown message to child to
     // allow it to perform shutdown tasks.
     MessageLoop::current()->PostTask(NewRunnableMethod
                                      <ShutDownMethod>(this,
                                                       &ContentParent::ShutDownProcess,
                                                       SEND_SHUTDOWN_MESSAGE));
   }
 }
@@ -1791,16 +1774,17 @@ ContentParent::LaunchSubprocess(ProcessP
 }
 
 ContentParent::ContentParent(ContentParent* aOpener,
                              const nsAString& aRemoteType)
   : nsIContentParent()
   , mOpener(aOpener)
   , mRemoteType(aRemoteType)
   , mIsForBrowser(!mRemoteType.IsEmpty())
+  , mLargeAllocationProcess(false)
 {
   InitializeMembers();  // Perform common initialization.
 
   // Insert ourselves into the global linked list of ContentParent objects.
   if (!sContentParents) {
     sContentParents = new LinkedList<ContentParent>();
   }
   sContentParents->insertBack(this);
@@ -1826,19 +1810,20 @@ ContentParent::~ContentParent()
   if (mForceKillTimer) {
     mForceKillTimer->Cancel();
   }
 
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   // We should be removed from all these lists in ActorDestroy.
   MOZ_ASSERT(!sPrivateContent || !sPrivateContent->Contains(this));
-  MOZ_ASSERT(!sBrowserContentParents ||
-             !sBrowserContentParents->Contains(mRemoteType) ||
-             !sBrowserContentParents->Get(mRemoteType)->Contains(this));
+  MOZ_ASSERT((!sBrowserContentParents ||
+              !sBrowserContentParents->Contains(this)) &&
+             (!sLargeAllocationContentParents ||
+              !sLargeAllocationContentParents->Contains(this)));
 }
 
 void
 ContentParent::InitInternal(ProcessPriority aInitialPriority,
                             bool aSetupOffMainThreadCompositing,
                             bool aSendRegisteredChrome)
 {
   if (aSendRegisteredChrome) {
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -82,19 +82,16 @@ class PStorageParent;
 class ClonedMessageData;
 class MemoryReport;
 class TabContext;
 class ContentBridgeParent;
 class GetFilesHelper;
 
 // This must match the one in E10SUtils.jsm.
 static NS_NAMED_LITERAL_STRING(DEFAULT_REMOTE_TYPE, "web");
-// This must start with the DEFAULT_REMOTE_TYPE above.
-static NS_NAMED_LITERAL_STRING(LARGE_ALLOCATION_REMOTE_TYPE,
-                               "webLargeAllocation");
 static NS_NAMED_LITERAL_STRING(NO_REMOTE_TYPE, "");
 
 class ContentParent final : public PContentParent
                           , public nsIContentParent
                           , public nsIObserver
                           , public nsIDOMGeoPositionCallback
                           , public nsIDOMGeoPositionErrorCallback
                           , public gfx::gfxVarReceiver
@@ -569,17 +566,18 @@ protected:
   virtual void ActorDestroy(ActorDestroyReason why) override;
 
   bool ShouldContinueFromReplyTimeout() override;
 
   void OnVarChanged(const GfxVarUpdate& aVar) override;
   void OnCompositorUnexpectedShutdown() override;
 
 private:
-  static nsClassHashtable<nsStringHashKey, nsTArray<ContentParent*>>* sBrowserContentParents;
+  static nsTArray<ContentParent*>* sBrowserContentParents;
+  static nsTArray<ContentParent*>* sLargeAllocationContentParents;
   static nsTArray<ContentParent*>* sPrivateContent;
   static StaticAutoPtr<LinkedList<ContentParent> > sContentParents;
 
   static void JoinProcessesIOThread(const nsTArray<ContentParent*>* aProcesses,
                                     Monitor* aMonitor, bool* aDone);
 
   static hal::ProcessPriority GetInitialProcessPriority(Element* aFrameElement);
 
@@ -643,22 +641,16 @@ private:
 
   // Set the child process's priority and then check whether the child is
   // still alive.  Returns true if the process is still alive, and false
   // otherwise.  If you pass a FOREGROUND* priority here, it's (hopefully)
   // unlikely that the process will be killed after this point.
   bool SetPriorityAndCheckIsAlive(hal::ProcessPriority aPriority);
 
   /**
-   * Decide whether the process should be kept alive even when it would normally
-   * be shut down, for example when all its tabs are closed.
-   */
-  bool ShouldKeepProcessAlive() const;
-
-  /**
    * Mark this ContentParent as dead for the purposes of Get*().
    * This method is idempotent.
    */
   void MarkAsDead();
 
   /**
    * How we will shut down this ContentParent and its subprocess.
    */
@@ -1161,16 +1153,17 @@ private:
   RefPtr<embedding::PrintingParent> mPrintingParent;
 #endif
 
   // This hashtable is used to run GetFilesHelper objects in the parent process.
   // GetFilesHelper can be aborted by receiving RecvDeleteGetFilesRequest.
   nsRefPtrHashtable<nsIDHashKey, GetFilesHelper> mGetFilesPendingRequests;
 
   nsTArray<nsCString> mBlobURLs;
+  bool mLargeAllocationProcess;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 class ParentIdleListener : public nsIObserver
 {
   friend class mozilla::dom::ContentParent;
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -2861,27 +2861,16 @@ pref("dom.ipc.plugins.asyncInit.enabled"
 pref("dom.ipc.plugins.asyncdrawing.enabled", false);
 #else
 // Allow the AsyncDrawing mode to be used for plugins in dev channels.
 pref("dom.ipc.plugins.asyncdrawing.enabled", true);
 #endif
 
 pref("dom.ipc.processCount", 1);
 
-// Override default dom.ipc.processCount for some remote content process types.
-pref("dom.ipc.processCount.webLargeAllocation", 2);
-
-// Pref to control whether we use separate content processes for top-level load
-// of file:// URIs.
-#if defined(NIGHTLY_BUILD)
-pref("browser.tabs.remote.separateFileUriProcess", true);
-#else
-pref("browser.tabs.remote.separateFileUriProcess", false);
-#endif
-
 // Enable caching of Moz2D Path objects for SVG geometry elements
 pref("svg.path-caching.enabled", true);
 
 // Enable the use of display-lists for SVG hit-testing and painting.
 pref("svg.display-lists.hit-testing.enabled", true);
 pref("svg.display-lists.painting.enabled", true);
 
 // Is support for the SVG 2 paint-order property enabled?