Chromium Code Reviews| Index: Source/core/rendering/RenderBlockFlow.cpp | 
| diff --git a/Source/core/rendering/RenderBlockFlow.cpp b/Source/core/rendering/RenderBlockFlow.cpp | 
| index d67b5e39511905f6578f1a1c47e99d281444d520..e19de90fd0e4219a169366984ed35cd83458d6e8 100644 | 
| --- a/Source/core/rendering/RenderBlockFlow.cpp | 
| +++ b/Source/core/rendering/RenderBlockFlow.cpp | 
| @@ -282,40 +282,64 @@ void RenderBlockFlow::layoutBlock(bool relayoutChildren) | 
| SubtreeLayoutScope layoutScope(this); | 
| + m_layoutScope = &layoutScope; | 
| + m_pageLogicalHeight = 0; | 
| + | 
| + preLayoutBlock(relayoutChildren, true); | 
| + | 
| // Multiple passes might be required for column and pagination based layout | 
| // In the case of the old column code the number of passes will only be two | 
| // however, in the newer column code the number of passes could equal the | 
| // number of columns. | 
| - bool done = false; | 
| - LayoutUnit pageLogicalHeight = 0; | 
| - while (!done) | 
| - done = layoutBlockFlow(relayoutChildren, pageLogicalHeight, layoutScope); | 
| + bool done = postLayoutBlock(); | 
| + while (!done) { | 
| + preLayoutBlock(relayoutChildren, true); | 
| + done = postLayoutBlock(); | 
| + } | 
| + m_layoutScope = 0; | 
| } | 
| -inline bool RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit &pageLogicalHeight, SubtreeLayoutScope& layoutScope) | 
| +void RenderBlockFlow::preLayoutBlock(bool relayoutChildren, bool traverseChildren) | 
| { | 
| - LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); | 
| + m_relayoutChildren = relayoutChildren; | 
| + preLayoutBlockFlow(traverseChildren); | 
| +} | 
| + | 
| +bool RenderBlockFlow::postLayoutBlock() | 
| +{ | 
| + return postLayoutBlockFlow(); | 
| +} | 
| + | 
| +void RenderBlockFlow::preLayoutBlockFlow(bool traverseChildren) | 
| +{ | 
| + m_checkForRepaint = checkForRepaintDuringLayout(); | 
| + m_oldBounds = LayoutRect(); | 
| + m_oldOutlineBox = LayoutRect(); | 
| + if (m_checkForRepaint) { | 
| + m_oldBounds = clippedOverflowRectForRepaint(containerForRepaint()); | 
| + m_oldOutlineBox = outlineBoundsForRepaint(containerForRepaint(), 0); | 
| + } | 
| if (updateLogicalWidthAndColumnWidth()) | 
| - relayoutChildren = true; | 
| + m_relayoutChildren = true; | 
| rebuildFloatsFromIntruding(); | 
| bool pageLogicalHeightChanged = false; | 
| - bool hasSpecifiedPageLogicalHeight = false; | 
| - checkForPaginationLogicalHeightChange(pageLogicalHeight, pageLogicalHeightChanged, hasSpecifiedPageLogicalHeight); | 
| + m_hasSpecifiedPageLogicalHeight = false; | 
| + checkForPaginationLogicalHeightChange(m_pageLogicalHeight, pageLogicalHeightChanged, m_hasSpecifiedPageLogicalHeight); | 
| RenderView* renderView = view(); | 
| - LayoutStateMaintainer statePusher(renderView, this, locationOffset(), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode(), pageLogicalHeight, pageLogicalHeightChanged, columnInfo()); | 
| + m_statePusher = new LayoutStateMaintainer(renderView, this, locationOffset(), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode(), m_pageLogicalHeight, pageLogicalHeightChanged, columnInfo()); | 
| // Regions changing widths can force us to relayout our children. | 
| RenderFlowThread* flowThread = flowThreadContainingBlock(); | 
| if (logicalWidthChangedInRegions(flowThread)) | 
| - relayoutChildren = true; | 
| + m_relayoutChildren = true; | 
| if (updateRegionsAndShapesLogicalSize(flowThread)) | 
| - relayoutChildren = true; | 
| - if (!relayoutChildren && isRenderNamedFlowFragmentContainer()) | 
| - relayoutChildren = true; | 
| + m_relayoutChildren = true; | 
| + if (!m_relayoutChildren && isRenderNamedFlowFragmentContainer()) | 
| + m_relayoutChildren = true; | 
| // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track | 
| // our current maximal positive and negative margins. These values are used when we | 
| @@ -336,12 +360,12 @@ inline bool RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit & | 
| LayoutUnit beforeEdge = borderBefore() + paddingBefore(); | 
| LayoutUnit afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeight(); | 
| - LayoutUnit previousHeight = logicalHeight(); | 
| + m_heightBeforeLayout = logicalHeight(); | 
| setLogicalHeight(beforeEdge); | 
| m_repaintLogicalTop = 0; | 
| m_repaintLogicalBottom = 0; | 
| - LayoutUnit maxFloatLogicalBottom = 0; | 
| + m_maxFloatLogicalBottom = 0; | 
| if (!firstChild() && !isAnonymousBlock()) | 
| setChildrenInline(true); | 
| @@ -350,15 +374,42 @@ inline bool RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit & | 
| textAutosizer->beginLayout(this); | 
| if (childrenInline()) | 
| - layoutInlineChildren(relayoutChildren, m_repaintLogicalTop, m_repaintLogicalBottom, afterEdge); | 
| - else | 
| - layoutBlockChildren(relayoutChildren, maxFloatLogicalBottom, layoutScope, beforeEdge, afterEdge); | 
| + layoutInlineChildren(m_relayoutChildren, m_repaintLogicalTop, m_repaintLogicalBottom, afterEdge); | 
| + else { | 
| + dirtyForLayoutFromPercentageHeightDescendants(*m_layoutScope); | 
| + | 
| + // Lay out our hypothetical grid line as though it occurs at the top of the block. | 
| + if (view()->layoutState()->lineGrid() == this) | 
| + layoutLineGridBox(); | 
| + | 
| + layoutBlockChildren(beforeEdge, afterEdge, traverseChildren); | 
| + } | 
| +} | 
| + | 
| +bool RenderBlockFlow::postLayoutBlockFlow() | 
| +{ | 
| + if (!m_statePusher) // simple layout | 
| + return true; | 
| if (frameView()->partialLayout().isStopping()) { | 
| - statePusher.pop(); | 
| + m_statePusher->pop(); | 
| + delete m_statePusher; | 
| + m_statePusher = 0; | 
| return true; | 
| } | 
| + LayoutRepainter repainter(*this, m_checkForRepaint, m_oldBounds, m_oldOutlineBox); | 
| + LayoutUnit beforeEdge = borderBefore() + paddingBefore(); | 
| + LayoutUnit afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeight(); | 
| + | 
| + if (!childrenInline()) { | 
| + // Now do the handling of the bottom of the block, adding in our bottom border/padding and | 
| + // determining the correct collapsed bottom margin information. | 
| + handleAfterSideOfBlock(m_lastNormalFlowChild, beforeEdge, afterEdge, *m_marginInfo); | 
| + delete m_marginInfo; | 
| + m_marginInfo = 0; | 
| + } | 
| + | 
| // Expand our intrinsic height to encompass floats. | 
| if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && createsBlockFormattingContext()) | 
| setLogicalHeight(lowestFloatLogicalBottom() + afterEdge); | 
| @@ -366,7 +417,9 @@ inline bool RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit & | 
| if (isRenderMultiColumnBlock()) { | 
| if (toRenderMultiColumnBlock(this)->shouldRelayoutMultiColumnBlock()) { | 
| setChildNeedsLayout(MarkOnlyThis); | 
| - statePusher.pop(); | 
| + m_statePusher->pop(); | 
| + delete m_statePusher; | 
| + m_statePusher = 0; | 
| return false; | 
| } | 
| } else if (hasColumns()) { | 
| @@ -378,17 +431,21 @@ inline bool RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit & | 
| LayoutUnit layoutOverflowLogicalBottom = (isHorizontalWritingMode() ? layoutOverflowRect().maxY() : layoutOverflowRect().maxX()) - borderBefore() - paddingBefore(); | 
| m_overflow = savedOverflow.release(); | 
| - if (!hasSpecifiedPageLogicalHeight && shouldRelayoutForPagination(pageLogicalHeight, layoutOverflowLogicalBottom)) { | 
| - statePusher.pop(); | 
| + if (!m_hasSpecifiedPageLogicalHeight && shouldRelayoutForPagination(m_pageLogicalHeight, layoutOverflowLogicalBottom)) { | 
| + m_statePusher->pop(); | 
| + delete m_statePusher; | 
| + m_statePusher = 0; | 
| setEverHadLayout(true); | 
| return false; | 
| } | 
| - setColumnCountAndHeight(ceilf((float)layoutOverflowLogicalBottom / pageLogicalHeight), pageLogicalHeight); | 
| + setColumnCountAndHeight(ceilf((float)layoutOverflowLogicalBottom / m_pageLogicalHeight), m_pageLogicalHeight); | 
| } | 
| if (shouldBreakAtLineToAvoidWidow()) { | 
| - statePusher.pop(); | 
| + m_statePusher->pop(); | 
| + delete m_statePusher; | 
| + m_statePusher = 0; | 
| setEverHadLayout(true); | 
| return false; | 
| } | 
| @@ -405,7 +462,7 @@ inline bool RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit & | 
| updateLogicalHeight(); | 
| LayoutUnit newHeight = logicalHeight(); | 
| if (oldHeight != newHeight) { | 
| - if (oldHeight > newHeight && maxFloatLogicalBottom > newHeight && !childrenInline()) { | 
| + if (oldHeight > newHeight && m_maxFloatLogicalBottom > newHeight && !childrenInline()) { | 
| // One of our children's floats may have become an overhanging float for us. We need to look for it. | 
| for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { | 
| if (child->isRenderBlockFlow() && !child->isFloatingOrOutOfFlowPositioned()) { | 
| @@ -417,26 +474,29 @@ inline bool RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit & | 
| } | 
| } | 
| - bool heightChanged = (previousHeight != newHeight); | 
| + bool heightChanged = (m_heightBeforeLayout != newHeight); | 
| if (heightChanged) | 
| - relayoutChildren = true; | 
| + m_relayoutChildren = true; | 
| - layoutPositionedObjects(relayoutChildren || isRoot()); | 
| + layoutPositionedObjects(m_relayoutChildren || isRoot()); | 
| - updateRegionsAndShapesAfterChildLayout(flowThread, heightChanged); | 
| + updateRegionsAndShapesAfterChildLayout(flowThreadContainingBlock(), heightChanged); | 
| // Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway). | 
| computeOverflow(oldClientAfterEdge); | 
| - statePusher.pop(); | 
| + m_statePusher->pop(); | 
| fitBorderToLinesIfNeeded(); | 
| - if (frameView()->partialLayout().isStopping()) | 
| + if (frameView()->partialLayout().isStopping()) { | 
| + delete m_statePusher; | 
| + m_statePusher = 0; | 
| return true; | 
| + } | 
| - if (renderView->layoutState()->m_pageLogicalHeight) | 
| - setPageLogicalOffset(renderView->layoutState()->pageLogicalOffset(this, logicalTop())); | 
| + if (view()->layoutState()->m_pageLogicalHeight) | 
| + setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(this, logicalTop())); | 
| updateLayerTransform(); | 
| @@ -453,17 +513,36 @@ inline bool RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit & | 
| repaintOverflow(); | 
| } | 
| + FastTextAutosizer* textAutosizer = document().fastTextAutosizer(); | 
| if (textAutosizer) | 
| textAutosizer->endLayout(this); | 
| clearNeedsLayout(); | 
| + delete m_statePusher; | 
| + m_statePusher = 0; | 
| 
 
esprehn
2014/02/15 00:35:43
This should be an OwnPtr you just clear.
 
 | 
| return true; | 
| } | 
| -void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom) | 
| +bool RenderBlockFlow::preLayoutBlockChild(RenderBox* child, bool& skipChildren) | 
| { | 
| - LayoutUnit oldPosMarginBefore = maxPositiveMarginBefore(); | 
| - LayoutUnit oldNegMarginBefore = maxNegativeMarginBefore(); | 
| + updateBlockChildDirtyBitsBeforeLayout(m_relayoutChildren, child); | 
| + | 
| + if (child->isOutOfFlowPositioned()) { | 
| + child->containingBlock()->insertPositionedObject(child); | 
| + adjustPositionedBlock(child, *m_marginInfo); | 
| + skipChildren = true; | 
| + return false; | 
| + } | 
| + | 
| + if (child->isFloating()) { | 
| + insertFloatingObject(child); | 
| + adjustFloatingBlock(*m_marginInfo); | 
| + skipChildren = true; | 
| + return false; | 
| + } | 
| + | 
| + m_oldPosMarginBefore = maxPositiveMarginBefore(); | 
| + m_oldNegMarginBefore = maxNegativeMarginBefore(); | 
| // The child is a normal flow object. Compute the margins we will use for collapsing now. | 
| child->computeAndSetBlockDirectionMargins(this); | 
| @@ -471,25 +550,25 @@ void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, | 
| // Try to guess our correct logical top position. In most cases this guess will | 
| // be correct. Only if we're wrong (when we compute the real logical top position) | 
| // will we have to potentially relayout. | 
| - LayoutUnit estimateWithoutPagination; | 
| - LayoutUnit logicalTopEstimate = estimateLogicalTopPosition(child, marginInfo, estimateWithoutPagination); | 
| + m_estimateWithoutPagination = 0; | 
| + m_logicalTopEstimate = estimateLogicalTopPosition(child, *m_marginInfo, m_estimateWithoutPagination); | 
| // Cache our old rect so that we can dirty the proper repaint rects if the child moves. | 
| - LayoutRect oldRect = child->frameRect(); | 
| + m_oldRect = child->frameRect(); | 
| LayoutUnit oldLogicalTop = logicalTopForChild(child); | 
| #if !ASSERT_DISABLED | 
| - LayoutSize oldLayoutDelta = RuntimeEnabledFeatures::repaintAfterLayoutEnabled() ? LayoutSize() : view()->layoutDelta(); | 
| + m_oldLayoutDelta = RuntimeEnabledFeatures::repaintAfterLayoutEnabled() ? LayoutSize() : view()->layoutDelta(); | 
| #endif | 
| // Go ahead and position the child as though it didn't collapse with the top. | 
| - setLogicalTopForChild(child, logicalTopEstimate, ApplyLayoutDelta); | 
| + setLogicalTopForChild(child, m_logicalTopEstimate, ApplyLayoutDelta); | 
| RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0; | 
| RenderBlockFlow* childRenderBlockFlow = (childRenderBlock && child->isRenderBlockFlow()) ? toRenderBlockFlow(child) : 0; | 
| bool markDescendantsWithFloats = false; | 
| - if (logicalTopEstimate != oldLogicalTop && !child->avoidsFloats() && childRenderBlock && childRenderBlock->containsFloats()) { | 
| + if (m_logicalTopEstimate != oldLogicalTop && !child->avoidsFloats() && childRenderBlock && childRenderBlock->containsFloats()) { | 
| markDescendantsWithFloats = true; | 
| - } else if (UNLIKELY(logicalTopEstimate.mightBeSaturated())) { | 
| + } else if (UNLIKELY(m_logicalTopEstimate.mightBeSaturated())) { | 
| // logicalTopEstimate, returned by estimateLogicalTopPosition, might be saturated for | 
| // very large elements. If it does the comparison with oldLogicalTop might yield a | 
| // false negative as adding and removing margins, borders etc from a saturated number | 
| @@ -498,8 +577,8 @@ void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, | 
| } else if (!child->avoidsFloats() || child->shrinkToAvoidFloats()) { | 
| // If an element might be affected by the presence of floats, then always mark it for | 
| // layout. | 
| - LayoutUnit fb = max(previousFloatLogicalBottom, lowestFloatLogicalBottom()); | 
| - if (fb > logicalTopEstimate) | 
| + LayoutUnit fb = max(m_previousFloatLogicalBottom, lowestFloatLogicalBottom()); | 
| + if (fb > m_logicalTopEstimate) | 
| markDescendantsWithFloats = true; | 
| } | 
| @@ -507,43 +586,58 @@ void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, | 
| if (markDescendantsWithFloats) | 
| childRenderBlockFlow->markAllDescendantsWithFloatsForLayout(); | 
| if (!child->isWritingModeRoot()) | 
| - previousFloatLogicalBottom = max(previousFloatLogicalBottom, oldLogicalTop + childRenderBlockFlow->lowestFloatLogicalBottom()); | 
| + m_previousFloatLogicalBottom = max(m_previousFloatLogicalBottom, oldLogicalTop + childRenderBlockFlow->lowestFloatLogicalBottom()); | 
| } | 
| - SubtreeLayoutScope layoutScope(child); | 
| + m_childLayoutScope = new SubtreeLayoutScope(child); | 
| if (!child->needsLayout()) | 
| - child->markForPaginationRelayoutIfNeeded(layoutScope); | 
| - | 
| - bool childHadLayout = child->everHadLayout(); | 
| - bool childNeededLayout = child->needsLayout(); | 
| - if (childNeededLayout) | 
| - child->layout(); | 
| + child->markForPaginationRelayoutIfNeeded(*m_childLayoutScope); | 
| + | 
| + m_childHadLayout = child->everHadLayout(); | 
| + m_childNeededLayout = child->needsLayout(); | 
| 
 
esprehn
2014/02/15 00:35:43
This doesn't feel right. Storing so much state in
 
atreat
2014/02/18 16:03:57
Right, see the comment in the header file.  We'll
 
 | 
| + skipChildren |= !m_childNeededLayout; | 
| + if (m_childNeededLayout) { | 
| + if (child->isNonRecursiveLayout()) | 
| + child->preLayout(); | 
| + else | 
| + child->layout(); | 
| + } | 
| + return true; | 
| +} | 
| - if (frameView()->partialLayout().isStopping()) | 
| +void RenderBlockFlow::postLayoutBlockChild(RenderBox* child) | 
| +{ | 
| + if (child->isOutOfFlowPositioned() || child->isFloating()) | 
| return; | 
| + if (m_childNeededLayout && child->isNonRecursiveLayout()) | 
| + child->postLayout(); | 
| + | 
| // Cache if we are at the top of the block right now. | 
| - bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock(); | 
| + bool atBeforeSideOfBlock = m_marginInfo->atBeforeSideOfBlock(); | 
| // Now determine the correct ypos based off examination of collapsing margin | 
| // values. | 
| - LayoutUnit logicalTopBeforeClear = collapseMargins(child, marginInfo); | 
| + LayoutUnit logicalTopBeforeClear = collapseMargins(child, *m_marginInfo); | 
| // Now check for clear. | 
| - LayoutUnit logicalTopAfterClear = clearFloatsIfNeeded(child, marginInfo, oldPosMarginBefore, oldNegMarginBefore, logicalTopBeforeClear); | 
| + LayoutUnit logicalTopAfterClear = clearFloatsIfNeeded(child, *m_marginInfo, m_oldPosMarginBefore, m_oldNegMarginBefore, logicalTopBeforeClear); | 
| bool paginated = view()->layoutState()->isPaginated(); | 
| if (paginated) { | 
| - logicalTopAfterClear = adjustBlockChildForPagination(logicalTopAfterClear, estimateWithoutPagination, child, | 
| + logicalTopAfterClear = adjustBlockChildForPagination(logicalTopAfterClear, m_estimateWithoutPagination, child, | 
| atBeforeSideOfBlock && logicalTopBeforeClear == logicalTopAfterClear); | 
| } | 
| setLogicalTopForChild(child, logicalTopAfterClear, ApplyLayoutDelta); | 
| + RenderBlock* childRenderBlock = child->isRenderBlock() ? toRenderBlock(child) : 0; | 
| + RenderBlockFlow* childRenderBlockFlow = (childRenderBlock && child->isRenderBlockFlow()) ? toRenderBlockFlow(child) : 0; | 
| + | 
| // Now we have a final top position. See if it really does end up being different from our estimate. | 
| // clearFloatsIfNeeded can also mark the child as needing a layout even though we didn't move. This happens | 
| // when collapseMargins dynamically adds overhanging floats because of a child with negative margins. | 
| - if (logicalTopAfterClear != logicalTopEstimate || child->needsLayout() || (paginated && childRenderBlock && childRenderBlock->shouldBreakAtLineToAvoidWidow())) { | 
| + if (logicalTopAfterClear != m_logicalTopEstimate || child->needsLayout() || (paginated && childRenderBlock && childRenderBlock->shouldBreakAtLineToAvoidWidow())) { | 
| SubtreeLayoutScope layoutScope(child); | 
| if (child->shrinkToAvoidFloats()) { | 
| // The child's width depends on the line width. | 
| @@ -568,30 +662,30 @@ void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, | 
| // we set this bit to ensure we would not collapse the child's margins, and those of any subsequent | 
| // self-collapsing siblings, with our parent. If this child is not self-collapsing then it can | 
| // collapse its margins with the parent so reset the bit. | 
| - if (!marginInfo.canCollapseMarginAfterWithLastChild() && !child->isSelfCollapsingBlock()) | 
| - marginInfo.setCanCollapseMarginAfterWithLastChild(true); | 
| + if (!m_marginInfo->canCollapseMarginAfterWithLastChild() && !child->isSelfCollapsingBlock()) | 
| + m_marginInfo->setCanCollapseMarginAfterWithLastChild(true); | 
| // We are no longer at the top of the block if we encounter a non-empty child. | 
| // This has to be done after checking for clear, so that margins can be reset if a clear occurred. | 
| - if (marginInfo.atBeforeSideOfBlock() && !child->isSelfCollapsingBlock()) | 
| - marginInfo.setAtBeforeSideOfBlock(false); | 
| + if (m_marginInfo->atBeforeSideOfBlock() && !child->isSelfCollapsingBlock()) | 
| + m_marginInfo->setAtBeforeSideOfBlock(false); | 
| // Now place the child in the correct left position | 
| determineLogicalLeftPositionForChild(child, ApplyLayoutDelta); | 
| - LayoutSize childOffset = child->location() - oldRect.location(); | 
| + LayoutSize childOffset = child->location() - m_oldRect.location(); | 
| relayoutShapeDescendantIfMoved(childRenderBlock, childOffset); | 
| // Update our height now that the child has been placed in the correct position. | 
| setLogicalHeight(logicalHeight() + logicalHeightForChild(child)); | 
| if (mustSeparateMarginAfterForChild(child)) { | 
| setLogicalHeight(logicalHeight() + marginAfterForChild(child)); | 
| - marginInfo.clearMargin(); | 
| + m_marginInfo->clearMargin(); | 
| } | 
| // If the child has overhanging floats that intrude into following siblings (or possibly out | 
| // of this block), then the parent gets notified of the floats now. | 
| if (childRenderBlockFlow && childRenderBlockFlow->containsFloats()) | 
| - maxFloatLogicalBottom = max(maxFloatLogicalBottom, addOverhangingFloats(childRenderBlockFlow, !childNeededLayout)); | 
| + m_maxFloatLogicalBottom = max(m_maxFloatLogicalBottom, addOverhangingFloats(childRenderBlockFlow, !m_childNeededLayout)); | 
| if (childOffset.width() || childOffset.height()) { | 
| if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) | 
| @@ -600,13 +694,13 @@ void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, | 
| // If the child moved, we have to repaint it as well as any floating/positioned | 
| // descendants. An exception is if we need a layout. In this case, we know we're going to | 
| // repaint ourselves (and the child) anyway. | 
| - if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && childHadLayout && !selfNeedsLayout()) | 
| + if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && m_childHadLayout && !selfNeedsLayout()) | 
| child->repaintOverhangingFloats(true); | 
| - else if (childHadLayout && !selfNeedsLayout() && child->checkForRepaintDuringLayout()) | 
| - child->repaintDuringLayoutIfMoved(oldRect); | 
| + else if (m_childHadLayout && !selfNeedsLayout() && child->checkForRepaintDuringLayout()) | 
| + child->repaintDuringLayoutIfMoved(m_oldRect); | 
| } | 
| - if (!childHadLayout && child->checkForRepaint()) { | 
| + if (!m_childHadLayout && child->checkForRepaint()) { | 
| if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) | 
| child->repaint(); | 
| child->repaintOverhangingFloats(true); | 
| @@ -614,14 +708,18 @@ void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, | 
| if (paginated) { | 
| // Check for an after page/column break. | 
| - LayoutUnit newHeight = applyAfterBreak(child, logicalHeight(), marginInfo); | 
| + LayoutUnit newHeight = applyAfterBreak(child, logicalHeight(), *m_marginInfo); | 
| if (newHeight != height()) | 
| setLogicalHeight(newHeight); | 
| } | 
| if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) { | 
| - ASSERT(view()->layoutDeltaMatches(oldLayoutDelta)); | 
| + ASSERT(view()->layoutDeltaMatches(m_oldLayoutDelta)); | 
| } | 
| + | 
| + m_lastNormalFlowChild = child; | 
| + delete m_childLayoutScope; | 
| + m_childLayoutScope = 0; | 
| } | 
| LayoutUnit RenderBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTopAfterClear, LayoutUnit estimateWithoutPagination, RenderBox* child, bool atBeforeSideOfBlock) | 
| @@ -848,63 +946,67 @@ void RenderBlockFlow::rebuildFloatsFromIntruding() | 
| } | 
| } | 
| -void RenderBlockFlow::layoutBlockChildren(bool relayoutChildren, LayoutUnit& maxFloatLogicalBottom, SubtreeLayoutScope& layoutScope, LayoutUnit beforeEdge, LayoutUnit afterEdge) | 
| +void RenderBlockFlow::layoutBlockChildren(LayoutUnit beforeEdge, LayoutUnit afterEdge, bool traverseChildren) | 
| { | 
| - dirtyForLayoutFromPercentageHeightDescendants(layoutScope); | 
| - | 
| - // Lay out our hypothetical grid line as though it occurs at the top of the block. | 
| - if (view()->layoutState()->lineGrid() == this) | 
| - layoutLineGridBox(); | 
| - | 
| // The margin struct caches all our current margin collapsing state. The compact struct caches state when we encounter compacts, | 
| - MarginInfo marginInfo(this, beforeEdge, afterEdge); | 
| + m_marginInfo = new MarginInfo(this, beforeEdge, afterEdge); | 
| 
 
esprehn
2014/02/15 00:35:43
Adding more mallocs doesn't seem like the right wa
 
 | 
| // Fieldsets need to find their legend and position it inside the border of the object. | 
| // The legend then gets skipped during normal layout. The same is true for ruby text. | 
| // It doesn't get included in the normal layout process but is instead skipped. | 
| - RenderObject* childToExclude = layoutSpecialExcludedChild(relayoutChildren, layoutScope); | 
| + m_childToExclude = layoutSpecialExcludedChild(m_relayoutChildren, *m_layoutScope); | 
| + m_previousFloatLogicalBottom = 0; | 
| + m_maxFloatLogicalBottom = 0; | 
| + m_lastNormalFlowChild = 0; | 
| - LayoutUnit previousFloatLogicalBottom = 0; | 
| - maxFloatLogicalBottom = 0; | 
| + if (!traverseChildren) | 
| + return; | 
| - RenderBox* next = firstChildBox(); | 
| - RenderBox* lastNormalFlowChild = 0; | 
| + bool skippingChildren = false; | 
| +#if NON_RECURSIVE | 
| + Order order = Pre; | 
| + RenderObject* childObject = nextForLayout(order, this, skippingChildren); | 
| + for (; childObject && childObject != this; childObject = childObject->nextForLayout(order, this, skippingChildren)) { | 
| + if (!childObject->isBox()) | 
| + continue; | 
| + RenderBox *child = toRenderBox(childObject); | 
| + skippingChildren = child->childrenInline(); | 
| +#else | 
| + (void)skippingChildren; | 
| + for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) { | 
| +#endif | 
| - while (next) { | 
| - RenderBox* child = next; | 
| - next = child->nextSiblingBox(); | 
| + ASSERT(child->parent()->isRenderBlockFlow()); | 
| + RenderBlockFlow* directParent = toRenderBlockFlow(child->parent()); | 
| LayoutRectRecorder recorder(*child); | 
| - | 
| - if (childToExclude == child) | 
| + if (directParent->m_childToExclude == child) { | 
| + skippingChildren = true; | 
| continue; // Skip this child, since it will be positioned by the specialized subclass (fieldsets and ruby runs). | 
| + } | 
| - updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, child); | 
| +#if NON_RECURSIVE | 
| + if (order == Pre) { | 
| +#endif | 
| - if (child->isOutOfFlowPositioned()) { | 
| - child->containingBlock()->insertPositionedObject(child); | 
| - adjustPositionedBlock(child, marginInfo); | 
| - continue; | 
| - } | 
| - if (child->isFloating()) { | 
| - insertFloatingObject(child); | 
| - adjustFloatingBlock(marginInfo); | 
| + // Lay out the child. | 
| + if (!directParent->preLayoutBlockChild(child, skippingChildren)) | 
| continue; | 
| - } | 
| - // Lay out the child. | 
| - layoutBlockChild(child, marginInfo, previousFloatLogicalBottom, maxFloatLogicalBottom); | 
| - lastNormalFlowChild = child; | 
| +#if NON_RECURSIVE | 
| + } else { | 
| +#endif | 
| + | 
| + directParent->postLayoutBlockChild(child); | 
| + | 
| +#if NON_RECURSIVE | 
| + } | 
| +#endif | 
| // If doing a partial layout and the child was the target renderer, early exit here. | 
| if (frameView()->partialLayout().checkPartialLayoutComplete(child)) | 
| return; | 
| - | 
| } | 
| - | 
| - // Now do the handling of the bottom of the block, adding in our bottom border/padding and | 
| - // determining the correct collapsed bottom margin information. | 
| - handleAfterSideOfBlock(lastNormalFlowChild, beforeEdge, afterEdge, marginInfo); | 
| } | 
| // Our MarginInfo state used when laying out block children. |