Closed Bug 1657024 Opened 5 years ago Closed 5 years ago

Simplify "get-next-page" logic in nsPageFrame.cpp

Categories

(Core :: Printing: Output, task)

task

Tracking

()

RESOLVED FIXED
81 Branch
Tracking Status
firefox81 --- fixed

People

(Reporter: dholbert, Assigned: dholbert)

References

Details

Attachments

(1 file)

nsPageFrame.cpp has a function called "GetNextPage", which essentially just takes a nsPageContentFrame and returns the next continuation.

Right now it does this by doing unnecessarily-complex pointer-chasing (it returns the nsPageContentFrame's parent's next-sibling's first-child; i.e. it's "cousin", looked up by following each direct relationship).

We can simplify this to just use GetNextContinuation, since the series of nsPageContentFrames are all connected in a next-continuation relationship anyway. This will help avoid the need for further complexity in bug 1652278 (where we'll be removing the guarantee that nsPageFrame instances are siblings of each other).

One minor drawback of switching to GetNextContinuation() here is that it's a virtual function-call.

However:

  • it saves us a lot of pointer-chasing (the "some ancestor's next-sibling's descendant" lookup)
  • If we static_cast to the concrete frame type, then the compiler will probably devirtualize it and be able to inline it.[1]

[1] (Justification: here's a simplified scenario on godbolt Compiler Explorer, compiled under clang: https://godbolt.org/z/45xEj5
The "static_cast" sample in that snippet (the last one) gets inlined successfully, when you look at its assembly. The assembly doesn't seem to be doing dynamic dispatch.

Before this patch, we used a clumsy "GetNextPage" helper-function (which,
despite its name, actually gets the next page content frame). It worked by
pointer-chasing to get the parent's next-sibling's first-child. This is
unnecessary; we can just directly query for the nsPageContentFrame's
next-continuation, since these frames are linked in a straightforward
continuation chain.

Note that GetNextContinuation() is a virtual function-call, but it may still be
faster than the pointer-chasing that we were doing with the GetNextPage()
API. Moreover, can help the compiler devirtualize it by static_cast'ing to the
concrete type before calling the method. This is safe since nsPageFrame always
contains a single nsPageContentFrame (which we already validate -- at least the
frame-type-part -- via assertions).

Pushed by dholbert@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/37030207d352 Simplify code that's effectively walking the nsPageContentFrame continuation chain. r=TYLin
Status: ASSIGNED → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
Target Milestone: --- → 81 Branch
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: