Backed out 3 changesets (bug 1459937) for failing crashtest with Assertion failure: (IndexInFlow(aOldParent) < IndexInFlow(aNewParent)) on a CLOSED TREE

Backed out changeset 2cff5c67d000 (bug 1459937)
Backed out changeset fb3fba19e615 (bug 1459937)
Backed out changeset bd4bd8ac335c (bug 1459937)
This commit is contained in:
Andreea Pavel 2018-07-15 10:06:23 +03:00
Родитель 846c1a6377
Коммит 10d4df5aa9
8 изменённых файлов: 24 добавлений и 95 удалений

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

@ -134,11 +134,6 @@ enum class DrawStringFlags {
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(DrawStringFlags)
enum class ReparentingDirection {
Backwards,
Forwards
};
/**
* nsLayoutUtils is a namespace class used for various helper
* functions that are useful in multiple places in layout. The goal

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

@ -606,75 +606,25 @@ nsBlockFrame::IsFloatContainingBlock() const
}
static void
ReparentFrameInternal(nsIFrame* aFrame, nsContainerFrame* aOldParent,
nsContainerFrame* aNewParent, bool aMarkDirty)
ReparentFrame(nsIFrame* aFrame, nsContainerFrame* aOldParent,
nsContainerFrame* aNewParent)
{
NS_ASSERTION(aOldParent == aFrame->GetParent(),
"Parent not consistent with expectations");
aFrame->SetParent(aNewParent);
if (aMarkDirty) {
aFrame->AddStateBits(NS_FRAME_IS_DIRTY);
}
// When pushing and pulling frames we need to check for whether any
// views need to be reparented
nsContainerFrame::ReparentFrameView(aFrame, aOldParent, aNewParent);
}
static bool
ShouldMarkReparentedFramesDirty(
#ifdef DEBUG
nsContainerFrame* aOldParent,
#endif
nsIFrame* aNewParent,
ReparentingDirection aDirection)
{
#ifdef DEBUG
MOZ_ASSERT(aOldParent->FirstInFlow() == aNewParent->FirstInFlow(),
"Reparenting should be between continuations of the same frame");
if (aOldParent->FirstInFlow() == aNewParent->FirstInFlow()) {
auto IndexInFlow =
[](const nsIFrame* f) {
int i = 0; while ((f = f->GetPrevInFlow())) { ++i; } return i;
};
MOZ_ASSERT((IndexInFlow(aOldParent) < IndexInFlow(aNewParent)) ==
(aDirection == ReparentingDirection::Forwards),
"Parents not in expected order");
}
#endif
return (aDirection == ReparentingDirection::Backwards) &&
(aNewParent->GetStateBits() & NS_FRAME_IS_DIRTY);
}
// Because a frame with NS_FRAME_IS_DIRTY marks all of its children dirty at
// the start of its reflow, when we move a frame from a later frame backwards to
// an earlier frame, and the earlier frame has NS_FRAME_IS_DIRTY (though that
// should corresponded with the later frame having NS_FRAME_IS_DIRTY), we need
// to add NS_FRAME_IS_DIRTY to the reparented frame.
static void
ReparentFrame(nsIFrame* aFrame, nsContainerFrame* aOldParent,
nsContainerFrame* aNewParent, ReparentingDirection aDirection)
{
const bool markDirty = ShouldMarkReparentedFramesDirty(
#ifdef DEBUG
aOldParent,
#endif
aNewParent, aDirection);
ReparentFrameInternal(aFrame, aOldParent, aNewParent, markDirty);
}
static void
ReparentFrames(nsFrameList& aFrameList, nsContainerFrame* aOldParent,
nsContainerFrame* aNewParent, ReparentingDirection aDirection)
nsContainerFrame* aNewParent)
{
const bool markDirty = ShouldMarkReparentedFramesDirty(
#ifdef DEBUG
aOldParent,
#endif
aNewParent, aDirection);
for (nsFrameList::Enumerator e(aFrameList); !e.AtEnd(); e.Next()) {
ReparentFrameInternal(e.get(), aOldParent, aNewParent, markDirty);
ReparentFrame(e.get(), aOldParent, aNewParent);
}
}
@ -2174,16 +2124,14 @@ static bool LineHasClear(nsLineBox* aLine) {
*/
void
nsBlockFrame::ReparentFloats(nsIFrame* aFirstFrame, nsBlockFrame* aOldParent,
bool aReparentSiblings,
ReparentingDirection aDirection)
{
bool aReparentSiblings) {
nsFrameList list;
aOldParent->CollectFloats(aFirstFrame, list, aReparentSiblings);
if (list.NotEmpty()) {
for (nsIFrame* f : list) {
MOZ_ASSERT(!(f->GetStateBits() & NS_FRAME_IS_PUSHED_FLOAT),
"CollectFloats should've removed that bit");
ReparentFrame(f, aOldParent, this, aDirection);
ReparentFrame(f, aOldParent, this);
}
mFloats.AppendFrames(nullptr, list);
}
@ -2680,8 +2628,7 @@ nsBlockFrame::ReflowDirtyLines(BlockReflowInput& aState)
if (pulledLine == nextInFlow->GetLineCursor()) {
nextInFlow->ClearLineCursor();
}
ReparentFrames(pulledFrames, nextInFlow, this,
ReparentingDirection::Backwards);
ReparentFrames(pulledFrames, nextInFlow, this);
NS_ASSERTION(pulledFrames.LastChild() == pulledLine->LastChild(),
"Unexpected last frame");
@ -2697,8 +2644,7 @@ nsBlockFrame::ReflowDirtyLines(BlockReflowInput& aState)
aState.mPrevChild = mFrames.LastChild();
// Reparent floats whose placeholders are in the line.
ReparentFloats(pulledLine->mFirstChild, nextInFlow, true,
ReparentingDirection::Backwards);
ReparentFloats(pulledLine->mFirstChild, nextInFlow, true);
DumpLine(aState, pulledLine, deltaBCoord, 0);
#ifdef DEBUG
@ -2977,13 +2923,12 @@ nsBlockFrame::PullFrameFrom(nsLineBox* aLine,
// When pushing and pulling frames we need to check for whether any
// views need to be reparented.
ReparentFrame(frame, aFromContainer, this, ReparentingDirection::Backwards);
ReparentFrame(frame, aFromContainer, this);
mFrames.AppendFrame(nullptr, frame);
// The frame might have (or contain) floats that need to be brought
// over too. (pass 'false' since there are no siblings to check)
ReparentFloats(frame, aFromContainer, false,
ReparentingDirection::Backwards);
ReparentFloats(frame, aFromContainer, false);
} else {
MOZ_ASSERT(aLine == aFromLine.prev());
}
@ -3728,10 +3673,8 @@ nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState,
if (NS_FAILED(rv)) {
return;
}
if (parent != this) {
ReparentFrame(nextFrame, parent, this,
ReparentingDirection::Backwards);
}
if (parent != this)
ReparentFrame(nextFrame, parent, this);
mFrames.InsertFrame(nullptr, frame, nextFrame);
madeContinuation = true; // needs to be added to mLines
nextFrame->RemoveStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
@ -4390,7 +4333,7 @@ nsBlockFrame::SplitFloat(BlockReflowInput& aState,
DebugOnly<nsresult> rv = oldParent->StealFrame(nextInFlow);
NS_ASSERTION(NS_SUCCEEDED(rv), "StealFrame failed");
if (oldParent != this) {
ReparentFrame(nextInFlow, oldParent, this, ReparentingDirection::Backwards);
ReparentFrame(nextInFlow, oldParent, this);
}
if (!aFloatStatus.IsOverflowIncomplete()) {
nextInFlow->RemoveStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
@ -4910,8 +4853,7 @@ nsBlockFrame::DrainOverflowLines()
FrameLines* overflowLines = prevBlock->RemoveOverflowLines();
if (overflowLines) {
// Make all the frames on the overflow line list mine.
ReparentFrames(overflowLines->mFrames, prevBlock, this,
ReparentingDirection::Forwards);
ReparentFrames(overflowLines->mFrames, prevBlock, this);
// Make the overflow out-of-flow frames mine too.
nsAutoOOFFrameList oofs(prevBlock);
@ -4925,8 +4867,7 @@ nsBlockFrame::DrainOverflowLines()
nif->RemoveStateBits(NS_FRAME_IS_PUSHED_FLOAT);
}
}
ReparentFrames(oofs.mList, prevBlock, this,
ReparentingDirection::Forwards);
ReparentFrames(oofs.mList, prevBlock, this);
mFloats.InsertFrames(nullptr, nullptr, oofs.mList);
}

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

@ -540,7 +540,7 @@ public:
}
void ReparentFloats(nsIFrame* aFirstFrame, nsBlockFrame* aOldParent,
bool aReparentSiblings, ReparentingDirection aDirection);
bool aReparentSiblings);
virtual bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) override;

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

@ -1595,8 +1595,7 @@ nsContainerFrame::MoveInlineOverflowToChildList(nsIFrame* aLineContainer)
// container if the container has prev continuation.
if (aLineContainer->GetPrevContinuation()) {
ReparentFloatsForInlineChild(aLineContainer,
prevOverflowFrames->FirstChild(), true,
ReparentingDirection::Forwards);
prevOverflowFrames->FirstChild(), true);
}
// When pushing and pulling frames we need to check for whether
// any views need to be reparented.
@ -1749,8 +1748,7 @@ nsContainerFrame::PullNextInFlowChild(ContinuationTraversingState& aState)
/* static */ void
nsContainerFrame::ReparentFloatsForInlineChild(nsIFrame* aOurLineContainer,
nsIFrame* aFrame,
bool aReparentSiblings,
ReparentingDirection aDirection)
bool aReparentSiblings)
{
// XXXbz this would be better if it took a nsFrameList or a frame
// list slice....
@ -1771,7 +1769,7 @@ nsContainerFrame::ReparentFloatsForInlineChild(nsIFrame* aOurLineContainer,
NS_ASSERTION(ourBlock, "Not a block, but broke vertically?");
while (true) {
ourBlock->ReparentFloats(aFrame, frameBlock, false, aDirection);
ourBlock->ReparentFloats(aFrame, frameBlock, false);
if (!aReparentSiblings)
return;
@ -1786,8 +1784,7 @@ nsContainerFrame::ReparentFloatsForInlineChild(nsIFrame* aOurLineContainer,
// trust that the frames in the sibling chain all have the same parent,
// because lazy reparenting may be going on. If we find a different
// parent we need to redo our analysis.
ReparentFloatsForInlineChild(aOurLineContainer, next, aReparentSiblings,
aDirection);
ReparentFloatsForInlineChild(aOurLineContainer, next, aReparentSiblings);
return;
}
}

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

@ -674,8 +674,7 @@ protected:
*/
static void ReparentFloatsForInlineChild(nsIFrame* aOurBlock,
nsIFrame* aFrame,
bool aReparentSiblings,
ReparentingDirection aDirection);
bool aReparentSiblings);
// ==========================================================================
/*

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

@ -806,8 +806,7 @@ nsInlineFrame::PullOneFrame(nsPresContext* aPresContext,
// The blockChildren.ContainsFrame check performed by
// ReparentFloatsForInlineChild will be fast because frame's ancestor
// will be the first child of its containing block.
ReparentFloatsForInlineChild(irs.mLineContainer, frame, false,
ReparentingDirection::Backwards);
ReparentFloatsForInlineChild(irs.mLineContainer, frame, false);
}
nextInFlow->mFrames.RemoveFirstChild();
// nsFirstLineFrame::PullOneFrame calls ReparentComputedStyle.

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

@ -784,8 +784,7 @@ nsRubyBaseContainerFrame::PullOneColumn(nsLineLayout* aLineLayout,
MOZ_ASSERT(newFloatCB, "Must have a float containing block");
if (oldFloatCB != newFloatCB) {
for (nsIFrame* frame : aColumn) {
newFloatCB->ReparentFloats(frame, oldFloatCB, false,
ReparentingDirection::Backwards);
newFloatCB->ReparentFloats(frame, oldFloatCB, false);
}
}
}

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

@ -421,8 +421,7 @@ nsRubyFrame::PullOneSegment(const nsLineLayout* aLineLayout,
if (nsBlockFrame* newFloatCB =
nsLayoutUtils::GetAsBlock(aLineLayout->LineContainerFrame())) {
if (oldFloatCB && oldFloatCB != newFloatCB) {
newFloatCB->ReparentFloats(baseFrame, oldFloatCB, true,
ReparentingDirection::Backwards);
newFloatCB->ReparentFloats(baseFrame, oldFloatCB, true);
}
}