mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-06 07:17:30 +09:00
moebius#138: Optimize operations on root of deeply-nested frame tree
https://github.com/MoonchildProductions/moebius/pull/138
This commit is contained in:
parent
02f3024a9c
commit
85692a1198
23 changed files with 651 additions and 40 deletions
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue