Backed out changeset 35afffcb4182 (bug 1374235) for build bustage because it landed before its servo commit. r=backout
authorSebastian Hengst <archaeopteryx@coole-files.de>
Fri, 01 Sep 2017 14:07:47 +0200
changeset 378207 be68eab4aba7939fb76bb9a6dec2887e800a965f
parent 378206 6341b88c5ecd5e1c177507a328896151fecd7869
child 378208 48bb34b7675cbf5b0bf9d19b3c95bd62a70767a2
push id50212
push userarchaeopteryx@coole-files.de
push dateFri, 01 Sep 2017 12:08:06 +0000
treeherderautoland@be68eab4aba7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1374235
milestone57.0a1
backs out35afffcb4182a3e703fae6fbf68da777325e625a
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
Backed out changeset 35afffcb4182 (bug 1374235) for build bustage because it landed before its servo commit. r=backout
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsCSSFrameConstructor.h
layout/style/ServoStyleSet.cpp
layout/style/ServoStyleSet.h
layout/style/ServoTypes.h
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -7593,16 +7593,32 @@ nsCSSFrameConstructor::StyleNewChildRang
       if (MOZ_LIKELY(parent) && parent->HasServoData()) {
         styleSet->StyleNewChildren(parent);
       }
     }
   }
 }
 
 void
+nsCSSFrameConstructor::StyleChildRangeForReconstruct(nsIContent* aStartChild,
+                                                     nsIContent* aEndChild)
+{
+  ServoStyleSet* styleSet = mPresShell->StyleSet()->AsServo();
+
+  // We take a parallelism hit here, since we don't have a great API to pass
+  // a range of elements to style to Servo.
+  for (nsIContent* child = aStartChild; child != aEndChild;
+       child = child->GetNextSibling()) {
+    if (child->IsElement()) {
+      styleSet->StyleSubtreeForReconstruct(child->AsElement());
+    }
+  }
+}
+
+void
 nsCSSFrameConstructor::ContentAppended(nsIContent* aContainer,
                                        nsIContent* aFirstNewContent,
                                        bool aAllowLazyConstruction,
                                        bool aForReconstruction,
                                        TreeMatchContext* aProvidedTreeMatchContext)
 {
   MOZ_ASSERT(!aProvidedTreeMatchContext || !aAllowLazyConstruction);
   MOZ_ASSERT(!aAllowLazyConstruction || !RestyleManager()->IsInStyleRefresh());
@@ -7681,18 +7697,22 @@ nsCSSFrameConstructor::ContentAppended(n
       if (isNewlyAddedContentForServo) {
         LazilyStyleNewChildRange(aFirstNewContent, nullptr);
       }
       return;
     }
   }
 
   // We couldn't construct lazily. Make Servo eagerly traverse the new content.
-  if (isNewlyAddedContentForServo) {
-    StyleNewChildRange(aFirstNewContent, nullptr);
+  if (aContainer->IsStyledByServo()) {
+    if (aForReconstruction) {
+      StyleChildRangeForReconstruct(aFirstNewContent, nullptr);
+    } else {
+      StyleNewChildRange(aFirstNewContent, nullptr);
+    }
   }
 
   if (isNewShadowTreeContent) {
     // Recreate frames if content is appended into a ShadowRoot
     // because children of ShadowRoot are rendered in place of children
     // of the host.
     //XXXsmaug This is super unefficient!
     nsIContent* bindingParent = aContainer->GetBindingParent();
@@ -8166,18 +8186,22 @@ nsCSSFrameConstructor::ContentRangeInser
       if (isNewlyAddedContentForServo) {
         LazilyStyleNewChildRange(aStartChild, aEndChild);
       }
       return;
     }
   }
 
   // We couldn't construct lazily. Make Servo eagerly traverse the new content.
-  if (isNewlyAddedContentForServo) {
-    StyleNewChildRange(aStartChild, aEndChild);
+  if (aContainer->IsStyledByServo()) {
+    if (aForReconstruction) {
+      StyleChildRangeForReconstruct(aStartChild, aEndChild);
+    } else {
+      StyleNewChildRange(aStartChild, aEndChild);
+    }
   }
 
   if (isNewShadowTreeContent) {
     // Recreate frames if content is inserted into a ShadowRoot
     // because children of ShadowRoot are rendered in place of
     // the children of the host.
     //XXXsmaug This is super unefficient!
     nsIContent* bindingParent = aContainer->GetBindingParent();
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -180,16 +180,23 @@ private:
    * on their flattened tree parents.  This is used when content is inserted
    * into the document and we decide that we cannot do lazy frame construction.
    * It handles children being rebound to different insertion points by calling
    * StyleNewChildren on each child's flattened tree parent.  Only used when we
    * are styled by Servo.
    */
   void StyleNewChildRange(nsIContent* aStartChild, nsIContent* aEndChild);
 
+  /**
+   * Calls StyleSubtreeForReconstruct on each child in the aStartChild/aEndChild
+   * range. Only used when we are styled by Servo.
+   */
+  void StyleChildRangeForReconstruct(nsIContent* aStartChild,
+                                     nsIContent* aEndChild);
+
 public:
   /**
    * Lazy frame construction is controlled by the aAllowLazyConstruction bool
    * parameter of nsCSSFrameConstructor::ContentAppended/Inserted. It is true
    * for all inserts/appends as passed from the presshell, except for the
    * insert of the root element, which is always non-lazy. Even if the
    * aAllowLazyConstruction passed to ContentAppended/Inserted is true we still
    * may not be able to construct lazily, so we call MaybeConstructLazily.
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -1047,16 +1047,57 @@ ServoStyleSet::StyleNewlyBoundElement(El
   if (MOZ_LIKELY(aElement->HasServoData())) {
     StyleNewChildren(aElement);
   } else {
     StyleNewSubtree(aElement);
   }
 }
 
 void
+ServoStyleSet::StyleSubtreeForReconstruct(Element* aRoot)
+{
+  MOZ_ASSERT(MayTraverseFrom(aRoot));
+  MOZ_ASSERT(aRoot->HasServoData());
+
+  // If the restyle root is beneath |aRoot|, there won't be any descendants bit
+  // leading us to aRoot. In this case, we need to traverse from the restyle
+  // root instead.
+  nsIDocument* doc = mPresContext->Document();
+  nsINode* restyleRoot = doc->GetServoRestyleRoot();
+  if (!restyleRoot) {
+    return;
+  }
+  Element* el = restyleRoot->IsElement() ? restyleRoot->AsElement() : nullptr;
+  if (el && nsContentUtils::ContentIsFlattenedTreeDescendantOf(el, aRoot)) {
+    MOZ_ASSERT(MayTraverseFrom(el));
+    aRoot = el;
+    doc->ClearServoRestyleRoot();
+  }
+
+  auto flags = ServoTraversalFlags::Forgetful |
+               ServoTraversalFlags::AggressivelyForgetful |
+               ServoTraversalFlags::ClearDirtyBits;
+  PreTraverse(flags);
+
+  AutoPrepareTraversal guard(this);
+
+  const SnapshotTable& snapshots = Snapshots();
+
+  DebugOnly<bool> postTraversalRequired =
+    Servo_TraverseSubtree(aRoot, mRawSet.get(), &snapshots, flags);
+  MOZ_ASSERT(!postTraversalRequired);
+
+  if (mPresContext->EffectCompositor()->PreTraverseInSubtree(flags, aRoot)) {
+    postTraversalRequired =
+      Servo_TraverseSubtree(aRoot, mRawSet.get(), &snapshots, flags);
+    MOZ_ASSERT(!postTraversalRequired);
+  }
+}
+
+void
 ServoStyleSet::MarkOriginsDirty(OriginFlags aChangedOrigins)
 {
   SetStylistStyleSheetsDirty();
   Servo_StyleSet_NoteStyleSheetsChanged(mRawSet.get(),
                                         mAuthorStyleDisabled,
                                         aChangedOrigins);
 }
 
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -298,16 +298,26 @@ public:
    * Eagerly styles the children of an element that has just had an XBL
    * binding applied to it.  Some XBL consumers attach bindings to elements
    * that have not been styled yet, and in such cases, this will do the
    * equivalent of StyleNewSubtree instead.
    */
   void StyleNewlyBoundElement(dom::Element* aElement);
 
   /**
+   * Like StyleNewSubtree, but in response to a request to reconstruct frames
+   * for the given subtree, and so works on elements that already have
+   * styles.  This will leave the subtree in a state just like after an initial
+   * styling, i.e. with new styles, no change hints, and with the dirty
+   * descendants bits cleared.  No comparison of old and new styles is done,
+   * so no change hints will be processed.
+   */
+  void StyleSubtreeForReconstruct(dom::Element* aRoot);
+
+  /**
    * Helper for correctly calling UpdateStylist without paying the cost of an
    * extra function call in the common no-rebuild-needed case.
    */
   void UpdateStylistIfNeeded()
   {
     if (StylistNeedsUpdate()) {
       UpdateStylist();
     }
--- a/layout/style/ServoTypes.h
+++ b/layout/style/ServoTypes.h
@@ -62,16 +62,19 @@ enum class ServoTraversalFlags : uint32_
   // Styles unstyled elements, but does not handle invalidations on
   // already-styled elements.
   UnstyledOnly = 1 << 2,
   // A forgetful traversal ignores the previous state of the frame tree, and
   // thus does not compute damage or maintain other state describing the styles
   // pre-traversal. A forgetful traversal is usually the right thing if you
   // aren't going to do a post-traversal.
   Forgetful = 1 << 3,
+  // Actively seeks out and clears change hints that may have been posted into
+  // the tree. Nonsensical without also passing Forgetful.
+  AggressivelyForgetful = 1 << 4,
   // Clears all the dirty bits (dirty descendants, animation-only dirty-descendants,
   // needs frame, descendants need frames) on the elements traversed.
   // in the subtree.
   ClearDirtyBits = 1 << 5,
   // Clears only the animation-only dirty descendants bit in the subtree.
   ClearAnimationOnlyDirtyDescendants = 1 << 6,
   // Allows the traversal to run in parallel if there are sufficient cores on
   // the machine.