Commit cee0a2e1 authored by Richard Townsend's avatar Richard Townsend Committed by Commit Bot

fixup: ResumeParsingAfterPause's PumpTokenizer behaviour

Several possibilities entering this function:
1) We're parsing with kForceSynchronousParsing (no background parser,
   tokenizer_ defined)
2) We're parsing with kAllowAsynchronousParsing without a background
   parser started (no tokenizer_)
3) We're parsing with kAllowAsynchronousParsing _with_ a background
   parser started (no tokenizer_)
4) We're parsing with kAllowDeferredParsing (with tokenizer_)

The previous code called PumpTokenizerIfPossible _only_ if tokenizer_,
wasn't defined, so the implication is that this operation should be
done synchronously and only if the background parser isn't being used.
The new code either pumped the tokenizer immediately, or deferred
the pump. This CL restores the previous behaviour.

Bug: 901056, 1087032, 1087325, 1087753
Change-Id: I7ed8ee0eea91eb7786e07a82b399f40f0c651dbe
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2235836
Commit-Queue: Richard Townsend <richard.townsend@arm.com>
Reviewed-by: default avatarMason Freed <masonfreed@chromium.org>
Cr-Commit-Position: refs/heads/master@{#777296}
parent 71d1d12b
...@@ -1290,6 +1290,16 @@ bool HTMLDocumentParser::IsWaitingForScripts() const { ...@@ -1290,6 +1290,16 @@ bool HTMLDocumentParser::IsWaitingForScripts() const {
} }
void HTMLDocumentParser::ResumeParsingAfterPause() { void HTMLDocumentParser::ResumeParsingAfterPause() {
// This function runs after a parser-blocking script has completed. There are
// four possible cases:
// 1) Parsing with kForceSynchronousParsing, where there is no background
// parser and a tokenizer_'s defined.
// 2) Parsing with kAllowAsynchronousParsing, without a background parser. In
// this case, the document is usually being completed or parsing has
// otherwise stopped.
// 3) Parsing with kAllowAsynchronousParsing with a background parser. In this
// case, need to add any pending speculations to the document.
// 4) Parsing with kAllowDeferredParsing, with a tokenizer_.
TRACE_EVENT1("blink", "HTMLDocumentParser::ResumeParsingAfterPause", "parser", TRACE_EVENT1("blink", "HTMLDocumentParser::ResumeParsingAfterPause", "parser",
(void*)this); (void*)this);
DCHECK(!IsExecutingScript()); DCHECK(!IsExecutingScript());
...@@ -1299,7 +1309,7 @@ void HTMLDocumentParser::ResumeParsingAfterPause() { ...@@ -1299,7 +1309,7 @@ void HTMLDocumentParser::ResumeParsingAfterPause() {
if (IsStopped() || IsPaused()) if (IsStopped() || IsPaused())
return; return;
if (have_background_parser_) { if (have_background_parser_) { // Case 3)
// If we paused in the middle of processing a token chunk, // If we paused in the middle of processing a token chunk,
// deal with that before starting to pump. // deal with that before starting to pump.
if (last_chunk_before_pause_) { if (last_chunk_before_pause_) {
...@@ -1312,28 +1322,21 @@ void HTMLDocumentParser::ResumeParsingAfterPause() { ...@@ -1312,28 +1322,21 @@ void HTMLDocumentParser::ResumeParsingAfterPause() {
PumpPendingSpeculations(); PumpPendingSpeculations();
} }
return; return;
} else if (!tokenizer_) {
// Attempted fix for test_installer failures. Appears that
// HTMLDocumentParser::ExecuteScriptsWaitingForResources is queued from a
// callback tasks, which calls this, possibly after Detach.
DCHECK(!token_);
token_ = std::make_unique<HTMLToken>();
tokenizer_ = std::make_unique<HTMLTokenizer>(options_);
} }
insertion_preload_scanner_.reset(); insertion_preload_scanner_.reset();
task_runner_state_->SetEndIfDelayed(true); if (tokenizer_) {
if (task_runner_state_->GetMode() != // Case 1) or 4): kForceSynchronousParsing, kAllowDeferredParsing.
ParserSynchronizationPolicy::kAllowDeferredParsing) { // kForceSynchronousParsing must pump the tokenizer synchronously.
// kDeferredParsing could (theoretically) defer the tokenizer pump.
// TODO(Richard.Townsend@arm.com) investigate this.
task_runner_state_->SetEndIfDelayed(true);
task_runner_state_->SetShouldComplete(true);
PumpTokenizerIfPossible(); PumpTokenizerIfPossible();
} else { } else {
DCHECK(RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled()); // Case 2): kAllowAsynchronousParsing, no background parser available
loading_task_runner_->PostTask( // (indicating possible Document shutdown).
FROM_HERE, EndIfDelayed();
WTF::Bind(&HTMLDocumentParser::DeferredPumpTokenizerIfPossible,
WrapPersistent(this)));
task_runner_state_->SetState(
HTMLDocumentParserState::DeferredParserState::kScheduled);
} }
} }
......
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