Bug 1349363 - Centralize pref-checking code for e10s-multi control. r=Felipe draft
authorBlake Kaplan <mrbkap@gmail.com>
Mon, 17 Apr 2017 14:36:04 -0700
changeset 564564 6a0541ec0e0c613a4eafa4e8e3729dcda1f3f8cf
parent 564445 722fdbff1efc308a22060e75b603311d23541bb5
child 564565 e60ef55ff64e3e74ee23b0bd77ef0e0bcc0c6c3a
push id54642
push userbmo:mrbkap@mozilla.com
push dateTue, 18 Apr 2017 19:22:13 +0000
reviewersFelipe
bugs1349363
milestone55.0a1
Bug 1349363 - Centralize pref-checking code for e10s-multi control. r=Felipe This patch centralizes all of the pref-checking code for e10s-multi in a single function. It is intended to be used throughout the codebase to see if e10s-multi is "on". It also introduces dom.ipc.multiOptOut, which can be set by the user to indicate that they do not want to participate in the e10s-multi experiment. MozReview-Commit-ID: Kyq1fqNzwue
dom/ipc/ContentParent.cpp
toolkit/xre/nsAppRunner.cpp
xpcom/system/nsIXULRuntime.idl
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -707,28 +707,22 @@ ContentParent::GetOrCreatePool(const nsA
   }
 
   return *sBrowserContentParents->LookupOrAdd(aContentProcessType);
 }
 
 /*static*/ uint32_t
 ContentParent::GetMaxProcessCount(const nsAString& aContentProcessType)
 {
+  if (aContentProcessType.EqualsLiteral("web")) {
+    return GetMaxWebProcessCount();
+  }
+
   nsAutoCString processCountPref("dom.ipc.processCount.");
   processCountPref.Append(NS_ConvertUTF16toUTF8(aContentProcessType));
-  bool hasUserValue = Preferences::HasUserValue(processCountPref.get()) ||
-                      Preferences::HasUserValue("dom.ipc.processCount");
-
-  // Let's respect the user's decision to enable multiple content processes
-  // despite some add-ons installed that might performing poorly.
-  if (!hasUserValue &&
-      Preferences::GetBool("extensions.e10sMultiBlocksEnabling", false) &&
-      Preferences::GetBool("extensions.e10sMultiBlockedByAddons", false)) {
-    return 1;
-  }
 
   int32_t maxContentParents;
   if (NS_FAILED(Preferences::GetInt(processCountPref.get(), &maxContentParents))) {
     maxContentParents = Preferences::GetInt("dom.ipc.processCount", 1);
   }
 
   if (maxContentParents < 1) {
     maxContentParents = 1;
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -930,16 +930,23 @@ nsXULAppInfo::Observe(nsISupports *aSubj
 NS_IMETHODIMP
 nsXULAppInfo::GetBrowserTabsRemoteAutostart(bool* aResult)
 {
   *aResult = BrowserTabsRemoteAutostart();
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsXULAppInfo::GetMaxWebProcessCount(uint32_t* aResult)
+{
+  *aResult = mozilla::GetMaxWebProcessCount();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsXULAppInfo::GetMultiprocessBlockPolicy(uint32_t* aResult)
 {
   *aResult = MultiprocessBlockPolicy();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULAppInfo::GetAccessibilityEnabled(bool* aResult)
@@ -5013,18 +5020,20 @@ MultiprocessBlockPolicy() {
   /*
    * None of the blocking policies matched, so e10s is allowed to run.
    * Cache the information and return 0, indicating success.
    */
   gMultiprocessBlockPolicy = 0;
   return 0;
 }
 
+namespace mozilla {
+
 bool
-mozilla::BrowserTabsRemoteAutostart()
+BrowserTabsRemoteAutostart()
 {
   if (gBrowserTabsRemoteAutostartInitialized) {
     return gBrowserTabsRemoteAutostart;
   }
   gBrowserTabsRemoteAutostartInitialized = true;
 
   // If we're in the content process, we are running E10S.
   if (XRE_IsContentProcess()) {
@@ -5073,23 +5082,57 @@ mozilla::BrowserTabsRemoteAutostart()
   mozilla::Telemetry::Accumulate(mozilla::Telemetry::E10S_STATUS, status);
   if (prefEnabled) {
     mozilla::Telemetry::Accumulate(mozilla::Telemetry::E10S_BLOCKED_FROM_RUNNING,
                                     !gBrowserTabsRemoteAutostart);
   }
   return gBrowserTabsRemoteAutostart;
 }
 
-namespace mozilla {
+uint32_t
+GetMaxWebProcessCount()
+{
+  // multiOptOut is in int to allow us to run multiple experiments without
+  // introducing multiple prefs a la the autostart.N prefs.
+  if (Preferences::GetInt("dom.ipc.multiOptOut", 0) >=
+          nsIXULRuntime::E10S_MULTI_EXPERIMENT) {
+    return 1;
+  }
+
+  const char* optInPref = "dom.ipc.processCount";
+  uint32_t optInPrefValue = Preferences::GetInt(optInPref, 1);
+
+  // If the user has set dom.ipc.processCount, respect their decision
+  // regardless of add-ons that might affect their experience or experiment
+  // cohort.
+  if (Preferences::HasUserValue(optInPref)) {
+    return std::max(1u, optInPrefValue);
+  }
+
+  // If there are add-ons that would make the user's experience poor, don't
+  // use more than one web content process.
+  if (Preferences::GetBool("extensions.e10sMultiBlocksEnabling", false) &&
+      Preferences::GetBool("extensions.e10sMultiBlockedByAddons", false)) {
+    return 1;
+  }
+
+  if (Preferences::HasUserValue("dom.ipc.processCount.web")) {
+    // The user didn't opt in or out so read the .web version of the pref.
+    return std::max(1, Preferences::GetInt("dom.ipc.processCount.web", 1));
+  }
+  return optInPrefValue;
+}
+
 const char*
 PlatformBuildID()
 {
   return gToolkitBuildID;
 }
-}
+
+} // namespace mozilla
 
 void
 SetupErrorHandling(const char* progname)
 {
 #ifdef XP_WIN
   /* On Windows XPSP3 and Windows Vista if DEP is configured off-by-default
      we still want DEP protection: enable it explicitly and programmatically.
 
--- a/xpcom/system/nsIXULRuntime.idl
+++ b/xpcom/system/nsIXULRuntime.idl
@@ -7,16 +7,17 @@
 %{C++
 
 namespace mozilla {
 // Simple C++ getter for nsIXULRuntime::browserTabsRemoteAutostart
 // This getter is a temporary function that checks for special
 // conditions in which e10s support is not great yet, and should
 // therefore be disabled. Bug 1065561 tracks its removal.
 bool BrowserTabsRemoteAutostart();
+uint32_t GetMaxWebProcessCount();
 }
 
 %}
 
 /**
  * Provides information about the XUL runtime.
  * @status UNSTABLE - This interface is not frozen and will probably change in
  *                    future releases. If you need this functionality to be
@@ -99,16 +100,31 @@ interface nsIXULRuntime : nsISupports
 
   /**
    * If true, browser tabs may be opened by default in a different process
    * from the main browser UI.
    */
   readonly attribute boolean browserTabsRemoteAutostart;
 
   /**
+   * Returns the number of content processes to use for normal web pages. If
+   * this value is > 1, then e10s-multi should be considered to be "on".
+   *
+   * NB: If browserTabsRemoteAutostart is false, then this value has no
+   * meaning and e10s should be considered to be "off"!
+   */
+  readonly attribute uint32_t maxWebProcessCount;
+
+  /**
+   * The current e10s-multi experiment number. Set dom.ipc.multiOptOut to (at
+   * least) this to disable it until the next experiment.
+   */
+  const uint32_t E10S_MULTI_EXPERIMENT = 1;
+
+  /**
    * A numeric value indicating whether multiprocess might be blocked.
    * Possible values can be found at nsAppRunner.cpp. A value of 0
    * represents not blocking.
    */
    readonly attribute unsigned long multiprocessBlockPolicy;
 
   /**
    * If true, the accessibility service is running.