зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1398119 - Rearrange NoteDirtyElement for faster bailouts on the same restyle root. r=emilio
This eliminates ~90% of the time spent in NoteDirtyElement on this testcase. MozReview-Commit-ID: Lm5hf7QRiOK
This commit is contained in:
Родитель
1ce8eb2531
Коммит
f458d41b8e
|
@ -4592,6 +4592,15 @@ NoteDirtyElement(Element* aElement, uint32_t aBits)
|
|||
MOZ_ASSERT(aElement->IsInComposedDoc());
|
||||
MOZ_ASSERT(aElement->IsStyledByServo());
|
||||
|
||||
// Check the existing root early on, since it may allow us to short-circuit
|
||||
// before examining the parent chain.
|
||||
nsIDocument* doc = aElement->GetComposedDoc();
|
||||
nsINode* existingRoot = doc->GetServoRestyleRoot();
|
||||
if (existingRoot == aElement) {
|
||||
doc->SetServoRestyleRootDirtyBits(doc->GetServoRestyleRootDirtyBits() | aBits);
|
||||
return;
|
||||
}
|
||||
|
||||
nsINode* parent = aElement->GetFlattenedTreeParentNodeForStyle();
|
||||
if (!parent) {
|
||||
// The element is not in the flattened tree, bail.
|
||||
|
@ -4630,24 +4639,20 @@ NoteDirtyElement(Element* aElement, uint32_t aBits)
|
|||
}
|
||||
}
|
||||
|
||||
nsIDocument* doc = aElement->GetComposedDoc();
|
||||
if (nsIPresShell* shell = doc->GetShell()) {
|
||||
shell->EnsureStyleFlush();
|
||||
}
|
||||
|
||||
MOZ_ASSERT(parent->IsElement() || parent == doc);
|
||||
|
||||
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 (!existingRoot) {
|
||||
doc->SetServoRestyleRoot(aElement, aBits);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4657,6 +4662,7 @@ NoteDirtyElement(Element* aElement, uint32_t aBits)
|
|||
!parent->IsElement() ||
|
||||
!PropagateBits(parent->AsElement(), aBits, existingRoot);
|
||||
|
||||
uint32_t existingBits = existingRoot ? doc->GetServoRestyleRootDirtyBits() : 0;
|
||||
if (!reachedDocRoot || existingRoot == doc) {
|
||||
// We're a descendant of the existing root. All that's left to do is to
|
||||
// make sure the bit we propagated is also registered on the root.
|
||||
|
|
|
@ -3149,6 +3149,7 @@ public:
|
|||
}
|
||||
|
||||
inline void SetServoRestyleRoot(nsINode* aRoot, uint32_t aDirtyBits);
|
||||
inline void SetServoRestyleRootDirtyBits(uint32_t aDirtyBits);
|
||||
|
||||
bool ShouldThrowOnDynamicMarkupInsertion()
|
||||
{
|
||||
|
|
|
@ -62,9 +62,6 @@ inline void
|
|||
nsIDocument::SetServoRestyleRoot(nsINode* aRoot, uint32_t aDirtyBits)
|
||||
{
|
||||
MOZ_ASSERT(aRoot);
|
||||
MOZ_ASSERT(aDirtyBits);
|
||||
MOZ_ASSERT((aDirtyBits & ~Element::kAllServoDescendantBits) == 0);
|
||||
MOZ_ASSERT((aDirtyBits & mServoRestyleRootDirtyBits) == mServoRestyleRootDirtyBits);
|
||||
|
||||
// NOTE(emilio): The !aRoot->IsElement() check allows us to handle cases where
|
||||
// we change the restyle root during unbinding of a subtree where the root is
|
||||
|
@ -90,7 +87,21 @@ nsIDocument::SetServoRestyleRoot(nsINode* aRoot, uint32_t aDirtyBits)
|
|||
nsContentUtils::ContentIsFlattenedTreeDescendantOfForStyle(mServoRestyleRoot, aRoot));
|
||||
MOZ_ASSERT(aRoot == aRoot->OwnerDocAsNode() || aRoot->IsElement());
|
||||
mServoRestyleRoot = aRoot;
|
||||
SetServoRestyleRootDirtyBits(aDirtyBits);
|
||||
}
|
||||
|
||||
// Note: we break this out of SetServoRestyleRoot so that callers can add
|
||||
// bits without doing a no-op assignment to the restyle root, which would
|
||||
// involve cycle-collected refcount traffic.
|
||||
inline void
|
||||
nsIDocument::SetServoRestyleRootDirtyBits(uint32_t aDirtyBits)
|
||||
{
|
||||
MOZ_ASSERT(aDirtyBits);
|
||||
MOZ_ASSERT((aDirtyBits & ~Element::kAllServoDescendantBits) == 0);
|
||||
MOZ_ASSERT((aDirtyBits & mServoRestyleRootDirtyBits) == mServoRestyleRootDirtyBits);
|
||||
MOZ_ASSERT(mServoRestyleRoot);
|
||||
mServoRestyleRootDirtyBits = aDirtyBits;
|
||||
}
|
||||
|
||||
|
||||
#endif // nsIDocumentInlines_h
|
||||
|
|
Загрузка…
Ссылка в новой задаче