Bug 1389681 - Move NoteDirty* to Element. r=emilio
authorBobby Holley <bobbyholley@gmail.com>
Fri, 11 Aug 2017 12:04:41 -0700
changeset 423921 b67c043292594bc95263ac81fc0b82b044df29e5
parent 423878 107b8c9fcd76829164580a7042e52bc230364fe1
child 423922 988314683e44e42ab63253c47db3c4e9602c3cbc
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
bugs1389681
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 1389681 - Move NoteDirty* to Element. r=emilio MozReview-Commit-ID: KvKAEuYkssx
dom/base/Element.cpp
dom/base/Element.h
dom/base/nsIContent.h
layout/base/nsCSSFrameConstructor.cpp
layout/style/ServoStyleSet.cpp
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -4197,42 +4197,42 @@ BitIsPropagated(const Element* aElement)
                   parentNode == parentNode->OwnerDoc()->GetRootElement());
   }
   return true;
 }
 #endif
 
 template<typename Traits>
 void
-NoteDirtyContent(nsIContent* aContent)
+NoteDirtyElement(Element* aElement)
 {
-  MOZ_ASSERT(aContent->IsInComposedDoc());
-  nsIDocument* doc = aContent->GetComposedDoc();
+  MOZ_ASSERT(aElement->IsInComposedDoc());
+  nsIDocument* doc = aElement->GetComposedDoc();
   nsIPresShell* shell = doc->GetShell();
   NS_ENSURE_TRUE_VOID(shell);
   shell->EnsureStyleFlush();
 
-  Element* parent = aContent->GetFlattenedTreeParentElementForStyle();
+  Element* parent = aElement->GetFlattenedTreeParentElementForStyle();
   if (!parent || !parent->HasServoData()) {
     // The bits only apply to styled elements.
     return;
   }
 
   Element* curr = parent;
   while (curr && !Traits::HasBit(curr)) {
     Traits::SetBit(curr);
     curr = curr->GetFlattenedTreeParentElementForStyle();
   }
 
   MOZ_ASSERT(BitIsPropagated<Traits>(parent));
 }
 
 void
-nsIContent::NoteDirtyForServo()
+Element::NoteDirtyForServo()
 {
-  NoteDirtyContent<DirtyDescendantsBit>(this);
+  NoteDirtyElement<DirtyDescendantsBit>(this);
 }
 
 void
-nsIContent::NoteAnimationOnlyDirtyForServo()
+Element::NoteAnimationOnlyDirtyForServo()
 {
-  NoteDirtyContent<AnimationOnlyDirtyDescendantsBit>(this);
+  NoteDirtyElement<AnimationOnlyDirtyDescendantsBit>(this);
 }
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -463,16 +463,19 @@ public:
       UpdateState(true);
     }
   }
 
   bool GetBindingURL(nsIDocument* aDocument, css::URLValue **aResult);
 
   Directionality GetComputedDirectionality() const;
 
+  void NoteDirtyForServo();
+  void NoteAnimationOnlyDirtyForServo();
+
   bool HasDirtyDescendantsForServo() const
   {
     MOZ_ASSERT(IsStyledByServo());
     return HasFlag(ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO);
   }
 
   void SetHasDirtyDescendantsForServo() {
     MOZ_ASSERT(IsStyledByServo());
--- a/dom/base/nsIContent.h
+++ b/dom/base/nsIContent.h
@@ -975,19 +975,16 @@ public:
   virtual nsresult GetEventTargetParent(
                      mozilla::EventChainPreVisitor& aVisitor) override;
 
   virtual bool IsPurple() = 0;
   virtual void RemovePurple() = 0;
 
   virtual bool OwnedOnlyByTheDOMTree() { return false; }
 
-  void NoteDirtyForServo();
-  void NoteAnimationOnlyDirtyForServo();
-
 protected:
   /**
    * Hook for implementing GetID.  This is guaranteed to only be
    * called if HasID() is true.
    */
   nsIAtom* DoGetID() const;
 
   // Returns base URI without considering xml:base.
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -7546,18 +7546,25 @@ nsCSSFrameConstructor::MaybeRecreateForF
 }
 
 void
 nsCSSFrameConstructor::LazilyStyleNewChildRange(nsIContent* aStartChild,
                                                 nsIContent* aEndChild)
 {
   for (nsIContent* child = aStartChild; child != aEndChild;
        child = child->GetNextSibling()) {
-    child->NoteDirtyForServo();
-  }
+    if (child->IsElement()) {
+      child->AsElement()->NoteDirtyForServo();
+    }
+  }
+
+  // NoteDirtyForServo() will ensure a style flush, but we don't invoke it for
+  // text nodes. So since this range might include no elements, we still need
+  // to manually ensure a style flush.
+  mPresShell->EnsureStyleFlush();
 }
 
 void
 nsCSSFrameConstructor::StyleNewChildRange(nsIContent* aStartChild,
                                           nsIContent* aEndChild)
 {
   ServoStyleSet* styleSet = mPresShell->StyleSet()->AsServo();
 
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -866,16 +866,20 @@ ServoStyleSet::StyleDocument(ServoTraver
   DocumentStyleRootIterator iter(mPresContext->Document());
   while (Element* root = iter.GetNextStyleRoot()) {
     MOZ_ASSERT(MayTraverseFrom(const_cast<Element*>(root)));
     AutoPrepareTraversal guard(this);
     const SnapshotTable& snapshots = Snapshots();
     bool isInitial = !root->HasServoData();
     auto flags = aBaseFlags;
 
+    // If there were text nodes inserted into the document (but not elements),
+    // there may be lazy frame construction to do even if no styling is required.
+    postTraversalRequired |= root->HasFlag(NODE_DESCENDANTS_NEED_FRAMES);
+
     // Allow the parallel traversal, unless we're traversing traversing one of
     // the native anonymous document style roots, which are tiny and not worth
     // parallelizing over.
     if (!root->IsInNativeAnonymousSubtree()) {
       flags |= ServoTraversalFlags::ParallelTraversal;
     }
 
     // Do the first traversal.