Bug 1349363 - Centralize pref-checking code for e10s-multi control. r=Felipe. a=gchang
authorBlake Kaplan <mrbkap@gmail.com>
Thu, 20 Apr 2017 12:49:04 +0800
changeset 393621 f6a1a69f8b06986e5a285fc819ff2d361bf8444c
parent 393620 c8a873cdb79ae81b37a2a4657055b19f869647d1
child 393622 25da34a87bee44c977c9824939414aea3d5d83c5
push id7206
push userihsiao@mozilla.com
push dateThu, 20 Apr 2017 04:51:05 +0000
treeherdermozilla-beta@bfa8f90200d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersFelipe, gchang
bugs1349363
milestone54.0
Bug 1349363 - Centralize pref-checking code for e10s-multi control. r=Felipe. a=gchang 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
@@ -716,28 +716,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
@@ -927,16 +927,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)
@@ -4964,18 +4971,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()) {
@@ -5024,16 +5033,52 @@ mozilla::BrowserTabsRemoteAutostart()
   mozilla::Telemetry::Accumulate(mozilla::Telemetry::E10S_STATUS, status);
   if (prefEnabled) {
     mozilla::Telemetry::Accumulate(mozilla::Telemetry::E10S_BLOCKED_FROM_RUNNING,
                                     !gBrowserTabsRemoteAutostart);
   }
   return gBrowserTabsRemoteAutostart;
 }
 
+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;
+}
+
+} // 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.
 
      This function is not available on WinXPSP2 so we dynamically load it.
--- 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.