Bug 1271015 patch 1 - Add mechanism for testing the number of elements restyled. r=heycam
authorL. David Baron <dbaron@dbaron.org>
Mon, 09 May 2016 11:26:35 -0700
changeset 321157 9c02ff079d45144e04587124f1d6ec3e407b6a11
parent 321156 bed3ca8d4a30edde13143cc513ff891411126c4a
child 321158 048db7c7e4881e6da9fb5dd5742326485ced03de
push id9671
push userraliiev@mozilla.com
push dateMon, 06 Jun 2016 20:27:52 +0000
treeherdermozilla-aurora@cea65ca3d0bd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1271015, 1189598
milestone49.0a1
Bug 1271015 patch 1 - Add mechanism for testing the number of elements restyled. r=heycam This is useful for writing tests that test particular optimizations, such as that a particular operation doesn't cause restyles. It sits next to similar counters for frames constructed and frames reflowed. I also snuck in a preference for the less-expensive mPresContext over the more expensive mFrame->PresContext() (which dereferences multiple pointers). (Originally written for work I planned to be part of bug 1189598.) MozReview-Commit-ID: 8PN7nwLJG9r
dom/base/nsDOMWindowUtils.cpp
dom/interfaces/base/nsIDOMWindowUtils.idl
layout/base/RestyleManager.cpp
layout/base/nsPresContext.h
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -3777,16 +3777,28 @@ nsDOMWindowUtils::XpconnectArgument(nsID
 NS_IMETHODIMP
 nsDOMWindowUtils::AskPermission(nsIContentPermissionRequest* aRequest)
 {
   nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
   return nsContentPermissionUtils::AskPermission(aRequest, window->GetCurrentInnerWindow());
 }
 
 NS_IMETHODIMP
+nsDOMWindowUtils::GetElementsRestyled(uint64_t* aResult)
+{
+  nsPresContext* presContext = GetPresContext();
+  if (!presContext) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
+  *aResult = presContext->ElementsRestyledCount();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsDOMWindowUtils::GetFramesConstructed(uint64_t* aResult)
 {
   nsPresContext* presContext = GetPresContext();
   if (!presContext) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   *aResult = presContext->FramesConstructedCount();
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -1777,16 +1777,27 @@ interface nsIDOMWindowUtils : nsISupport
 
   /**
    * Helper for JS components that need to send permission requests with
    * e10s support properly.
    */
   void askPermission(in nsIContentPermissionRequest aRequest);
 
   /**
+   * Number of elements restyled for the curent document.
+   *
+   * Note that during a restyle operation we may restyle an element more
+   * than once (e.g., for an inline that contains blocks).  This also
+   * counts restyling of pseudo-elements and anonymous boxes.
+   *
+   * May throw NS_ERROR_NOT_AVAILABLE.
+   */
+  readonly attribute unsigned long long elementsRestyled;
+
+  /**
    * Number of frames constructed (excluding breaking) for the curent
    * document.
    *
    * May throw NS_ERROR_NOT_AVAILABLE.
    */
   readonly attribute unsigned long long framesConstructed;
 
   /**
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -3218,24 +3218,27 @@ ElementRestyler::Restyle(nsRestyleHint a
   // |content| and |pseudoContent| mean, and their relationship to
   // |mFrame->GetContent()|, make more sense.  However, we can't,
   // because of frame trees like the one in
   // https://bugzilla.mozilla.org/show_bug.cgi?id=472353#c14 .  Once we
   // fix bug 242277 we should be able to make this make more sense.
   NS_ASSERTION(mFrame->GetContent() || !mParentContent ||
                !mParentContent->GetParent(),
                "frame must have content (unless at the top of the tree)");
+  MOZ_ASSERT(mPresContext == mFrame->PresContext(), "pres contexts match");
 
   NS_ASSERTION(!GetPrevContinuationWithSameStyle(mFrame),
                "should not be trying to restyle this frame separately");
 
   MOZ_ASSERT(!(aRestyleHint & eRestyle_LaterSiblings),
              "eRestyle_LaterSiblings must not be part of aRestyleHint");
 
-  AutoDisplayContentsAncestorPusher adcp(mTreeMatchContext, mFrame->PresContext(),
+  mPresContext->RestyledElement();
+
+  AutoDisplayContentsAncestorPusher adcp(mTreeMatchContext, mPresContext,
       mFrame->GetContent() ? mFrame->GetContent()->GetParent() : nullptr);
 
   AutoSelectorArrayTruncater asat(mSelectorsForDescendants);
 
   // List of descendant elements of mContent we know we will eventually need to
   // restyle.  Before we return from this function, we call
   // RestyleTracker::AddRestyleRootsIfAwaitingRestyle to ensure they get
   // restyled in RestyleTracker::DoProcessRestyles.
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -846,23 +846,29 @@ public:
   */
   bool EnsureVisible();
 
 #ifdef MOZ_REFLOW_PERF
   void CountReflows(const char * aName,
                                 nsIFrame * aFrame);
 #endif
 
+  void RestyledElement() {
+    ++mElementsRestyled;
+  }
   void ConstructedFrame() {
     ++mFramesConstructed;
   }
   void ReflowedFrame() {
     ++mFramesReflowed;
   }
 
+  uint64_t ElementsRestyledCount() {
+    return mElementsRestyled;
+  }
   uint64_t FramesConstructedCount() {
     return mFramesConstructed;
   }
   uint64_t FramesReflowedCount() {
     return mFramesReflowed;
   }
 
   /**
@@ -1298,16 +1304,17 @@ protected:
   LangGroupFontPrefs    mLangGroupFontPrefs;
 
   nscoord               mBorderWidthTable[3];
 
   uint32_t              mInterruptChecksToSkip;
 
   // Counters for tests and tools that want to detect frame construction
   // or reflow.
+  uint64_t              mElementsRestyled;
   uint64_t              mFramesConstructed;
   uint64_t              mFramesReflowed;
 
   mozilla::TimeStamp    mReflowStartTime;
 
   // last time we did a full style flush
   mozilla::TimeStamp    mLastStyleUpdateForAllAnimations;