Bug 1334075: Part 2, mark some methods in nsTextFrame as final to avoid virtual calls. r=xidorn

MozReview-Commit-ID: FBhjFSNviBL
This commit is contained in:
Emilio Cobos Álvarez 2017-01-26 14:23:04 +01:00
Родитель ad0b4ef8b2
Коммит 1c87f99407
2 изменённых файлов: 72 добавлений и 74 удалений

Просмотреть файл

@ -587,7 +587,7 @@ ClearAllTextRunReferences(nsTextFrame* aFrame, gfxTextRun* aTextRun,
} else {
do {
NS_ASSERTION(aFrame->GetType() == nsGkAtoms::textFrame, "Bad frame");
aFrame = static_cast<nsTextFrame*>(aFrame->GetNextContinuation());
aFrame = aFrame->GetNextContinuation();
} while (aFrame && aFrame != aStartContinuation);
}
bool found = aStartContinuation == aFrame;
@ -596,7 +596,7 @@ ClearAllTextRunReferences(nsTextFrame* aFrame, gfxTextRun* aTextRun,
if (!aFrame->RemoveTextRun(aTextRun)) {
break;
}
aFrame = static_cast<nsTextFrame*>(aFrame->GetNextContinuation());
aFrame = aFrame->GetNextContinuation();
}
NS_POSTCONDITION(!found || aStartContinuation, "how did we find null?");
return found;
@ -714,7 +714,7 @@ GlyphObserver::NotifyGlyphsChanged()
}
int32_t nsTextFrame::GetContentEnd() const {
nsTextFrame* next = static_cast<nsTextFrame*>(GetNextContinuation());
nsTextFrame* next = GetNextContinuation();
return next ? next->GetContentOffset() : mContent->GetText()->GetLength();
}
@ -749,7 +749,7 @@ int32_t nsTextFrame::GetInFlowContentLength() {
return flowLength->mEndFlowOffset - mContentOffset;
}
nsTextFrame* nextBidi = static_cast<nsTextFrame*>(LastInFlow()->GetNextContinuation());
nsTextFrame* nextBidi = LastInFlow()->GetNextContinuation();
int32_t endFlow = nextBidi ? nextBidi->GetContentOffset() : mContent->TextLength();
if (!flowLength) {
@ -1678,7 +1678,7 @@ void BuildTextRunsScanner::AccumulateRunInfo(nsTextFrame* aFrame)
NS_ASSERTION(mappedFlow->mStartFrame == aFrame ||
mappedFlow->GetContentEnd() == aFrame->GetContentOffset(),
"Overlapping or discontiguous frames => BAD");
mappedFlow->mEndFrame = static_cast<nsTextFrame*>(aFrame->GetNextContinuation());
mappedFlow->mEndFrame = aFrame->GetNextContinuation();
if (mCurrentFramesAllSameTextRun != aFrame->GetTextRun(mWhichTextRun)) {
mCurrentFramesAllSameTextRun = nullptr;
}
@ -2304,7 +2304,7 @@ BuildTextRunsScanner::BuildTextRunForFrames(void* aTextBuffer)
nsStyleContext* sc = nullptr;
RefPtr<nsTransformedCharStyle> charStyle;
for (f = mappedFlow->mStartFrame; f != mappedFlow->mEndFrame;
f = static_cast<nsTextFrame*>(f->GetNextContinuation())) {
f = f->GetNextContinuation()) {
uint32_t offset = iter.GetSkippedOffset();
iter.AdvanceOriginal(f->GetContentLength());
uint32_t end = iter.GetSkippedOffset();
@ -2738,8 +2738,7 @@ BuildTextRunsScanner::AssignTextRun(gfxTextRun* aTextRun, float aInflation)
nsTextFrame* startFrame = mappedFlow->mStartFrame;
nsTextFrame* endFrame = mappedFlow->mEndFrame;
nsTextFrame* f;
for (f = startFrame; f != endFrame;
f = static_cast<nsTextFrame*>(f->GetNextContinuation())) {
for (f = startFrame; f != endFrame; f = f->GetNextContinuation()) {
#ifdef DEBUG_roc
if (f->GetTextRun(mWhichTextRun)) {
gfxTextRun* textRun = f->GetTextRun(mWhichTextRun);
@ -4264,54 +4263,57 @@ nsTextFrame::DestroyFrom(nsIFrame* aDestructRoot)
nsFrame::DestroyFrom(aDestructRoot);
}
class nsContinuingTextFrame : public nsTextFrame {
class nsContinuingTextFrame final : public nsTextFrame
{
public:
NS_DECL_FRAMEARENA_HELPERS
friend nsIFrame* NS_NewContinuingTextFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
virtual void Init(nsIContent* aContent,
nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) override;
void Init(nsIContent* aContent,
nsContainerFrame* aParent,
nsIFrame* aPrevInFlow) override;
virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
void DestroyFrom(nsIFrame* aDestructRoot) override;
virtual nsIFrame* GetPrevContinuation() const override {
nsTextFrame* GetPrevContinuation() const override
{
return mPrevContinuation;
}
virtual void SetPrevContinuation(nsIFrame* aPrevContinuation) override {
void SetPrevContinuation(nsIFrame* aPrevContinuation) override
{
NS_ASSERTION (!aPrevContinuation || GetType() == aPrevContinuation->GetType(),
"setting a prev continuation with incorrect type!");
NS_ASSERTION (!nsSplittableFrame::IsInPrevContinuationChain(aPrevContinuation, this),
"creating a loop in continuation chain!");
mPrevContinuation = aPrevContinuation;
mPrevContinuation = static_cast<nsTextFrame*>(aPrevContinuation);
RemoveStateBits(NS_FRAME_IS_FLUID_CONTINUATION);
}
virtual nsIFrame* GetPrevInFlowVirtual() const override {
return GetPrevInFlow();
}
nsIFrame* GetPrevInFlow() const {
nsIFrame* GetPrevInFlowVirtual() const override { return GetPrevInFlow(); }
nsTextFrame* GetPrevInFlow() const
{
return (GetStateBits() & NS_FRAME_IS_FLUID_CONTINUATION) ? mPrevContinuation : nullptr;
}
virtual void SetPrevInFlow(nsIFrame* aPrevInFlow) override {
void SetPrevInFlow(nsIFrame* aPrevInFlow) override
{
NS_ASSERTION (!aPrevInFlow || GetType() == aPrevInFlow->GetType(),
"setting a prev in flow with incorrect type!");
NS_ASSERTION (!nsSplittableFrame::IsInPrevContinuationChain(aPrevInFlow, this),
"creating a loop in continuation chain!");
mPrevContinuation = aPrevInFlow;
mPrevContinuation = static_cast<nsTextFrame*>(aPrevInFlow);
AddStateBits(NS_FRAME_IS_FLUID_CONTINUATION);
}
virtual nsIFrame* FirstInFlow() const override;
virtual nsIFrame* FirstContinuation() const override;
nsIFrame* FirstInFlow() const override;
nsIFrame* FirstContinuation() const override;
virtual void AddInlineMinISize(nsRenderingContext *aRenderingContext,
InlineMinISizeData *aData) override;
virtual void AddInlinePrefISize(nsRenderingContext *aRenderingContext,
InlinePrefISizeData *aData) override;
void AddInlineMinISize(nsRenderingContext* aRenderingContext,
InlineMinISizeData* aData) override;
void AddInlinePrefISize(nsRenderingContext* aRenderingContext,
InlinePrefISizeData* aData) override;
protected:
explicit nsContinuingTextFrame(nsStyleContext* aContext) : nsTextFrame(aContext) {}
nsIFrame* mPrevContinuation;
nsTextFrame* mPrevContinuation;
};
void
@ -4323,12 +4325,11 @@ nsContinuingTextFrame::Init(nsIContent* aContent,
// NOTE: bypassing nsTextFrame::Init!!!
nsFrame::Init(aContent, aParent, aPrevInFlow);
nsTextFrame* nextContinuation =
static_cast<nsTextFrame*>(aPrevInFlow->GetNextContinuation());
nsTextFrame* prev = static_cast<nsTextFrame*>(aPrevInFlow);
nsTextFrame* nextContinuation = prev->GetNextContinuation();
// Hook the frame into the flow
SetPrevInFlow(aPrevInFlow);
aPrevInFlow->SetNextInFlow(this);
nsTextFrame* prev = static_cast<nsTextFrame*>(aPrevInFlow);
mContentOffset = prev->GetContentOffset() + prev->GetContentLengthHint();
NS_ASSERTION(mContentOffset < int32_t(aContent->GetText()->GetLength()),
"Creating ContinuingTextFrame, but there is no more content");
@ -4369,7 +4370,7 @@ nsContinuingTextFrame::Init(nsIContent* aContent,
"between continuations");
#endif
nextContinuation->mContentOffset = mContentOffset;
nextContinuation = static_cast<nsTextFrame*>(nextContinuation->GetNextContinuation());
nextContinuation = nextContinuation->GetNextContinuation();
}
}
mState |= NS_FRAME_IS_BIDI;
@ -4397,9 +4398,7 @@ nsContinuingTextFrame::DestroyFrom(nsIFrame* aDestructRoot)
// Clear the previous continuation's text run also, so that it can rebuild
// the text run to include our text.
if (mPrevContinuation) {
nsTextFrame *prevContinuationText =
static_cast<nsTextFrame*>(mPrevContinuation);
prevContinuationText->ClearTextRuns();
mPrevContinuation->ClearTextRuns();
}
}
nsSplittableFrame::RemoveFromFlow(this);
@ -4535,24 +4534,23 @@ nsTextFrame::GetCursor(const nsPoint& aPoint,
}
}
nsIFrame*
nsTextFrame*
nsTextFrame::LastInFlow() const
{
nsTextFrame* lastInFlow = const_cast<nsTextFrame*>(this);
while (lastInFlow->GetNextInFlow()) {
lastInFlow = static_cast<nsTextFrame*>(lastInFlow->GetNextInFlow());
lastInFlow = lastInFlow->GetNextInFlow();
}
MOZ_ASSERT(lastInFlow, "post-condition failed");
return lastInFlow;
}
nsIFrame*
nsTextFrame*
nsTextFrame::LastContinuation() const
{
nsTextFrame* lastContinuation = const_cast<nsTextFrame*>(this);
while (lastContinuation->mNextContinuation) {
lastContinuation =
static_cast<nsTextFrame*>(lastContinuation->mNextContinuation);
lastContinuation = lastContinuation->mNextContinuation;
}
MOZ_ASSERT(lastContinuation, "post-condition failed");
return lastContinuation;
@ -4681,7 +4679,7 @@ nsTextFrame::CharacterDataChanged(CharacterDataChangeInfo* aInfo)
nsTextFrame* next;
nsTextFrame* textFrame = this;
while (true) {
next = static_cast<nsTextFrame*>(textFrame->GetNextContinuation());
next = textFrame->GetNextContinuation();
if (!next || next->GetContentOffset() > int32_t(aInfo->mChangeStart))
break;
textFrame = next;
@ -4721,7 +4719,7 @@ nsTextFrame::CharacterDataChanged(CharacterDataChangeInfo* aInfo)
textFrame->mContentOffset = endOfChangedText;
}
textFrame = static_cast<nsTextFrame*>(textFrame->GetNextContinuation());
textFrame = textFrame->GetNextContinuation();
} while (textFrame && textFrame->GetContentOffset() < int32_t(aInfo->mChangeEnd));
// This is how much the length of the string changed by --- i.e.,
@ -4737,7 +4735,7 @@ nsTextFrame::CharacterDataChanged(CharacterDataChangeInfo* aInfo)
// XXX we could rescue some text runs by adjusting their user data
// to reflect the change in DOM offsets
textFrame->ClearTextRuns();
textFrame = static_cast<nsTextFrame*>(textFrame->GetNextContinuation());
textFrame = textFrame->GetNextContinuation();
}
}
@ -7464,7 +7462,7 @@ nsTextFrame::SetSelectedRange(uint32_t aStart, uint32_t aEnd, bool aSelected,
nsTextFrame* f = this;
while (f && f->GetContentEnd() <= int32_t(aStart)) {
f = static_cast<nsTextFrame*>(f->GetNextContinuation());
f = f->GetNextContinuation();
}
nsPresContext* presContext = PresContext();
@ -7487,7 +7485,7 @@ nsTextFrame::SetSelectedRange(uint32_t aStart, uint32_t aEnd, bool aSelected,
// Selection might change anything. Invalidate the overflow area.
f->InvalidateFrame();
f = static_cast<nsTextFrame*>(f->GetNextContinuation());
f = f->GetNextContinuation();
}
}
@ -7700,7 +7698,7 @@ nsTextFrame::GetChildFrameContainingOffset(int32_t aContentOffset,
if ((aContentOffset >= offset) &&
(aHint || aContentOffset != offset)) {
while (true) {
nsTextFrame* next = static_cast<nsTextFrame*>(f->GetNextContinuation());
nsTextFrame* next = f->GetNextContinuation();
if (!next || aContentOffset < next->GetContentOffset())
break;
if (aContentOffset == next->GetContentOffset()) {
@ -7716,7 +7714,7 @@ nsTextFrame::GetChildFrameContainingOffset(int32_t aContentOffset,
}
} else {
while (true) {
nsTextFrame* prev = static_cast<nsTextFrame*>(f->GetPrevContinuation());
nsTextFrame* prev = f->GetPrevContinuation();
if (!prev || aContentOffset > f->GetContentOffset())
break;
if (aContentOffset == f->GetContentOffset()) {
@ -8093,8 +8091,7 @@ nsTextFrame::CheckVisibility(nsPresContext* aContext, int32_t aStartIndex,
// Text in the range is visible if there is at least one character in the range
// that is not skipped and is mapped by this frame (which is the primary frame)
// or one of its continuations.
for (nsTextFrame* f = this; f;
f = static_cast<nsTextFrame*>(GetNextContinuation())) {
for (nsTextFrame* f = this; f; f = f->GetNextContinuation()) {
int32_t dummyOffset = 0;
if (f->PeekOffsetNoAmount(true, &dummyOffset) == FOUND) {
*aRetval = true;
@ -8460,7 +8457,7 @@ nsTextFrame::AddInlineMinISize(nsRenderingContext *aRenderingContext,
const gfxTextRun* lastTextRun = nullptr;
// nsContinuingTextFrame does nothing for AddInlineMinISize; all text frames
// in the flow are handled right here.
for (f = this; f; f = static_cast<nsTextFrame*>(f->GetNextContinuation())) {
for (f = this; f; f = f->GetNextContinuation()) {
// f->GetTextRun(nsTextFrame::eNotInflated) could be null if we
// haven't set up textruns yet for f. Except in OOM situations,
// lastTextRun will only be null for the first text frame.
@ -8611,7 +8608,7 @@ nsTextFrame::AddInlinePrefISize(nsRenderingContext *aRenderingContext,
const gfxTextRun* lastTextRun = nullptr;
// nsContinuingTextFrame does nothing for AddInlineMinISize; all text frames
// in the flow are handled right here.
for (f = this; f; f = static_cast<nsTextFrame*>(f->GetNextContinuation())) {
for (f = this; f; f = f->GetNextContinuation()) {
// f->GetTextRun(nsTextFrame::eNotInflated) could be null if we
// haven't set up textruns yet for f. Except in OOM situations,
// lastTextRun will only be null for the first text frame.
@ -8770,11 +8767,11 @@ RemoveEmptyInFlows(nsTextFrame* aFrame, nsTextFrame* aFirstToNotRemove)
aFrame->GetPrevInFlow() != nullptr,
"aFrame should have a fluid prev continuation");
nsIFrame* prevContinuation = aFrame->GetPrevContinuation();
nsIFrame* lastRemoved = aFirstToNotRemove->GetPrevContinuation();
nsTextFrame* prevContinuation = aFrame->GetPrevContinuation();
nsTextFrame* lastRemoved = aFirstToNotRemove->GetPrevContinuation();
for (nsTextFrame* f = aFrame; f != aFirstToNotRemove;
f = static_cast<nsTextFrame*>(f->GetNextContinuation())) {
f = f->GetNextContinuation()) {
// f is going to be destroyed soon, after it is unlinked from the
// continuation chain. If its textrun is going to be destroyed we need to
// do it now, before we unlink the frames to remove from the flow,
@ -8813,7 +8810,7 @@ nsTextFrame::SetLength(int32_t aLength, nsLineLayout* aLineLayout,
{
mContentLengthHint = aLength;
int32_t end = GetContentOffset() + aLength;
nsTextFrame* f = static_cast<nsTextFrame*>(GetNextInFlow());
nsTextFrame* f = GetNextInFlow();
if (!f)
return;
@ -8876,7 +8873,7 @@ nsTextFrame::SetLength(int32_t aLength, nsLineLayout* aLineLayout,
ClearTextRuns();
f->ClearTextRuns();
}
nsTextFrame* next = static_cast<nsTextFrame*>(f->GetNextInFlow());
nsTextFrame* next = f->GetNextInFlow();
// Note: the "f->GetNextSibling() == next" check below is to restrict
// this optimization to the case where they are on the same child list.
// Otherwise we might remove the only child of a nsFirstLetterFrame
@ -8913,14 +8910,14 @@ nsTextFrame::SetLength(int32_t aLength, nsLineLayout* aLineLayout,
int32_t iterations = 0;
while (f && iterations < 10) {
f->GetContentLength(); // Assert if negative length
f = static_cast<nsTextFrame*>(f->GetNextContinuation());
f = f->GetNextContinuation();
++iterations;
}
f = this;
iterations = 0;
while (f && iterations < 10) {
f->GetContentLength(); // Assert if negative length
f = static_cast<nsTextFrame*>(f->GetPrevContinuation());
f = f->GetPrevContinuation();
++iterations;
}
#endif
@ -9785,7 +9782,7 @@ nsTextFrame::GetRenderedText(uint32_t aStartOffset,
Maybe<nsBlockFrame::AutoLineCursorSetup> autoLineCursor;
for (textFrame = this; textFrame;
textFrame = static_cast<nsTextFrame*>(textFrame->GetNextContinuation())) {
textFrame = textFrame->GetNextContinuation()) {
if (textFrame->GetStateBits() & NS_FRAME_IS_DIRTY) {
// We don't trust dirty frames, especially when computing rendered text.
break;
@ -10052,7 +10049,7 @@ nsTextFrame::AdjustOffsetsForBidi(int32_t aStart, int32_t aEnd)
*/
ClearTextRuns();
nsTextFrame* prev = static_cast<nsTextFrame*>(GetPrevContinuation());
nsTextFrame* prev = GetPrevContinuation();
if (prev) {
// the bidi resolver can be very evil when columns/pages are involved. Don't
// let it violate our invariants.

Просмотреть файл

@ -82,10 +82,11 @@ public:
nsresult GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor) override;
nsresult CharacterDataChanged(CharacterDataChangeInfo* aInfo) override;
nsresult CharacterDataChanged(CharacterDataChangeInfo* aInfo) final;
nsIFrame* GetNextContinuation() const override { return mNextContinuation; }
void SetNextContinuation(nsIFrame* aNextContinuation) override
nsTextFrame* GetPrevContinuation() const override { return nullptr; }
nsTextFrame* GetNextContinuation() const final { return mNextContinuation; }
void SetNextContinuation(nsIFrame* aNextContinuation) final
{
NS_ASSERTION(!aNextContinuation ||
GetType() == aNextContinuation->GetType(),
@ -93,12 +94,12 @@ public:
NS_ASSERTION(
!nsSplittableFrame::IsInNextContinuationChain(aNextContinuation, this),
"creating a loop in continuation chain!");
mNextContinuation = aNextContinuation;
mNextContinuation = static_cast<nsTextFrame*>(aNextContinuation);
if (aNextContinuation)
aNextContinuation->RemoveStateBits(NS_FRAME_IS_FLUID_CONTINUATION);
}
nsIFrame* GetNextInFlowVirtual() const override { return GetNextInFlow(); }
nsIFrame* GetNextInFlow() const
nsTextFrame* GetNextInFlow() const
{
return mNextContinuation &&
(mNextContinuation->GetStateBits() &
@ -106,21 +107,21 @@ public:
? mNextContinuation
: nullptr;
}
void SetNextInFlow(nsIFrame* aNextInFlow) override
void SetNextInFlow(nsIFrame* aNextInFlow) final
{
NS_ASSERTION(!aNextInFlow || GetType() == aNextInFlow->GetType(),
"setting a next in flow with incorrect type!");
NS_ASSERTION(
!nsSplittableFrame::IsInNextContinuationChain(aNextInFlow, this),
"creating a loop in continuation chain!");
mNextContinuation = aNextInFlow;
mNextContinuation = static_cast<nsTextFrame*>(aNextInFlow);
if (aNextInFlow)
aNextInFlow->AddStateBits(NS_FRAME_IS_FLUID_CONTINUATION);
}
nsIFrame* LastInFlow() const override;
nsIFrame* LastContinuation() const override;
nsTextFrame* LastInFlow() const final;
nsTextFrame* LastContinuation() const final;
nsSplittableType GetSplittableType() const override
nsSplittableType GetSplittableType() const final
{
return NS_FRAME_SPLITTABLE;
}
@ -130,9 +131,9 @@ public:
*
* @see nsGkAtoms::textFrame
*/
nsIAtom* GetType() const override;
nsIAtom* GetType() const final;
bool IsFrameOfType(uint32_t aFlags) const override
bool IsFrameOfType(uint32_t aFlags) const final
{
// Set the frame state bit for text frames to mark them as replaced.
// XXX kipp: temporary
@ -654,7 +655,7 @@ protected:
virtual ~nsTextFrame();
RefPtr<gfxTextRun> mTextRun;
nsIFrame* mNextContinuation;
nsTextFrame* mNextContinuation;
// The key invariant here is that mContentOffset never decreases along
// a next-continuation chain. And of course mContentOffset is always <= the
// the text node's content length, and the mContentOffset for the first frame