Bug 1804772 - Make nsIFrame::GetStartPageValue/nsIFrame::GetEndPageValue constant complexity by copying over the PageValuesProperty value when creating frame continuations. r=dholbert

This was causing layout/generic/crashtests/1683126.html to timeout with named
pages enabled.

It is possible for a frame's PageValues struct to have both the start and end
values be set to null as further children are added. In that case, we can
avoid doing an extra allocation for each of that frame's continuations, as a
small optimization.

Differential Revision: https://phabricator.services.mozilla.com/D164266
This commit is contained in:
Emily McDonough
2022-12-09 21:01:53 +00:00
parent ba5b217186
commit 5960cb8918
2 changed files with 19 additions and 4 deletions

View File

@@ -8095,6 +8095,23 @@ nsIFrame* nsCSSFrameConstructor::CreateContinuingFrame(
// aFrame cannot be a dynamic reflow root because it has a continuation now.
aFrame->RemoveStateBits(NS_FRAME_DYNAMIC_REFLOW_ROOT);
// XXXalaskanemily: This avoids linear-time FirstContinuation lookups during
// paginated reflow, but there are a lot of smarter ways to manage this. We
// might also want to share the struct (refcount or some guarantee the struct
// will remain valid during reflow).
if (nsIFrame::PageValues* pageValues =
aFrame->GetProperty(nsIFrame::PageValuesProperty())) {
// It is possible that both values of a PageValues struct can be
// overwritten with null. If that's the case, then as a minor optimization
// we don't need to create a copy of the struct since this property being
// missing is equivalent to having null start/end values.
if (pageValues->mStartPageValue || pageValues->mEndPageValue) {
nsIFrame::PageValues* const newPageValues =
new nsIFrame::PageValues(*pageValues);
newFrame->SetProperty(nsIFrame::PageValuesProperty(), newPageValues);
}
}
MOZ_ASSERT(!newFrame->GetNextSibling(), "unexpected sibling");
return newFrame;
}