moebius#138: Optimize operations on root of deeply-nested frame tree

https://github.com/MoonchildProductions/moebius/pull/138
This commit is contained in:
janekptacijarabaci 2018-04-24 21:39:13 +02:00 • committed by Roy Tam
commit 85692a1198
23 changed files with 651 additions and 40 deletions

View file

@ -1844,6 +1844,24 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
SetParentIsContent(false);
}
#ifdef DEBUG
// If we can get access to the PresContext, then we sanity-check that
// we're not leaving behind a pointer to ourselves as the PresContext's
// cached provider of the viewport's scrollbar styles.
if (document) {
nsIPresShell* presShell = document->GetShell();
if (presShell) {
nsPresContext* presContext = presShell->GetPresContext();
if (presContext) {
MOZ_ASSERT(this !=
presContext->GetViewportScrollbarStylesOverrideNode(),
"Leaving behind a raw pointer to this node (as having "
"propagated scrollbar styles) - that's dangerous...");
}
}
}
#endif
// Ensure that CSS transitions don't continue on an element at a
// different place in the tree (even if reinserted before next
// animation refresh).

View file

@ -2054,10 +2054,17 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
mFirstChild = content->GetNextSibling();
}
mChildren.RemoveChildAt(i);
if (content == mCachedRootElement) {
// Immediately clear mCachedRootElement, now that it's been removed
// from mChildren, so that GetRootElement() will stop returning this
// now-stale value.
mCachedRootElement = nullptr;
}
nsNodeUtils::ContentRemoved(this, content, i, previousSibling);
content->UnbindFromTree();
}
mCachedRootElement = nullptr;
MOZ_ASSERT(!mCachedRootElement,
"After removing all children, there should be no root elem");
}
mInUnlinkOrDeletion = oldVal;
@ -3913,8 +3920,18 @@ nsDocument::RemoveChildAt(uint32_t aIndex, bool aNotify)
DestroyElementMaps();
}
doRemoveChildAt(aIndex, aNotify, oldKid, mChildren);
// Preemptively clear mCachedRootElement, since we may be about to remove it
// from our child list, and we don't want to return this maybe-obsolete value
// from any GetRootElement() calls that happen inside of doRemoveChildAt().
// (NOTE: for this to be useful, doRemoveChildAt() must NOT trigger any
// GetRootElement() calls until after it's removed the child from mChildren.
// Any call before that point would restore this soon-to-be-obsolete cached
// answer, and our clearing here would be fruitless.)
mCachedRootElement = nullptr;
doRemoveChildAt(aIndex, aNotify, oldKid, mChildren);
MOZ_ASSERT(mCachedRootElement != oldKid,
"Stale pointer in mCachedRootElement, after we tried to clear it "
"(maybe somebody called GetRootElement() too early?)");
}
void

View file

@ -1907,6 +1907,10 @@ void
nsINode::doRemoveChildAt(uint32_t aIndex, bool aNotify,
nsIContent* aKid, nsAttrAndChildArray& aChildArray)
{
// NOTE: This function must not trigger any calls to
// nsIDocument::GetRootElement() calls until *after* it has removed aKid from
// aChildArray. Any calls before then could potentially restore a stale
// value for our cached root element, per note in nsDocument::RemoveChildAt().
NS_PRECONDITION(aKid && aKid->GetParentNode() == this &&
aKid == GetChildAt(aIndex) &&
IndexOf(aKid) == (int32_t)aIndex, "Bogus aKid");