Attach FrameProperties to each frame instead of using a shared hashtable

Dispense the shared hashtable and instead attach the frame property list directly to nsIFrame.
This commit is contained in:
win7-7 2019-06-26 01:51:45 +03:00 committed by Roy Tam
commit 922e819d1c
62 changed files with 738 additions and 945 deletions

View file

@ -78,7 +78,7 @@ nsContainerFrame::SetInitialChildList(ChildListID aListID,
"Only top layer frames should have backdrop");
MOZ_ASSERT(GetStateBits() & NS_FRAME_OUT_OF_FLOW,
"Top layer frames should be out-of-flow");
MOZ_ASSERT(!Properties().Get(BackdropProperty()),
MOZ_ASSERT(!GetProperty(BackdropProperty()),
"We shouldn't have setup backdrop frame list before");
#ifdef DEBUG
{
@ -93,7 +93,7 @@ nsContainerFrame::SetInitialChildList(ChildListID aListID,
#endif
nsFrameList* list =
new (PresContext()->PresShell()) nsFrameList(aChildList);
Properties().Set(BackdropProperty(), list);
SetProperty(BackdropProperty(), list);
} else {
MOZ_ASSERT_UNREACHABLE("Unexpected child list");
}
@ -189,18 +189,17 @@ nsContainerFrame::DestroyAbsoluteFrames(nsIFrame* aDestructRoot)
void
nsContainerFrame::SafelyDestroyFrameListProp(nsIFrame* aDestructRoot,
nsIPresShell* aPresShell,
FramePropertyTable* aPropTable,
FrameListPropertyDescriptor aProp)
{
// Note that the last frame can be removed through another route and thus
// delete the property -- that's why we fetch the property again before
// removing each frame rather than fetching it once and iterating the list.
while (nsFrameList* frameList = aPropTable->Get(this, aProp)) {
while (nsFrameList* frameList = GetProperty(aProp)) {
nsIFrame* frame = frameList->RemoveFirstChild();
if (MOZ_LIKELY(frame)) {
frame->DestroyFrom(aDestructRoot);
} else {
aPropTable->Remove(this, aProp);
RemoveProperty(aProp);
frameList->Delete(aPresShell);
return;
}
@ -223,22 +222,21 @@ nsContainerFrame::DestroyFrom(nsIFrame* aDestructRoot)
// Destroy frames on the auxiliary frame lists and delete the lists.
nsPresContext* pc = PresContext();
nsIPresShell* shell = pc->PresShell();
FramePropertyTable* props = pc->PropertyTable();
SafelyDestroyFrameListProp(aDestructRoot, shell, props, OverflowProperty());
SafelyDestroyFrameListProp(aDestructRoot, shell, OverflowProperty());
MOZ_ASSERT(IsFrameOfType(nsIFrame::eCanContainOverflowContainers) ||
!(props->Get(this, nsContainerFrame::OverflowContainersProperty()) ||
props->Get(this, nsContainerFrame::ExcessOverflowContainersProperty())),
!(GetProperty(nsContainerFrame::OverflowContainersProperty()) ||
GetProperty(nsContainerFrame::ExcessOverflowContainersProperty())),
"this type of frame should't have overflow containers");
SafelyDestroyFrameListProp(aDestructRoot, shell, props,
SafelyDestroyFrameListProp(aDestructRoot, shell,
OverflowContainersProperty());
SafelyDestroyFrameListProp(aDestructRoot, shell, props,
SafelyDestroyFrameListProp(aDestructRoot, shell,
ExcessOverflowContainersProperty());
MOZ_ASSERT(!props->Get(this, BackdropProperty()) ||
MOZ_ASSERT(!GetProperty(BackdropProperty()) ||
StyleDisplay()->mTopLayer != NS_STYLE_TOP_LAYER_NONE,
"only top layer frame may have backdrop");
SafelyDestroyFrameListProp(aDestructRoot, shell, props, BackdropProperty());
SafelyDestroyFrameListProp(aDestructRoot, shell, BackdropProperty());
nsSplittableFrame::DestroyFrom(aDestructRoot);
}
@ -278,12 +276,11 @@ nsContainerFrame::GetChildList(ChildListID aListID) const
static void
AppendIfNonempty(const nsIFrame* aFrame,
FramePropertyTable* aPropTable,
nsContainerFrame::FrameListPropertyDescriptor aProperty,
nsTArray<nsIFrame::ChildList>* aLists,
nsIFrame::ChildListID aListID)
{
if (nsFrameList* list = aPropTable->Get(aFrame, aProperty)) {
if (nsFrameList* list = aFrame->GetProperty(aProperty)) {
list->AppendIfNonempty(aLists, aListID);
}
}
@ -292,20 +289,19 @@ void
nsContainerFrame::GetChildLists(nsTArray<ChildList>* aLists) const
{
mFrames.AppendIfNonempty(aLists, kPrincipalList);
FramePropertyTable* propTable = PresContext()->PropertyTable();
::AppendIfNonempty(this, propTable, OverflowProperty(),
::AppendIfNonempty(this, OverflowProperty(),
aLists, kOverflowList);
if (IsFrameOfType(nsIFrame::eCanContainOverflowContainers)) {
::AppendIfNonempty(this, propTable, OverflowContainersProperty(),
::AppendIfNonempty(this, OverflowContainersProperty(),
aLists, kOverflowContainersList);
::AppendIfNonempty(this, propTable, ExcessOverflowContainersProperty(),
::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, propTable, BackdropProperty(),
::AppendIfNonempty(this, BackdropProperty(),
aLists, kBackdropList);
}
nsSplittableFrame::GetChildLists(aLists);
@ -1335,15 +1331,15 @@ nsContainerFrame::DisplayOverflowContainers(nsDisplayListBuilder* aBuilder,
}
static bool
TryRemoveFrame(nsIFrame* aFrame, FramePropertyTable* aPropTable,
TryRemoveFrame(nsIFrame* aFrame,
nsContainerFrame::FrameListPropertyDescriptor aProp,
nsIFrame* aChildToRemove)
{
nsFrameList* list = aPropTable->Get(aFrame, aProp);
nsFrameList* list = aFrame->GetProperty(aProp);
if (list && list->StartRemoveFrame(aChildToRemove)) {
// aChildToRemove *may* have been removed from this list.
if (list->IsEmpty()) {
aPropTable->Remove(aFrame, aProp);
aFrame->RemoveProperty(aProp);
list->Delete(aFrame->PresContext()->PresShell());
}
return true;
@ -1356,13 +1352,12 @@ nsContainerFrame::MaybeStealOverflowContainerFrame(nsIFrame* aChild)
{
bool removed = false;
if (MOZ_UNLIKELY(aChild->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) {
FramePropertyTable* propTable = PresContext()->PropertyTable();
// Try removing from the overflow container list.
removed = ::TryRemoveFrame(this, propTable, OverflowContainersProperty(),
removed = ::TryRemoveFrame(this, OverflowContainersProperty(),
aChild);
if (!removed) {
// It might be in the excess overflow container list.
removed = ::TryRemoveFrame(this, propTable,
removed = ::TryRemoveFrame(this,
ExcessOverflowContainersProperty(),
aChild);
}
@ -1377,10 +1372,9 @@ nsContainerFrame::StealFrame(nsIFrame* aChild)
if (!mFrames.ContainsFrame(aChild)) {
nsFrameList* list = GetOverflowFrames();
if (!list || !list->ContainsFrame(aChild)) {
FramePropertyTable* propTable = PresContext()->PropertyTable();
list = propTable->Get(this, OverflowContainersProperty());
list = GetProperty(OverflowContainersProperty());
if (!list || !list->ContainsFrame(aChild)) {
list = propTable->Get(this, ExcessOverflowContainersProperty());
list = GetProperty(ExcessOverflowContainersProperty());
MOZ_ASSERT(list && list->ContainsFrame(aChild), "aChild isn't our child"
" or on a frame list not supported by StealFrame");
}
@ -1536,20 +1530,20 @@ nsContainerFrame::SetOverflowFrames(const nsFrameList& aOverflowFrames)
nsPresContext* pc = PresContext();
nsFrameList* newList = new (pc->PresShell()) nsFrameList(aOverflowFrames);
pc->PropertyTable()->Set(this, OverflowProperty(), newList);
SetProperty(OverflowProperty(), newList);
}
nsFrameList*
nsContainerFrame::GetPropTableFrames(
FrameListPropertyDescriptor aProperty) const
{
return PresContext()->PropertyTable()->Get(this, aProperty);
return GetProperty(aProperty);
}
nsFrameList*
nsContainerFrame::RemovePropTableFrames(FrameListPropertyDescriptor aProperty)
{
return PresContext()->PropertyTable()->Remove(this, aProperty);
return RemoveProperty(aProperty);
}
void
@ -1563,7 +1557,7 @@ nsContainerFrame::SetPropTableFrames(nsFrameList* aFrameList,
IsFrameOfType(nsIFrame::eCanContainOverflowContainers),
"this type of frame can't have overflow containers");
MOZ_ASSERT(!GetPropTableFrames(aProperty));
PresContext()->PropertyTable()->Set(this, aProperty, aFrameList);
SetProperty(aProperty, aFrameList);
}
/**
@ -2253,13 +2247,11 @@ nsOverflowContinuationTracker::EndFinish(nsIFrame* aChild)
return;
}
// Forget mOverflowContList if it was deleted.
nsPresContext* pc = aChild->PresContext();
FramePropertyTable* propTable = pc->PropertyTable();
nsFrameList* eoc = propTable->Get(
mParent, nsContainerFrame::ExcessOverflowContainersProperty());
nsFrameList* eoc = mParent->GetProperty
(nsContainerFrame::ExcessOverflowContainersProperty());
if (eoc != mOverflowContList) {
nsFrameList* oc = static_cast<nsFrameList*>(propTable->Get(mParent,
nsContainerFrame::OverflowContainersProperty()));
nsFrameList* oc = static_cast<nsFrameList*>(mParent->GetProperty
(nsContainerFrame::OverflowContainersProperty()));
if (oc != mOverflowContList) {
// mOverflowContList was deleted
mPrevOverflowCont = nullptr;