Commit 120589bd authored by Morten Stenshorne's avatar Morten Stenshorne Committed by Commit Bot

[LayoutNG] Remove NGInlineChildLayoutContext member.

Remove NGInlineChildLayoutContext from NGBlockLayoutAlgorithm. This structure
is quite big, and since we stack-allocate the alogorithms, this matters. Only
stack-allocate NGInlineChildLayoutContext on demand (when children are inline).

This saves 816 bytes [*] of stack space per in-flow layout recursion.

[*] Linux 64bit release.

Bug: 930637
Change-Id: I40c12cb6e7996e54c9bf3ebe7285350591c90fef
Reviewed-on: https://chromium-review.googlesource.com/c/1485238Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Reviewed-by: default avatarChristian Biesinger <cbiesinger@chromium.org>
Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Commit-Queue: Morten Stenshorne <mstensho@chromium.org>
Cr-Commit-Position: refs/heads/master@{#635150}
parent 02c469f4
...@@ -353,6 +353,22 @@ NGLogicalOffset NGBlockLayoutAlgorithm::CalculateLogicalOffset( ...@@ -353,6 +353,22 @@ NGLogicalOffset NGBlockLayoutAlgorithm::CalculateLogicalOffset(
} }
scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout() { scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
// Inline children require an inline child layout context to be
// passed between siblings. We want to stack-allocate that one, but
// only on demand, as it's quite big.
if (Node().ChildrenInline())
return LayoutWithInlineChildLayoutContext();
return Layout(nullptr);
}
NOINLINE scoped_refptr<const NGLayoutResult>
NGBlockLayoutAlgorithm::LayoutWithInlineChildLayoutContext() {
NGInlineChildLayoutContext context;
return Layout(&context);
}
inline scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout(
NGInlineChildLayoutContext* inline_child_layout_context) {
NGBoxStrut borders = ComputeBorders(ConstraintSpace(), Node()); NGBoxStrut borders = ComputeBorders(ConstraintSpace(), Node());
NGBoxStrut padding = ComputePadding(ConstraintSpace(), Style()); NGBoxStrut padding = ComputePadding(ConstraintSpace(), Style());
border_padding_ = borders + padding; border_padding_ = borders + padding;
...@@ -529,9 +545,9 @@ scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout() { ...@@ -529,9 +545,9 @@ scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
&previous_inflow_position); &previous_inflow_position);
previous_inline_break_token = nullptr; previous_inline_break_token = nullptr;
} else { } else {
abort = abort = !HandleInflow(
!HandleInflow(child, child_break_token, &previous_inflow_position, child, child_break_token, &previous_inflow_position,
&previous_inline_break_token); inline_child_layout_context, &previous_inline_break_token);
} }
if (abort) { if (abort) {
...@@ -1218,6 +1234,7 @@ bool NGBlockLayoutAlgorithm::HandleInflow( ...@@ -1218,6 +1234,7 @@ bool NGBlockLayoutAlgorithm::HandleInflow(
NGLayoutInputNode child, NGLayoutInputNode child,
const NGBreakToken* child_break_token, const NGBreakToken* child_break_token,
NGPreviousInflowPosition* previous_inflow_position, NGPreviousInflowPosition* previous_inflow_position,
NGInlineChildLayoutContext* inline_child_layout_context,
scoped_refptr<const NGInlineBreakToken>* previous_inline_break_token) { scoped_refptr<const NGInlineBreakToken>* previous_inline_break_token) {
DCHECK(child); DCHECK(child);
DCHECK(!child.IsFloating()); DCHECK(!child.IsFloating());
...@@ -1261,15 +1278,16 @@ bool NGBlockLayoutAlgorithm::HandleInflow( ...@@ -1261,15 +1278,16 @@ bool NGBlockLayoutAlgorithm::HandleInflow(
has_clearance_past_adjoining_floats, /* is_new_fc */ false); has_clearance_past_adjoining_floats, /* is_new_fc */ false);
NGConstraintSpace child_space = NGConstraintSpace child_space =
CreateConstraintSpaceForChild(child, child_data, child_available_size_); CreateConstraintSpaceForChild(child, child_data, child_available_size_);
scoped_refptr<const NGLayoutResult> layout_result = child.Layout( scoped_refptr<const NGLayoutResult> layout_result =
child_space, child_break_token, &inline_child_layout_context_); child.Layout(child_space, child_break_token, inline_child_layout_context);
// To save space of the stack when we recurse into |NGBlockNode::Layout| // To save space of the stack when we recurse into |NGBlockNode::Layout|
// above, the rest of this function is continued within |FinishInflow|. // above, the rest of this function is continued within |FinishInflow|.
// However it should be read as one function. // However it should be read as one function.
return FinishInflow(child, child_break_token, child_space, return FinishInflow(child, child_break_token, child_space,
std::move(layout_result), &child_data, std::move(layout_result), &child_data,
previous_inflow_position, previous_inline_break_token); previous_inflow_position, inline_child_layout_context,
previous_inline_break_token);
} }
bool NGBlockLayoutAlgorithm::FinishInflow( bool NGBlockLayoutAlgorithm::FinishInflow(
...@@ -1279,6 +1297,7 @@ bool NGBlockLayoutAlgorithm::FinishInflow( ...@@ -1279,6 +1297,7 @@ bool NGBlockLayoutAlgorithm::FinishInflow(
scoped_refptr<const NGLayoutResult> layout_result, scoped_refptr<const NGLayoutResult> layout_result,
NGInflowChildData* child_data, NGInflowChildData* child_data,
NGPreviousInflowPosition* previous_inflow_position, NGPreviousInflowPosition* previous_inflow_position,
NGInlineChildLayoutContext* inline_child_layout_context,
scoped_refptr<const NGInlineBreakToken>* previous_inline_break_token) { scoped_refptr<const NGInlineBreakToken>* previous_inline_break_token) {
base::Optional<LayoutUnit> child_bfc_block_offset = base::Optional<LayoutUnit> child_bfc_block_offset =
layout_result->BfcBlockOffset(); layout_result->BfcBlockOffset();
...@@ -1406,7 +1425,7 @@ bool NGBlockLayoutAlgorithm::FinishInflow( ...@@ -1406,7 +1425,7 @@ bool NGBlockLayoutAlgorithm::FinishInflow(
NGConstraintSpace new_child_space = CreateConstraintSpaceForChild( NGConstraintSpace new_child_space = CreateConstraintSpaceForChild(
child, *child_data, child_available_size_, child_bfc_block_offset); child, *child_data, child_available_size_, child_bfc_block_offset);
layout_result = child.Layout(new_child_space, child_break_token, layout_result = child.Layout(new_child_space, child_break_token,
&inline_child_layout_context_); inline_child_layout_context);
if (layout_result->Status() == NGLayoutResult::kBfcBlockOffsetResolved) { if (layout_result->Status() == NGLayoutResult::kBfcBlockOffsetResolved) {
// Even a second layout pass may abort, if the BFC block offset initially // Even a second layout pass may abort, if the BFC block offset initially
...@@ -1419,7 +1438,7 @@ bool NGBlockLayoutAlgorithm::FinishInflow( ...@@ -1419,7 +1438,7 @@ bool NGBlockLayoutAlgorithm::FinishInflow(
new_child_space = CreateConstraintSpaceForChild( new_child_space = CreateConstraintSpaceForChild(
child, *child_data, child_available_size_, child_bfc_block_offset); child, *child_data, child_available_size_, child_bfc_block_offset);
layout_result = child.Layout(new_child_space, child_break_token, layout_result = child.Layout(new_child_space, child_break_token,
&inline_child_layout_context_); inline_child_layout_context);
} }
DCHECK_EQ(layout_result->Status(), NGLayoutResult::kSuccess); DCHECK_EQ(layout_result->Status(), NGLayoutResult::kSuccess);
......
...@@ -68,6 +68,12 @@ class CORE_EXPORT NGBlockLayoutAlgorithm ...@@ -68,6 +68,12 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
scoped_refptr<const NGLayoutResult> Layout() override; scoped_refptr<const NGLayoutResult> Layout() override;
private: private:
NOINLINE scoped_refptr<const NGLayoutResult>
LayoutWithInlineChildLayoutContext();
inline scoped_refptr<const NGLayoutResult> Layout(
NGInlineChildLayoutContext* inline_child_layout_context);
// Return the BFC block offset of this block. // Return the BFC block offset of this block.
LayoutUnit BfcBlockOffset() const { LayoutUnit BfcBlockOffset() const {
// If we have resolved our BFC block offset, use that. // If we have resolved our BFC block offset, use that.
...@@ -183,6 +189,7 @@ class CORE_EXPORT NGBlockLayoutAlgorithm ...@@ -183,6 +189,7 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
NGLayoutInputNode child, NGLayoutInputNode child,
const NGBreakToken* child_break_token, const NGBreakToken* child_break_token,
NGPreviousInflowPosition*, NGPreviousInflowPosition*,
NGInlineChildLayoutContext*,
scoped_refptr<const NGInlineBreakToken>* previous_inline_break_token); scoped_refptr<const NGInlineBreakToken>* previous_inline_break_token);
bool FinishInflow( bool FinishInflow(
...@@ -192,6 +199,7 @@ class CORE_EXPORT NGBlockLayoutAlgorithm ...@@ -192,6 +199,7 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
scoped_refptr<const NGLayoutResult>, scoped_refptr<const NGLayoutResult>,
NGInflowChildData*, NGInflowChildData*,
NGPreviousInflowPosition*, NGPreviousInflowPosition*,
NGInlineChildLayoutContext*,
scoped_refptr<const NGInlineBreakToken>* previous_inline_break_token); scoped_refptr<const NGInlineBreakToken>* previous_inline_break_token);
// Return the amount of block space available in the current fragmentainer // Return the amount of block space available in the current fragmentainer
...@@ -297,8 +305,6 @@ class CORE_EXPORT NGBlockLayoutAlgorithm ...@@ -297,8 +305,6 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
NGBoxStrut border_scrollbar_padding_; NGBoxStrut border_scrollbar_padding_;
LayoutUnit intrinsic_block_size_; LayoutUnit intrinsic_block_size_;
NGInlineChildLayoutContext inline_child_layout_context_;
// The line box index at which we ran out of space. This where we'll actually // The line box index at which we ran out of space. This where we'll actually
// end up breaking, unless we determine that we should break earlier in order // end up breaking, unless we determine that we should break earlier in order
// to satisfy the widows request. // to satisfy the widows request.
......
...@@ -838,6 +838,12 @@ void NGBlockNode::CopyFragmentDataToLayoutBoxForInlineChildren( ...@@ -838,6 +838,12 @@ void NGBlockNode::CopyFragmentDataToLayoutBoxForInlineChildren(
} }
} }
bool NGBlockNode::ChildrenInline() const {
if (const auto* block = ToLayoutBlockFlowOrNull(box_))
return AreNGBlockFlowChildrenInline(block);
return false;
}
bool NGBlockNode::IsInlineLevel() const { bool NGBlockNode::IsInlineLevel() const {
return GetLayoutBox()->IsInline(); return GetLayoutBox()->IsInline();
} }
......
...@@ -69,6 +69,7 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode { ...@@ -69,6 +69,7 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode {
NGBlockNode GetRenderedLegend() const; NGBlockNode GetRenderedLegend() const;
NGBlockNode GetFieldsetContent() const; NGBlockNode GetFieldsetContent() const;
bool ChildrenInline() const;
bool IsInlineLevel() const; bool IsInlineLevel() const;
bool IsAtomicInlineLevel() const; bool IsAtomicInlineLevel() const;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment