diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp index 8e45b5a77181..3098ba9d7cd8 100644 --- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -219,8 +219,9 @@ nsContainerFrame::RemoveFrame(nsIAtom* aListName, generateReflowCommand = PR_FALSE; } #endif - nsContainerFrame* parent = static_cast(aOldFrame->GetParent()); while (aOldFrame) { + nsContainerFrame* parent = + static_cast(aOldFrame->GetParent()); // When the parent is an inline frame we have a simple task - just // remove the frame from its parents list and generate a reflow // command. @@ -237,15 +238,17 @@ nsContainerFrame::RemoveFrame(nsIAtom* aListName, aOldFrame->Destroy(); } } else { - // This recursive call takes care of all continuations after aOldFrame, - // so we don't need to loop anymore. - parent->RemoveFrame(nsnull, aOldFrame); - break; + // We don't want to simply make a recursive call here because with + // thousands of continuations it would exhaust the stack. Instead, + // unhook aOldFrame from the continuation chain, destroy it, and + // continue the loop. + if (oldFrameNextContinuation) { + oldFrameNextContinuation->SetPrevContinuation(nsnull); + aOldFrame->SetNextContinuation(nsnull); + } + parent->RemoveFrame(aListName, aOldFrame); } aOldFrame = oldFrameNextContinuation; - if (aOldFrame) { - parent = static_cast(aOldFrame->GetParent()); - } } if (generateReflowCommand) {