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
--- 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);