Bug 1331525 - Send the Large-Allocation success message to the correct document, r=ehsan
authorMichael Layzell <michael@thelayzells.com>
Wed, 18 Jan 2017 13:10:54 -0500
changeset 375228 357422df05cd565f9799bc10317e7f7986ed6634
parent 375227 031e8ac3457d8beb672b253291a801797016f6b0
child 375229 31b797ff27420565e351df1321ac03bcc26d3fa9
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1331525
milestone53.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 1331525 - Send the Large-Allocation success message to the correct document, r=ehsan MozReview-Commit-ID: E44hlMI2EE3
dom/base/nsContentUtils.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsPIDOMWindow.h
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -9694,70 +9694,44 @@ nsContentUtils::AttemptLargeAllocationLo
     return false;
   }
 
   nsPIDOMWindowOuter* outer = nsPIDOMWindowOuter::From(window);
   if (NS_WARN_IF(!outer)) {
     return false;
   }
 
-  nsIDocument* doc = outer->GetExtantDoc();
-
   if (!XRE_IsContentProcess()) {
-    if (doc) {
-      nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
-                                      NS_LITERAL_CSTRING("DOM"),
-                                      doc,
-                                      nsContentUtils::eDOM_PROPERTIES,
-                                      "LargeAllocationNonE10S");
-    }
+    outer->SetLargeAllocStatus(LargeAllocStatus::NON_E10S);
     return false;
   }
 
   nsIDocShell* docShell = outer->GetDocShell();
   if (!docShell->GetIsOnlyToplevelInTabGroup()) {
-    if (doc) {
-      nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
-                                      NS_LITERAL_CSTRING("DOM"),
-                                      doc,
-                                      nsContentUtils::eDOM_PROPERTIES,
-                                      "LargeAllocationNotOnlyToplevelInTabGroup");
-    }
+    outer->SetLargeAllocStatus(LargeAllocStatus::NOT_ONLY_TOPLEVEL_IN_TABGROUP);
     return false;
   }
 
   // Get the request method, and check if it is a GET request. If it is not GET,
   // then we cannot perform a large allocation load.
   nsAutoCString requestMethod;
   rv = aChannel->GetRequestMethod(requestMethod);
   NS_ENSURE_SUCCESS(rv, false);
 
   if (NS_WARN_IF(!requestMethod.LowerCaseEqualsLiteral("get"))) {
-    if (doc) {
-      nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
-                                      NS_LITERAL_CSTRING("DOM"),
-                                      doc,
-                                      nsContentUtils::eDOM_PROPERTIES,
-                                      "LargeAllocationNonGetRequest");
-    }
+    outer->SetLargeAllocStatus(LargeAllocStatus::NON_GET);
     return false;
   }
 
-  TabChild* tabChild = TabChild::GetFrom(outer);
+  TabChild* tabChild = TabChild::GetFrom(outer->AsOuter());
   NS_ENSURE_TRUE(tabChild, false);
 
   if (tabChild->TakeIsFreshProcess())  {
     NS_WARNING("Already in a fresh process, ignoring Large-Allocation header!");
-    if (doc) {
-      nsContentUtils::ReportToConsole(nsIScriptError::infoFlag,
-                                      NS_LITERAL_CSTRING("DOM"),
-                                      doc,
-                                      nsContentUtils::eDOM_PROPERTIES,
-                                      "LargeAllocationSuccess");
-    }
+    outer->SetLargeAllocStatus(LargeAllocStatus::SUCCESS);
     return false;
   }
 
   // At this point the fress process load should succeed! We just need to get
   // ourselves a nsIWebBrowserChrome3 to ask to perform the reload. We should
   // have one, as we have already confirmed that we are running in a content
   // process.
   nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -650,17 +650,18 @@ nsPIDOMWindow<T>::nsPIDOMWindow(nsPIDOMW
   mIsActive(false), mIsBackground(false),
   mMediaSuspend(Preferences::GetBool("media.block-autoplay-until-in-foreground", true) ?
     nsISuspendedTypes::SUSPENDED_BLOCK : nsISuspendedTypes::NONE_SUSPENDED),
   mAudioMuted(false), mAudioVolume(1.0), mAudioCaptured(false),
   mDesktopModeViewport(false), mIsRootOuterWindow(false), mInnerWindow(nullptr),
   mOuterWindow(aOuterWindow),
   // Make sure no actual window ends up with mWindowID == 0
   mWindowID(NextWindowID()), mHasNotifiedGlobalCreated(false),
-  mMarkedCCGeneration(0), mServiceWorkersTestingEnabled(false)
+  mMarkedCCGeneration(0), mServiceWorkersTestingEnabled(false),
+  mLargeAllocStatus(LargeAllocStatus::NONE)
 {
   if (aOuterWindow) {
     mTimeoutManager =
       MakeUnique<mozilla::dom::TimeoutManager>(*nsGlobalWindow::Cast(AsInner()));
   }
 }
 
 template<class T>
@@ -2929,16 +2930,21 @@ nsGlobalWindow::SetNewDocument(nsIDocume
       newInnerWindow->mHasNotifiedGlobalCreated = true;
       nsContentUtils::AddScriptRunner(
         NewRunnableMethod(this, &nsGlobalWindow::DispatchDOMWindowCreated));
     }
   }
 
   PreloadLocalStorage();
 
+  // If we have a recorded interesting Large-Allocation header status, report it
+  // to the newly attached document.
+  ReportLargeAllocStatus();
+  mLargeAllocStatus = LargeAllocStatus::NONE;
+
   return NS_OK;
 }
 
 void
 nsGlobalWindow::PreloadLocalStorage()
 {
   MOZ_ASSERT(IsOuterWindow());
 
@@ -13899,16 +13905,58 @@ nsGlobalWindow::CreateNamedPropertiesObj
 
 bool
 nsGlobalWindow::GetIsPrerendered()
 {
   nsIDocShell* docShell = GetDocShell();
   return docShell && docShell->GetIsPrerendered();
 }
 
+void
+nsPIDOMWindowOuter::SetLargeAllocStatus(LargeAllocStatus aStatus)
+{
+  MOZ_ASSERT(mLargeAllocStatus == LargeAllocStatus::NONE);
+  mLargeAllocStatus = aStatus;
+}
+
+void
+nsGlobalWindow::ReportLargeAllocStatus()
+{
+  MOZ_RELEASE_ASSERT(IsOuterWindow());
+
+  uint32_t errorFlags = nsIScriptError::warningFlag;
+  const char* message = nullptr;
+
+  switch (mLargeAllocStatus) {
+    case LargeAllocStatus::SUCCESS:
+      // Override the error flags such that the success message isn't reported
+      // as a warning.
+      errorFlags = nsIScriptError::infoFlag;
+      message = "LargeAllocationSuccess";
+      break;
+    case LargeAllocStatus::NON_GET:
+      message = "LargeAllocationNonGetRequest";
+      break;
+    case LargeAllocStatus::NON_E10S:
+      message = "LargeAllocationNonE10S";
+      break;
+    case LargeAllocStatus::NOT_ONLY_TOPLEVEL_IN_TABGROUP:
+      message = "LargeAllocationNotOnlyToplevelInTabGroup";
+      break;
+    default: // LargeAllocStatus::NONE
+      return; // Don't report a message to the console
+  }
+
+  nsContentUtils::ReportToConsole(errorFlags,
+                                  NS_LITERAL_CSTRING("DOM"),
+                                  mDoc,
+                                  nsContentUtils::eDOM_PROPERTIES,
+                                  message);
+}
+
 #ifdef MOZ_B2G
 void
 nsGlobalWindow::EnableNetworkEvent(EventMessage aEventMessage)
 {
   MOZ_ASSERT(IsInnerWindow());
 
   nsCOMPtr<nsIPermissionManager> permMgr =
     services::GetPermissionManager();
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -1557,16 +1557,20 @@ public:
   PopupControlState RevisePopupAbuseLevel(PopupControlState);
   void     FireAbuseEvents(const nsAString &aPopupURL,
                            const nsAString &aPopupWindowName,
                            const nsAString &aPopupWindowFeatures);
   void FireOfflineStatusEventIfChanged();
 
   bool GetIsPrerendered();
 
+private:
+  void ReportLargeAllocStatus();
+
+public:
   // Inner windows only.
   nsresult ScheduleNextIdleObserverCallback();
   uint32_t GetFuzzTimeMS();
   nsresult ScheduleActiveTimerCallback();
   uint32_t FindInsertionIndex(IdleObserverHolder* aIdleObserver);
   virtual nsresult RegisterIdleObserver(nsIIdleObserver* aIdleObserverPtr) override;
   nsresult FindIndexOfElementToRemove(nsIIdleObserver* aIdleObserver,
                                       int32_t* aRemoveElementIndex);
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -83,16 +83,39 @@ enum class FullscreenReason
   // Fullscreen API is the API provided to untrusted content.
   ForFullscreenAPI,
   // This reason can only be used with exiting fullscreen.
   // It is otherwise identical to eForFullscreenAPI except it would
   // suppress the fullscreen transition.
   ForForceExitFullscreen
 };
 
+namespace mozilla {
+namespace dom {
+// The states in this enum represent the different possible outcomes which the
+// window could be experiencing of loading a document with the
+// Large-Allocation header. The NONE case represents the case where no
+// Large-Allocation header was set.
+enum class LargeAllocStatus : uint8_t
+{
+  // These are the OK states, NONE means that no large allocation status message
+  // should be printed, while SUCCESS means that the success message should be
+  // printed.
+  NONE,
+  SUCCESS,
+
+  // These are the ERROR states. If a window is in one of these states, then the
+  // next document loaded in that window should have an error message reported
+  // to it.
+  NON_GET,
+  NON_E10S,
+  NOT_ONLY_TOPLEVEL_IN_TABGROUP
+};
+} // namespace dom
+} // namespace mozilla
 
 // nsPIDOMWindowInner and nsPIDOMWindowOuter are identical in all respects
 // except for the type name. They *must* remain identical so that we can
 // reinterpret_cast between them.
 template<class T>
 class nsPIDOMWindow : public T
 {
 public:
@@ -705,16 +728,18 @@ protected:
   // the (chrome|content)-document-global-created notification.
   bool mHasNotifiedGlobalCreated;
 
   uint32_t mMarkedCCGeneration;
 
   // Let the service workers plumbing know that some feature are enabled while
   // testing.
   bool mServiceWorkersTestingEnabled;
+
+  mozilla::dom::LargeAllocStatus mLargeAllocStatus; // Outer window only
 };
 
 #define NS_PIDOMWINDOWINNER_IID \
 { 0x775dabc9, 0x8f43, 0x4277, \
   { 0x9a, 0xdb, 0xf1, 0x99, 0x0d, 0x77, 0xcf, 0xfb } }
 
 #define NS_PIDOMWINDOWOUTER_IID \
   { 0x769693d4, 0xb009, 0x4fe2, \
@@ -935,16 +960,18 @@ public:
 
   float GetAudioVolume() const;
   nsresult SetAudioVolume(float aVolume);
 
   void SetServiceWorkersTestingEnabled(bool aEnabled);
   bool GetServiceWorkersTestingEnabled();
 
   float GetDevicePixelRatio(mozilla::dom::CallerType aCallerType);
+
+  void SetLargeAllocStatus(mozilla::dom::LargeAllocStatus aStatus);
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsPIDOMWindowOuter, NS_PIDOMWINDOWOUTER_IID)
 
 #include "nsPIDOMWindowInlines.h"
 
 #ifdef MOZILLA_INTERNAL_API
 PopupControlState