Bug 1390409 part 2 - Replace aParentWasRestyled with a bitflag. r=emilio
authorXidorn Quan <me@upsuper.org>
Mon, 28 Aug 2017 14:53:35 +1000
changeset 426809 2a54187a362e9809ee0a45c4bb7008705f3016b9
parent 426808 9900e7757a4fad3db1f25081d5431cf285ca8840
child 426810 a5c00f0df5be05a13ec87004719a0ac4d410cb22
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1390409
milestone57.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 1390409 part 2 - Replace aParentWasRestyled with a bitflag. r=emilio MozReview-Commit-ID: 49C1N6LNXi7
layout/base/ServoRestyleManager.cpp
layout/base/ServoRestyleManager.h
--- a/layout/base/ServoRestyleManager.cpp
+++ b/layout/base/ServoRestyleManager.cpp
@@ -640,22 +640,31 @@ UpdateFramePseudoElementStyles(nsIFrame*
   if (aFrame->IsFrameOfType(nsIFrame::eBlockFrame)) {
     static_cast<nsBlockFrame*>(aFrame)->UpdatePseudoElementStyles(aRestyleState);
   }
 
   UpdateBackdropIfNeeded(
     aFrame, aRestyleState.StyleSet(), aRestyleState.ChangeList());
 }
 
+enum class ServoPostTraversalFlags : uint32_t
+{
+  Empty = 0,
+  // Whether parent was restyled.
+  ParentWasRestyled = 1 << 0,
+};
+
+MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ServoPostTraversalFlags)
+
 bool
 ServoRestyleManager::ProcessPostTraversal(
   Element* aElement,
   ServoStyleContext* aParentContext,
   ServoRestyleState& aRestyleState,
-  bool aParentWasRestyled)
+  ServoPostTraversalFlags aFlags)
 {
   nsIFrame* styleFrame = nsLayoutUtils::GetStyleFrame(aElement);
   nsIFrame* primaryFrame = aElement->GetPrimaryFrame();
 
   // NOTE(emilio): This is needed because for table frames the bit is set on the
   // table wrapper (which is the primary frame), not on the table itself.
   const bool isOutOfFlow =
     primaryFrame &&
@@ -689,17 +698,18 @@ ServoRestyleManager::ProcessPostTraversa
     } else {
       maybeAnonBoxChild = primaryFrame;
       changeHint = NS_RemoveSubsumedHints(
         changeHint, aRestyleState.ChangesHandledFor(*styleFrame));
     }
 
     // If the parent wasn't restyled, the styles of our anon box parents won't
     // change either.
-    if (aParentWasRestyled && maybeAnonBoxChild->ParentIsWrapperAnonBox()) {
+    if ((aFlags & ServoPostTraversalFlags::ParentWasRestyled) &&
+        maybeAnonBoxChild->ParentIsWrapperAnonBox()) {
       aRestyleState.AddPendingWrapperRestyle(
         ServoRestyleState::TableAwareParentFor(maybeAnonBoxChild));
     }
   }
 
   // Although we shouldn't generate non-ReconstructFrame hints for elements with
   // no frames, we can still get them here if they were explicitly posted by
   // PostRestyleEvent, such as a RepaintFrame hint when a :link changes to be
@@ -812,32 +822,35 @@ ServoRestyleManager::ProcessPostTraversa
       styleFrame, aElement, aRestyleState.ChangeList());
   }
 
   const bool traverseElementChildren =
     aElement->HasAnyOfFlags(Element::kAllServoDescendantBits);
   const bool traverseTextChildren =
     wasRestyled || aElement->HasFlag(NODE_DESCENDANTS_NEED_FRAMES);
   bool recreatedAnyContext = wasRestyled;
+  ServoPostTraversalFlags childrenFlags =
+    wasRestyled ? ServoPostTraversalFlags::ParentWasRestyled
+                : ServoPostTraversalFlags::Empty;
   if (traverseElementChildren || traverseTextChildren) {
     StyleChildrenIterator it(aElement);
     TextPostTraversalState textState(*aElement,
                                      upToDateContext,
                                      displayContentsStyle && wasRestyled,
                                      childrenRestyleState);
     for (nsIContent* n = it.GetNextChild(); n; n = it.GetNextChild()) {
       if (traverseElementChildren && n->IsElement()) {
         recreatedAnyContext |= ProcessPostTraversal(n->AsElement(),
                                                     upToDateContext,
                                                     childrenRestyleState,
-                                                    wasRestyled);
+                                                    childrenFlags);
       } else if (traverseTextChildren && n->IsNodeOfType(nsINode::eTEXT)) {
         recreatedAnyContext |= ProcessPostTraversalForText(n, textState,
                                                            childrenRestyleState,
-                                                           wasRestyled);
+                                                           childrenFlags);
       }
     }
   }
 
   // We want to update frame pseudo-element styles after we've traversed our
   // kids, because some of those updates (::first-line/::first-letter) need to
   // modify the styles of the kids, and the child traversal above would just
   // clobber those modifications.
@@ -874,34 +887,35 @@ ServoRestyleManager::ProcessPostTraversa
   return recreatedAnyContext;
 }
 
 bool
 ServoRestyleManager::ProcessPostTraversalForText(
     nsIContent* aTextNode,
     TextPostTraversalState& aPostTraversalState,
     ServoRestyleState& aRestyleState,
-    bool aParentWasRestyled)
+    ServoPostTraversalFlags aFlags)
 {
   // Handle lazy frame construction.
   if (aTextNode->HasFlag(NODE_NEEDS_FRAME)) {
     aPostTraversalState.ChangeList().AppendChange(
       nullptr, aTextNode, nsChangeHint_ReconstructFrame);
     return true;
   }
 
   // Handle restyle.
   nsIFrame* primaryFrame = aTextNode->GetPrimaryFrame();
   if (!primaryFrame) {
     return false;
   }
 
   // If the parent wasn't restyled, the styles of our anon box parents won't
   // change either.
-  if (aParentWasRestyled && primaryFrame->ParentIsWrapperAnonBox()) {
+  if ((aFlags & ServoPostTraversalFlags::ParentWasRestyled) &&
+      primaryFrame->ParentIsWrapperAnonBox()) {
     aRestyleState.AddPendingWrapperRestyle(
       ServoRestyleState::TableAwareParentFor(primaryFrame));
   }
 
   nsStyleContext& newContext = aPostTraversalState.ComputeStyle(aTextNode);
   aPostTraversalState.ComputeHintIfNeeded(aTextNode, primaryFrame, newContext);
 
   // We want to walk all the continuations here, even the ones with different
@@ -1019,19 +1033,18 @@ ServoRestyleManager::DoProcessPendingRes
     // Recreate style contexts, and queue up change hints (which also handle
     // lazy frame construction).
     {
       AutoRestyleTimelineMarker marker(mPresContext->GetDocShell(), false);
       DocumentStyleRootIterator iter(doc->GetServoRestyleRoot());
       while (Element* root = iter.GetNextStyleRoot()) {
         nsTArray<nsIFrame*> wrappersToRestyle;
         ServoRestyleState state(*styleSet, currentChanges, wrappersToRestyle);
-        anyStyleChanged |=
-          ProcessPostTraversal(root, nullptr, state,
-                               /* aParentWasRestyled = */ false);
+        ServoPostTraversalFlags flags = ServoPostTraversalFlags::Empty;
+        anyStyleChanged |= ProcessPostTraversal(root, nullptr, state, flags);
       }
     }
 
     doc->ClearServoRestyleRoot();
 
     // Process the change hints.
     //
     // Unfortunately, the frame constructor can generate new change hints while
--- a/layout/base/ServoRestyleManager.h
+++ b/layout/base/ServoRestyleManager.h
@@ -158,16 +158,18 @@ private:
 
   // Whether we should assert in our destructor that we've processed all of the
   // relevant wrapper restyles.
 #ifdef DEBUG
   const bool mAssertWrapperRestyleLength = true;
 #endif // DEBUG
 };
 
+enum class ServoPostTraversalFlags : uint32_t;
+
 /**
  * Restyle manager for a Servo-backed style system.
  */
 class ServoRestyleManager : public RestyleManager
 {
   friend class ServoStyleSet;
 
 public:
@@ -257,23 +259,23 @@ private:
    * Returns whether any style did actually change. There may be cases where we
    * didn't need to change any style after all, for example, when a content
    * attribute changes that happens not to have any effect on the style of that
    * element or any descendant or sibling.
    */
   bool ProcessPostTraversal(Element* aElement,
                             ServoStyleContext* aParentContext,
                             ServoRestyleState& aRestyleState,
-                            bool aParentWasRestyled);
+                            ServoPostTraversalFlags aFlags);
 
   struct TextPostTraversalState;
   bool ProcessPostTraversalForText(nsIContent* aTextNode,
                                    TextPostTraversalState& aState,
                                    ServoRestyleState& aRestyleState,
-                                   bool aParentWasRestyled);
+                                   ServoPostTraversalFlags aFlags);
 
   inline ServoStyleSet* StyleSet() const
   {
     MOZ_ASSERT(PresContext()->StyleSet()->IsServo(),
                "ServoRestyleManager should only be used with a Servo-flavored "
                "style backend");
     return PresContext()->StyleSet()->AsServo();
   }