Bug 1364813 - Remove IsFrameOfType, use non-virtual checks. r=jwatt

Extend the per-frame-class bit we have to devirtualize IsLeaf to also
devirtualize IsFrameOfType. That is, move this data to FrameClasses.py.

This was done by going through all the frame classes, trying to preserve
behavior.

The only quirky thing is that I had to add two more trivial frame
classes, `nsAudioFrame` for audio elements, and
`nsFloatingFirstLetterFrame`. That's because these frame classes were
returning different answers at runtime, but they do this only on
conditions that trigger frame reconstruction (floating, and being an
audio element, respectively).

Differential Revision: https://phabricator.services.mozilla.com/D194703
This commit is contained in:
Emilio Cobos Álvarez
2023-11-26 22:17:28 +00:00
parent 19bccb6e33
commit c27730d3df
105 changed files with 543 additions and 882 deletions

View File

@@ -129,6 +129,7 @@ using namespace mozilla::dom;
nsIFrame* NS_NewHTMLCanvasFrame(PresShell* aPresShell, ComputedStyle* aStyle);
nsIFrame* NS_NewHTMLVideoFrame(PresShell* aPresShell, ComputedStyle* aStyle);
nsIFrame* NS_NewHTMLAudioFrame(PresShell* aPresShell, ComputedStyle* aStyle);
nsContainerFrame* NS_NewSVGOuterSVGFrame(PresShell* aPresShell,
ComputedStyle* aStyle);
@@ -265,7 +266,7 @@ static void AssertAnonymousFlexOrGridItemParent(const nsIFrame* aChild,
* needs to terminate it).
*/
static bool IsInlineFrame(const nsIFrame* aFrame) {
return aFrame->IsFrameOfType(nsIFrame::eLineParticipant);
return aFrame->IsLineParticipant();
}
/**
@@ -284,7 +285,7 @@ static inline bool IsDisplayContents(const nsIContent* aContent) {
* frame being used for SVG text.
*/
static bool IsFrameForSVG(const nsIFrame* aFrame) {
return aFrame->IsFrameOfType(nsIFrame::eSVG) || aFrame->IsInSVGTextSubtree();
return aFrame->IsSVGFrame() || aFrame->IsInSVGTextSubtree();
}
static bool IsLastContinuationForColumnContent(const nsIFrame* aFrame) {
@@ -300,8 +301,7 @@ static bool IsLastContinuationForColumnContent(const nsIFrame* aFrame) {
* lower-level descendents inside them, of course).
*/
static bool ShouldSuppressFloatingOfDescendants(nsIFrame* aFrame) {
return aFrame->IsFlexOrGridContainer() ||
aFrame->IsFrameOfType(nsIFrame::eMathML);
return aFrame->IsFlexOrGridContainer() || aFrame->IsMathMLFrame();
}
// Return true if column-span descendants should be suppressed under aFrame's
@@ -2329,7 +2329,7 @@ static inline bool NeedFrameFor(const nsFrameConstructorState& aState,
// white-space, where we know we'll be dropping them all anyway, and involve
// an extra walk down the frame construction item list.
auto excludesIgnorableWhitespace = [](nsIFrame* aParentFrame) {
return aParentFrame->IsFrameOfType(nsIFrame::eMathML);
return aParentFrame->IsMathMLFrame();
};
if (!aParentFrame || !excludesIgnorableWhitespace(aParentFrame) ||
aParentFrame->IsGeneratedContentFrame() || !aChildContent->IsText()) {
@@ -2585,9 +2585,9 @@ nsIFrame* nsCSSFrameConstructor::ConstructDocElementFrame(
// Still need to process the child content
nsFrameList childList;
NS_ASSERTION(!contentFrame->IsBlockFrameOrSubclass() &&
!contentFrame->IsFrameOfType(nsIFrame::eSVG),
"Only XUL frames should reach here");
NS_ASSERTION(
!contentFrame->IsBlockFrameOrSubclass() && !contentFrame->IsSVGFrame(),
"Only XUL frames should reach here");
nsFrameConstructorSaveState floatSaveState;
state.MaybePushFloatContainingBlock(contentFrame, floatSaveState);
@@ -3515,7 +3515,7 @@ nsCSSFrameConstructor::FindHTMLData(const Element& aElement,
PseudoStyleType::buttonContent}},
SIMPLE_TAG_CHAIN(canvas, nsCSSFrameConstructor::FindCanvasData),
SIMPLE_TAG_CREATE(video, NS_NewHTMLVideoFrame),
SIMPLE_TAG_CREATE(audio, NS_NewHTMLVideoFrame),
SIMPLE_TAG_CREATE(audio, NS_NewHTMLAudioFrame),
SIMPLE_TAG_CREATE(progress, NS_NewProgressFrame),
SIMPLE_TAG_CREATE(meter, NS_NewMeterFrame),
SIMPLE_TAG_CHAIN(details, nsCSSFrameConstructor::FindDetailsData),
@@ -3972,7 +3972,7 @@ void nsCSSFrameConstructor::ConstructFrameFromItemInternal(
}
}
NS_ASSERTION(newFrame->IsFrameOfType(nsIFrame::eLineParticipant) ==
NS_ASSERTION(newFrame->IsLineParticipant() ==
((bits & FCDATA_IS_LINE_PARTICIPANT) != 0),
"Incorrectly set FCDATA_IS_LINE_PARTICIPANT bits");
@@ -5578,7 +5578,7 @@ nsContainerFrame* nsCSSFrameConstructor::GetAbsoluteContainingBlock(
// Starting with aFrame, look for a frame that is absolutely positioned or
// relatively positioned (and transformed, if aType is FIXED)
for (nsIFrame* frame = aFrame; frame; frame = frame->GetParent()) {
if (frame->IsFrameOfType(nsIFrame::eMathML)) {
if (frame->IsMathMLFrame()) {
// If it's mathml, bail out -- no absolute positioning out from inside
// mathml frames. Note that we don't make this part of the loop
// condition because of the stuff at the end of this method...
@@ -7472,7 +7472,7 @@ bool nsCSSFrameConstructor::ContentRemoved(nsIContent* aChild,
nsIFrame* possibleMathMLAncestor = parentType == LayoutFrameType::Block
? parentFrame->GetParent()
: parentFrame;
if (possibleMathMLAncestor->IsFrameOfType(nsIFrame::eMathML)) {
if (possibleMathMLAncestor->IsMathMLFrame()) {
LAYOUT_PHASE_TEMP_EXIT();
RecreateFramesForContent(parentFrame->GetContent(), InsertionKind::Async);
LAYOUT_PHASE_TEMP_REENTER();
@@ -8435,14 +8435,13 @@ void nsCSSFrameConstructor::UpdateTableCellSpans(nsIContent* aContent) {
static nsIContent* GetTopmostMathMLElement(nsIContent* aMathMLContent) {
MOZ_ASSERT(aMathMLContent->IsMathMLElement());
MOZ_ASSERT(aMathMLContent->GetPrimaryFrame());
MOZ_ASSERT(
aMathMLContent->GetPrimaryFrame()->IsFrameOfType(nsIFrame::eMathML));
MOZ_ASSERT(aMathMLContent->GetPrimaryFrame()->IsMathMLFrame());
nsIContent* root = aMathMLContent;
for (nsIContent* parent = aMathMLContent->GetFlattenedTreeParent(); parent;
parent = parent->GetFlattenedTreeParent()) {
nsIFrame* frame = parent->GetPrimaryFrame();
if (!frame || !frame->IsFrameOfType(nsIFrame::eMathML)) {
if (!frame || !frame->IsMathMLFrame()) {
break;
}
root = parent;
@@ -8512,7 +8511,7 @@ void nsCSSFrameConstructor::RecreateFramesForContent(
}
nsIFrame* frame = aContent->GetPrimaryFrame();
if (frame && frame->IsFrameOfType(nsIFrame::eMathML)) {
if (frame && frame->IsMathMLFrame()) {
// Reframe the topmost MathML element to prevent exponential blowup
// (see bug 397518).
aContent = GetTopmostMathMLElement(aContent);
@@ -9334,7 +9333,7 @@ static bool FrameWantsToBeInAnonymousItem(const nsIFrame* aContainerFrame,
// Any line-participant frames (e.g. text) definitely want to be wrapped in
// an anonymous flex/grid item.
if (aFrame->IsFrameOfType(nsIFrame::eLineParticipant)) {
if (aFrame->IsLineParticipant()) {
return true;
}
@@ -10033,7 +10032,7 @@ nsFirstLetterFrame* nsCSSFrameConstructor::CreateFloatingLetterFrame(
MOZ_ASSERT(aParentStyle);
nsFirstLetterFrame* letterFrame =
NS_NewFirstLetterFrame(mPresShell, aComputedStyle);
NS_NewFloatingFirstLetterFrame(mPresShell, aComputedStyle);
// We don't want to use a text content for a non-text frame (because we want
// its primary frame to be a text frame).
nsIContent* letterContent = aParentFrame->GetContent();
@@ -11280,7 +11279,7 @@ bool nsCSSFrameConstructor::WipeInsertionParent(nsContainerFrame* aFrame) {
// FIXME(emilio): This looks terribly inefficient if you insert elements deep
// in a MathML subtree.
if (aFrame->IsFrameOfType(nsIFrame::eMathML)) {
if (aFrame->IsMathMLFrame()) {
TRACE("MathML");
RecreateFramesForContent(aFrame->GetContent(), InsertionKind::Async);
return true;