Bug 1394935: Assert that we don't call into NoteDirtyElement with extra bits on the restyle root's parent chain. r=bholley
authorEmilio Cobos Álvarez <emilio@crisal.io>
Thu, 31 Aug 2017 09:42:22 +0200
changeset 378072 089cbcabf67aee48a15d86b7db992f15883b92b4
parent 378071 9fad64b68cbcad16f98e00cb026366bd40cc0bc9
child 378073 3b1074717dac63fd1e2d2128f522c35ad9e59899
push id32421
push userarchaeopteryx@coole-files.de
push dateFri, 01 Sep 2017 08:31:26 +0000
treeherdermozilla-central@583e73fb8e3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs1394935
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 1394935: Assert that we don't call into NoteDirtyElement with extra bits on the restyle root's parent chain. r=bholley MozReview-Commit-ID: Kt5aZSRBvlE
dom/base/Element.cpp
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -4260,16 +4260,31 @@ BitIsPropagated(const Element* aElement,
     MOZ_ASSERT_IF(!curr,
                   parentNode == aElement->OwnerDoc() ||
                   parentNode == parentNode->OwnerDoc()->GetRootElement());
   }
   return true;
 }
 #endif
 
+static inline void
+AssertNoBitsPropagatedFrom(nsINode* aRoot) {
+#ifdef DEBUG
+  if (!aRoot || !aRoot->IsElement()) {
+    return;
+  }
+
+  auto* element = aRoot->GetFlattenedTreeParentElementForStyle();
+  while (element) {
+    MOZ_ASSERT(!element->HasAnyOfFlags(Element::kAllServoDescendantBits));
+    element = element->GetFlattenedTreeParentElementForStyle();
+  }
+#endif
+}
+
 // Sets |aBits| on aElement and all of its flattened-tree ancestors up to and
 // including aStopAt or the root element (whichever is encountered first).
 static inline Element*
 PropagateBits(Element* aElement, uint32_t aBits, nsINode* aStopAt)
 {
   Element* curr = aElement;
   while (curr && !curr->HasAllFlags(aBits)) {
     curr->SetFlags(aBits);
@@ -4342,20 +4357,25 @@ NoteDirtyElement(Element* aElement, uint
     }
   }
 
   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.
-  nsINode* existingRoot = doc->GetServoRestyleRoot();
-  uint32_t existingBits = existingRoot ? doc->GetServoRestyleRootDirtyBits() : 0;
   if (!existingRoot || existingRoot == aElement) {
     doc->SetServoRestyleRoot(aElement, existingBits | aBit);
     return;
   }
 
   // There is an existing restyle root - walk up the tree from our element,
   // propagating bits as wel go.
   const bool reachedDocRoot = !parent || !PropagateBits(parent, aBit, existingRoot);