Bug 1398119: Move the common case of NoteDirtyElement during innerHTML up. draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Fri, 08 Sep 2017 16:27:12 +0200
changeset 661524 178fe799e2836ed85ba65f6e3268aec8657ea63b
parent 661476 b0ca53f97034770ed0ec5e59897939e60aef88da
child 730615 2a0fbc95f1b22be332c412d644d7b96bd1cada1f
push id78809
push userbmo:emilio@crisal.io
push dateFri, 08 Sep 2017 17:27:08 +0000
bugs1398119
milestone57.0a1
Bug 1398119: Move the common case of NoteDirtyElement during innerHTML up. MozReview-Commit-ID: 4KznPYcBr05
dom/base/Element.cpp
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -4349,16 +4349,31 @@ PropagateBits(Element* aElement, uint32_
 // element under the current root is dirtied, that's why we don't trivially use
 // `nsContentUtils::GetCommonFlattenedTreeAncestorForStyle`.
 static void
 NoteDirtyElement(Element* aElement, uint32_t aBits)
 {
   MOZ_ASSERT(aElement->IsInComposedDoc());
   MOZ_ASSERT(aElement->IsStyledByServo());
 
+  nsIDocument* doc = aElement->GetComposedDoc();
+
+  nsINode* existingRoot = doc->GetServoRestyleRoot();
+  uint32_t existingBits = existingRoot ? doc->GetServoRestyleRootDirtyBits() : 0;
+
+  // The bit checks below rely on this to arrive to useful conclusions about the
+  // shape of the tree.
+  AssertNoBitsPropagatedFrom(existingRoot);
+
+  // If the root is already aElement, just note the root+bits and return.
+  if (existingRoot == aElement) {
+    doc->SetServoRestyleRoot(aElement, existingBits | aBits);
+    return;
+  }
+
   Element* parent = aElement->GetFlattenedTreeParentElementForStyle();
   if (MOZ_LIKELY(parent)) {
     // If our parent is unstyled, we can inductively assume that it will be
     // traversed when the time is right, and that the traversal will reach us
     // when it happens. Nothing left to do.
     if (!parent->HasServoData()) {
       return;
     }
@@ -4380,32 +4395,23 @@ NoteDirtyElement(Element* aElement, uint
     // The check above doesn't work for <area> element because <area> always
     // have display:none, but before we fix bug 135040, it may have primary
     // frame from <img>.
     if (parent->IsHTMLElement(nsGkAtoms::area)) {
       return;
     }
   }
 
-  nsIDocument* doc = aElement->GetComposedDoc();
-  if (nsIPresShell* shell = doc->GetShell()) {
-    shell->EnsureStyleFlush();
-  }
-
-  nsINode* existingRoot = doc->GetServoRestyleRoot();
-  uint32_t existingBits = existingRoot ? doc->GetServoRestyleRootDirtyBits() : 0;
-
-  // The bit checks below rely on this to arrive to useful conclusions about the
-  // shape of the tree.
-  AssertNoBitsPropagatedFrom(existingRoot);
-
-  // If there's no existing restyle root, or if the root is already aElement,
-  // just note the root+bits and return.
-  if (!existingRoot || existingRoot == aElement) {
-    doc->SetServoRestyleRoot(aElement, existingBits | aBits);
+  // If there's no existing restyle root, just record it and ensure a style
+  // flush happens.
+  if (!existingRoot) {
+    if (nsIPresShell* shell = doc->GetShell()) {
+      shell->EnsureStyleFlush();
+    }
+    doc->SetServoRestyleRoot(aElement, aBits);
     return;
   }
 
   // There is an existing restyle root - walk up the tree from our element,
   // propagating bits as we go.
   const bool reachedDocRoot = !parent || !PropagateBits(parent, aBits, existingRoot);
 
   if (!reachedDocRoot || existingRoot == doc) {