diff options
author | win7-7 <win7-7@users.noreply.github.com> | 2019-07-08 19:19:56 +0300 |
---|---|---|
committer | win7-7 <win7-7@users.noreply.github.com> | 2019-07-08 19:19:56 +0300 |
commit | 570cad82795beeb1eb7011c09be295afa11373ce (patch) | |
tree | 3e189787caf3eeff12b34137a0055c185f0519b2 /layout/generic | |
parent | 4b4d3a9cca870681e1187794f951808c10274dd3 (diff) | |
download | UXP-570cad82795beeb1eb7011c09be295afa11373ce.tar UXP-570cad82795beeb1eb7011c09be295afa11373ce.tar.gz UXP-570cad82795beeb1eb7011c09be295afa11373ce.tar.lz UXP-570cad82795beeb1eb7011c09be295afa11373ce.tar.xz UXP-570cad82795beeb1eb7011c09be295afa11373ce.zip |
Iterate the frame property list once to collect which child list properties we have
Look into optimizing out the hashtable lookups from nsContainerFrame
Diffstat (limited to 'layout/generic')
-rw-r--r-- | layout/generic/nsContainerFrame.cpp | 89 |
1 files changed, 53 insertions, 36 deletions
diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp index 2933ac4cf..abf687c9b 100644 --- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -219,24 +219,49 @@ nsContainerFrame::DestroyFrom(nsIFrame* aDestructRoot) // Destroy frames on the principal child list. mFrames.DestroyFramesFrom(aDestructRoot); + + if (MOZ_UNLIKELY(!mProperties.IsEmpty())) { + using T = mozilla::FrameProperties::UntypedDescriptor; + bool hasO = false, hasOC = false, hasEOC = false, hasBackdrop = false; + mProperties.ForEach([&] (const T& aProp, void*) { + if (aProp == OverflowProperty()) { + hasO = true; + } else if (aProp == OverflowContainersProperty()) { + hasOC = true; + } else if (aProp == ExcessOverflowContainersProperty()) { + hasEOC = true; + } else if (aProp == BackdropProperty()) { + hasBackdrop = true; + } + return true; + }); + // Destroy frames on the auxiliary frame lists and delete the lists. nsPresContext* pc = PresContext(); nsIPresShell* shell = pc->PresShell(); - SafelyDestroyFrameListProp(aDestructRoot, shell, OverflowProperty()); + if (hasO) { + SafelyDestroyFrameListProp(aDestructRoot, shell, OverflowProperty()); + } - MOZ_ASSERT(IsFrameOfType(nsIFrame::eCanContainOverflowContainers) || - !(GetProperty(nsContainerFrame::OverflowContainersProperty()) || - GetProperty(nsContainerFrame::ExcessOverflowContainersProperty())), - "this type of frame should't have overflow containers"); - SafelyDestroyFrameListProp(aDestructRoot, shell, - OverflowContainersProperty()); - SafelyDestroyFrameListProp(aDestructRoot, shell, - ExcessOverflowContainersProperty()); + MOZ_ASSERT(IsFrameOfType(eCanContainOverflowContainers) || + !(hasOC || hasEOC), + "this type of frame shouldn't have overflow containers"); + if (hasOC) { + SafelyDestroyFrameListProp(aDestructRoot, shell, + OverflowContainersProperty()); + } + if (hasEOC) { + SafelyDestroyFrameListProp(aDestructRoot, shell, + ExcessOverflowContainersProperty()); + } MOZ_ASSERT(!GetProperty(BackdropProperty()) || StyleDisplay()->mTopLayer != NS_STYLE_TOP_LAYER_NONE, "only top layer frame may have backdrop"); - SafelyDestroyFrameListProp(aDestructRoot, shell, BackdropProperty()); + if (hasBackdrop) { + SafelyDestroyFrameListProp(aDestructRoot, shell, BackdropProperty()); + } +} nsSplittableFrame::DestroyFrom(aDestructRoot); } @@ -274,36 +299,28 @@ nsContainerFrame::GetChildList(ChildListID aListID) const } } -static void -AppendIfNonempty(const nsIFrame* aFrame, - nsContainerFrame::FrameListPropertyDescriptor aProperty, - nsTArray<nsIFrame::ChildList>* aLists, - nsIFrame::ChildListID aListID) -{ - if (nsFrameList* list = aFrame->GetProperty(aProperty)) { - list->AppendIfNonempty(aLists, aListID); - } -} - void nsContainerFrame::GetChildLists(nsTArray<ChildList>* aLists) const { mFrames.AppendIfNonempty(aLists, kPrincipalList); - ::AppendIfNonempty(this, OverflowProperty(), - aLists, kOverflowList); - if (IsFrameOfType(nsIFrame::eCanContainOverflowContainers)) { - ::AppendIfNonempty(this, OverflowContainersProperty(), - aLists, kOverflowContainersList); - ::AppendIfNonempty(this, ExcessOverflowContainersProperty(), - aLists, kExcessOverflowContainersList); - } - // Bypass BackdropProperty hashtable lookup for any in-flow frames - // since frames in the top layer (only which can have backdrop) are - // definitely out-of-flow. - if (GetStateBits() & NS_FRAME_OUT_OF_FLOW) { - ::AppendIfNonempty(this, BackdropProperty(), - aLists, kBackdropList); - } + using T = mozilla::FrameProperties::UntypedDescriptor; + mProperties.ForEach([this, aLists] (const T& aProp, void* aValue) { + typedef const nsFrameList* L; + if (aProp == OverflowProperty()) { + L(aValue)->AppendIfNonempty(aLists, kOverflowList); + } else if (aProp == OverflowContainersProperty()) { + MOZ_ASSERT(IsFrameOfType(nsIFrame::eCanContainOverflowContainers), + "found unexpected OverflowContainersProperty"); + L(aValue)->AppendIfNonempty(aLists, kOverflowContainersList); + } else if (aProp == ExcessOverflowContainersProperty()) { + MOZ_ASSERT(IsFrameOfType(nsIFrame::eCanContainOverflowContainers), + "found unexpected ExcessOverflowContainersProperty"); + L(aValue)->AppendIfNonempty(aLists, kExcessOverflowContainersList); + } else if (aProp == BackdropProperty()) { + L(aValue)->AppendIfNonempty(aLists, kBackdropList); + } + return true; + }); nsSplittableFrame::GetChildLists(aLists); } |