Commit 6a5c8f69 authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

[LayoutNG] Add DCHECK for when line breaker goes infinite loop

This patch adds a DCHECK to detect when |NGLineBreaker| goes
infinite loop by |HandleOverflow()|, |Rewind()|, but failed
to find appropriate secondary break point and |Rewind()| to
the same point again and again.

Change-Id: I9963fb5252f61fcfd0e5d768da8a4968f1f7c9e4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1801474Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Commit-Queue: Emil A Eklund <eae@chromium.org>
Commit-Queue: Koji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#696740}
parent 521b4319
...@@ -324,6 +324,10 @@ void NGLineBreaker::PrepareNextLine(NGLineInfo* line_info) { ...@@ -324,6 +324,10 @@ void NGLineBreaker::PrepareNextLine(NGLineInfo* line_info) {
position_ = line_info->TextIndent(); position_ = line_info->TextIndent();
overflow_item_index_ = 0; overflow_item_index_ = 0;
#if DCHECK_IS_ON()
last_rewind_from_item_index_ = last_rewind_to_item_index_ = 0;
#endif
} }
void NGLineBreaker::NextLine( void NGLineBreaker::NextLine(
...@@ -1687,6 +1691,9 @@ void NGLineBreaker::HandleOverflow(NGLineInfo* line_info) { ...@@ -1687,6 +1691,9 @@ void NGLineBreaker::HandleOverflow(NGLineInfo* line_info) {
Rewind(0, line_info); Rewind(0, line_info);
state_ = LineBreakState::kContinue; state_ = LineBreakState::kContinue;
overflow_item_index_ = 0; overflow_item_index_ = 0;
#if DCHECK_IS_ON()
last_rewind_from_item_index_ = last_rewind_to_item_index_ = 0;
#endif
return; return;
} }
...@@ -1709,6 +1716,15 @@ void NGLineBreaker::HandleOverflow(NGLineInfo* line_info) { ...@@ -1709,6 +1716,15 @@ void NGLineBreaker::HandleOverflow(NGLineInfo* line_info) {
} }
void NGLineBreaker::Rewind(unsigned new_end, NGLineInfo* line_info) { void NGLineBreaker::Rewind(unsigned new_end, NGLineInfo* line_info) {
#if DCHECK_IS_ON()
// Detect rewind-loop. If we're trying to rewind to the same index twice,
// we're in the infinite loop.
DCHECK(item_index_ != last_rewind_from_item_index_ ||
new_end != last_rewind_to_item_index_);
last_rewind_from_item_index_ = item_index_;
last_rewind_to_item_index_ = new_end;
#endif
NGInlineItemResults& item_results = *line_info->MutableResults(); NGInlineItemResults& item_results = *line_info->MutableResults();
DCHECK_LT(new_end, item_results.size()); DCHECK_LT(new_end, item_results.size());
......
...@@ -289,6 +289,12 @@ class CORE_EXPORT NGLineBreaker { ...@@ -289,6 +289,12 @@ class CORE_EXPORT NGLineBreaker {
// This is copied from NGInlineNode, then updated after each forced line break // This is copied from NGInlineNode, then updated after each forced line break
// if 'unicode-bidi: plaintext'. // if 'unicode-bidi: plaintext'.
TextDirection base_direction_; TextDirection base_direction_;
#if DCHECK_IS_ON()
// These fields are to detect rewind-loop.
unsigned last_rewind_from_item_index_ = 0;
unsigned last_rewind_to_item_index_ = 0;
#endif
}; };
} // namespace blink } // namespace blink
......
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