Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp

Issue 2695633007: Revert of Put the BackgroundHTMLParser on oilpan heap (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 23 matching lines...) Expand all
34 #include "core/dom/TaskRunnerHelper.h" 34 #include "core/dom/TaskRunnerHelper.h"
35 #include "core/frame/LocalFrame.h" 35 #include "core/frame/LocalFrame.h"
36 #include "core/frame/Settings.h" 36 #include "core/frame/Settings.h"
37 #include "core/html/HTMLDocument.h" 37 #include "core/html/HTMLDocument.h"
38 #include "core/html/parser/AtomicHTMLToken.h" 38 #include "core/html/parser/AtomicHTMLToken.h"
39 #include "core/html/parser/BackgroundHTMLParser.h" 39 #include "core/html/parser/BackgroundHTMLParser.h"
40 #include "core/html/parser/HTMLParserScheduler.h" 40 #include "core/html/parser/HTMLParserScheduler.h"
41 #include "core/html/parser/HTMLParserScriptRunner.h" 41 #include "core/html/parser/HTMLParserScriptRunner.h"
42 #include "core/html/parser/HTMLResourcePreloader.h" 42 #include "core/html/parser/HTMLResourcePreloader.h"
43 #include "core/html/parser/HTMLTreeBuilder.h" 43 #include "core/html/parser/HTMLTreeBuilder.h"
44 #include "core/html/parser/TokenizedChunkQueue.h"
45 #include "core/inspector/InspectorInstrumentation.h" 44 #include "core/inspector/InspectorInstrumentation.h"
46 #include "core/inspector/InspectorTraceEvents.h" 45 #include "core/inspector/InspectorTraceEvents.h"
47 #include "core/loader/DocumentLoader.h" 46 #include "core/loader/DocumentLoader.h"
48 #include "core/loader/LinkLoader.h" 47 #include "core/loader/LinkLoader.h"
49 #include "core/loader/NavigationScheduler.h" 48 #include "core/loader/NavigationScheduler.h"
50 #include "platform/CrossThreadFunctional.h" 49 #include "platform/CrossThreadFunctional.h"
51 #include "platform/Histogram.h" 50 #include "platform/Histogram.h"
52 #include "platform/SharedBuffer.h" 51 #include "platform/SharedBuffer.h"
53 #include "platform/WebFrameScheduler.h" 52 #include "platform/WebFrameScheduler.h"
54 #include "platform/heap/Handle.h" 53 #include "platform/heap/Handle.h"
55 #include "platform/heap/Persistent.h"
56 #include "platform/instrumentation/tracing/TraceEvent.h" 54 #include "platform/instrumentation/tracing/TraceEvent.h"
57 #include "platform/loader/fetch/ResourceFetcher.h" 55 #include "platform/loader/fetch/ResourceFetcher.h"
58 #include "public/platform/Platform.h" 56 #include "public/platform/Platform.h"
59 #include "public/platform/WebLoadingBehaviorFlag.h" 57 #include "public/platform/WebLoadingBehaviorFlag.h"
60 #include "public/platform/WebScheduler.h" 58 #include "public/platform/WebScheduler.h"
61 #include "public/platform/WebThread.h" 59 #include "public/platform/WebThread.h"
62 #include "wtf/AutoReset.h" 60 #include "wtf/AutoReset.h"
63 #include "wtf/PtrUtil.h" 61 #include "wtf/PtrUtil.h"
62 #include <memory>
64 63
65 namespace blink { 64 namespace blink {
66 65
67 using namespace HTMLNames; 66 using namespace HTMLNames;
68 67
69 // This is a direct transcription of step 4 from: 68 // This is a direct transcription of step 4 from:
70 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#frag ment-case 69 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#frag ment-case
71 static HTMLTokenizer::State tokenizerStateForContextElement( 70 static HTMLTokenizer::State tokenizerStateForContextElement(
72 Element* contextElement, 71 Element* contextElement,
73 bool reportErrors, 72 bool reportErrors,
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 ParserSynchronizationPolicy syncPolicy) 124 ParserSynchronizationPolicy syncPolicy)
126 : ScriptableDocumentParser(document, contentPolicy), 125 : ScriptableDocumentParser(document, contentPolicy),
127 m_options(&document), 126 m_options(&document),
128 m_reentryPermit(HTMLParserReentryPermit::create()), 127 m_reentryPermit(HTMLParserReentryPermit::create()),
129 m_token(syncPolicy == ForceSynchronousParsing 128 m_token(syncPolicy == ForceSynchronousParsing
130 ? WTF::wrapUnique(new HTMLToken) 129 ? WTF::wrapUnique(new HTMLToken)
131 : nullptr), 130 : nullptr),
132 m_tokenizer(syncPolicy == ForceSynchronousParsing 131 m_tokenizer(syncPolicy == ForceSynchronousParsing
133 ? HTMLTokenizer::create(m_options) 132 ? HTMLTokenizer::create(m_options)
134 : nullptr), 133 : nullptr),
134 m_loadingTaskRunner(
135 TaskRunnerHelper::get(TaskType::Networking, &document)),
135 m_parserScheduler( 136 m_parserScheduler(
136 syncPolicy == AllowAsynchronousParsing 137 syncPolicy == AllowAsynchronousParsing
137 ? HTMLParserScheduler::create( 138 ? HTMLParserScheduler::create(this, m_loadingTaskRunner.get())
138 this,
139 TaskRunnerHelper::get(TaskType::Networking, &document))
140 : nullptr), 139 : nullptr),
141 m_xssAuditorDelegate(&document), 140 m_xssAuditorDelegate(&document),
141 m_weakFactory(this),
142 m_preloader(HTMLResourcePreloader::create(document)), 142 m_preloader(HTMLResourcePreloader::create(document)),
143 m_tokenizedChunkQueue(TokenizedChunkQueue::create()), 143 m_tokenizedChunkQueue(TokenizedChunkQueue::create()),
144 m_evaluator(DocumentWriteEvaluator::create(document)), 144 m_evaluator(DocumentWriteEvaluator::create(document)),
145 m_pendingCSPMetaToken(nullptr), 145 m_pendingCSPMetaToken(nullptr),
146 m_shouldUseThreading(syncPolicy == AllowAsynchronousParsing), 146 m_shouldUseThreading(syncPolicy == AllowAsynchronousParsing),
147 m_endWasDelayed(false), 147 m_endWasDelayed(false),
148 m_haveBackgroundParser(false),
148 m_tasksWereSuspended(false), 149 m_tasksWereSuspended(false),
149 m_pumpSessionNestingLevel(0), 150 m_pumpSessionNestingLevel(0),
150 m_pumpSpeculationsSessionNestingLevel(0), 151 m_pumpSpeculationsSessionNestingLevel(0),
151 m_isParsingAtLineNumber(false), 152 m_isParsingAtLineNumber(false),
152 m_triedLoadingLinkHeaders(false), 153 m_triedLoadingLinkHeaders(false),
153 m_addedPendingStylesheetInBody(false), 154 m_addedPendingStylesheetInBody(false),
154 m_isWaitingForStylesheets(false) { 155 m_isWaitingForStylesheets(false) {
155 ASSERT(shouldUseThreading() || (m_token && m_tokenizer)); 156 ASSERT(shouldUseThreading() || (m_token && m_tokenizer));
156 // Threading is not allowed in prefetch mode. 157 // Threading is not allowed in prefetch mode.
157 DCHECK(!document.isPrefetchOnly() || !shouldUseThreading()); 158 DCHECK(!document.isPrefetchOnly() || !shouldUseThreading());
158 } 159 }
159 160
160 HTMLDocumentParser::~HTMLDocumentParser() {} 161 HTMLDocumentParser::~HTMLDocumentParser() {}
161 162
163 void HTMLDocumentParser::dispose() {
164 // In Oilpan, HTMLDocumentParser can die together with Document, and detach()
165 // is not called in this case.
166 if (m_haveBackgroundParser)
167 stopBackgroundParser();
168 }
169
162 DEFINE_TRACE(HTMLDocumentParser) { 170 DEFINE_TRACE(HTMLDocumentParser) {
163 visitor->trace(m_treeBuilder); 171 visitor->trace(m_treeBuilder);
164 visitor->trace(m_parserScheduler); 172 visitor->trace(m_parserScheduler);
165 visitor->trace(m_xssAuditorDelegate); 173 visitor->trace(m_xssAuditorDelegate);
166 visitor->trace(m_scriptRunner); 174 visitor->trace(m_scriptRunner);
167 visitor->trace(m_backgroundParser);
168 visitor->trace(m_preloader); 175 visitor->trace(m_preloader);
169 ScriptableDocumentParser::trace(visitor); 176 ScriptableDocumentParser::trace(visitor);
170 HTMLParserScriptRunnerHost::trace(visitor); 177 HTMLParserScriptRunnerHost::trace(visitor);
171 } 178 }
172 179
173 void HTMLDocumentParser::detach() { 180 void HTMLDocumentParser::detach() {
174 if (!isParsingFragment() && m_tokenizedChunkQueue.get() && 181 if (!isParsingFragment() && m_tokenizedChunkQueue.get() &&
175 m_tokenizedChunkQueue->peakPendingChunkCount()) { 182 m_tokenizedChunkQueue->peakPendingChunkCount()) {
176 DEFINE_STATIC_LOCAL(CustomCountHistogram, peakPendingChunkHistogram, 183 DEFINE_STATIC_LOCAL(CustomCountHistogram, peakPendingChunkHistogram,
177 ("Parser.PeakPendingChunkCount", 1, 1000, 50)); 184 ("Parser.PeakPendingChunkCount", 1, 1000, 50));
178 peakPendingChunkHistogram.count( 185 peakPendingChunkHistogram.count(
179 m_tokenizedChunkQueue->peakPendingChunkCount()); 186 m_tokenizedChunkQueue->peakPendingChunkCount());
180 DEFINE_STATIC_LOCAL(CustomCountHistogram, peakPendingTokenHistogram, 187 DEFINE_STATIC_LOCAL(CustomCountHistogram, peakPendingTokenHistogram,
181 ("Parser.PeakPendingTokenCount", 1, 100000, 50)); 188 ("Parser.PeakPendingTokenCount", 1, 100000, 50));
182 peakPendingTokenHistogram.count( 189 peakPendingTokenHistogram.count(
183 m_tokenizedChunkQueue->peakPendingTokenCount()); 190 m_tokenizedChunkQueue->peakPendingTokenCount());
184 } 191 }
185 192
186 m_backgroundParser.clear(); 193 if (m_haveBackgroundParser)
194 stopBackgroundParser();
187 DocumentParser::detach(); 195 DocumentParser::detach();
188 if (m_scriptRunner) 196 if (m_scriptRunner)
189 m_scriptRunner->detach(); 197 m_scriptRunner->detach();
190 m_treeBuilder->detach(); 198 m_treeBuilder->detach();
191 // FIXME: It seems wrong that we would have a preload scanner here. Yet during 199 // FIXME: It seems wrong that we would have a preload scanner here. Yet during
192 // fast/dom/HTMLScriptElement/script-load-events.html we do. 200 // fast/dom/HTMLScriptElement/script-load-events.html we do.
193 m_preloadScanner.reset(); 201 m_preloadScanner.reset();
194 m_insertionPreloadScanner.reset(); 202 m_insertionPreloadScanner.reset();
195 if (m_parserScheduler) { 203 if (m_parserScheduler) {
196 m_parserScheduler->detach(); 204 m_parserScheduler->detach();
197 m_parserScheduler.clear(); 205 m_parserScheduler.clear();
198 } 206 }
199 // Oilpan: It is important to clear m_token to deallocate backing memory of 207 // Oilpan: It is important to clear m_token to deallocate backing memory of
200 // HTMLToken::m_data and let the allocator reuse the memory for 208 // HTMLToken::m_data and let the allocator reuse the memory for
201 // HTMLToken::m_data of a next HTMLDocumentParser. We need to clear 209 // HTMLToken::m_data of a next HTMLDocumentParser. We need to clear
202 // m_tokenizer first because m_tokenizer has a raw pointer to m_token. 210 // m_tokenizer first because m_tokenizer has a raw pointer to m_token.
203 m_tokenizer.reset(); 211 m_tokenizer.reset();
204 m_token.reset(); 212 m_token.reset();
205 } 213 }
206 214
207 void HTMLDocumentParser::stopParsing() { 215 void HTMLDocumentParser::stopParsing() {
208 DocumentParser::stopParsing(); 216 DocumentParser::stopParsing();
209 if (m_parserScheduler) { 217 if (m_parserScheduler) {
210 m_parserScheduler->detach(); 218 m_parserScheduler->detach();
211 m_parserScheduler.clear(); 219 m_parserScheduler.clear();
212 } 220 }
213 m_backgroundParser.clear(); 221 if (m_haveBackgroundParser)
222 stopBackgroundParser();
214 } 223 }
215 224
216 // This kicks off "Once the user agent stops parsing" as described by: 225 // This kicks off "Once the user agent stops parsing" as described by:
217 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the- end 226 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the- end
218 void HTMLDocumentParser::prepareToStopParsing() { 227 void HTMLDocumentParser::prepareToStopParsing() {
219 // FIXME: It may not be correct to disable this for the background parser. 228 // FIXME: It may not be correct to disable this for the background parser.
220 // That means hasInsertionPoint() may not be correct in some cases. 229 // That means hasInsertionPoint() may not be correct in some cases.
221 ASSERT(!hasInsertionPoint() || m_backgroundParser); 230 ASSERT(!hasInsertionPoint() || m_haveBackgroundParser);
222 231
223 // NOTE: This pump should only ever emit buffered character tokens. 232 // NOTE: This pump should only ever emit buffered character tokens.
224 if (m_tokenizer) { 233 if (m_tokenizer) {
225 ASSERT(!m_backgroundParser); 234 ASSERT(!m_haveBackgroundParser);
226 pumpTokenizerIfPossible(); 235 pumpTokenizerIfPossible();
227 } 236 }
228 237
229 if (isStopped()) 238 if (isStopped())
230 return; 239 return;
231 240
232 DocumentParser::prepareToStopParsing(); 241 DocumentParser::prepareToStopParsing();
233 242
234 // We will not have a scriptRunner when parsing a DocumentFragment. 243 // We will not have a scriptRunner when parsing a DocumentFragment.
235 if (m_scriptRunner) 244 if (m_scriptRunner)
(...skipping 19 matching lines...) Expand all
255 pumpTokenizer(); 264 pumpTokenizer();
256 } 265 }
257 266
258 bool HTMLDocumentParser::isScheduledForResume() const { 267 bool HTMLDocumentParser::isScheduledForResume() const {
259 return m_parserScheduler && m_parserScheduler->isScheduledForResume(); 268 return m_parserScheduler && m_parserScheduler->isScheduledForResume();
260 } 269 }
261 270
262 // Used by HTMLParserScheduler 271 // Used by HTMLParserScheduler
263 void HTMLDocumentParser::resumeParsingAfterYield() { 272 void HTMLDocumentParser::resumeParsingAfterYield() {
264 ASSERT(shouldUseThreading()); 273 ASSERT(shouldUseThreading());
265 ASSERT(m_backgroundParser); 274 ASSERT(m_haveBackgroundParser);
266 275
267 checkIfBodyStylesheetAdded(); 276 checkIfBodyStylesheetAdded();
268 if (isStopped() || isPaused()) 277 if (isStopped() || isPaused())
269 return; 278 return;
270 279
271 pumpPendingSpeculations(); 280 pumpPendingSpeculations();
272 } 281 }
273 282
274 void HTMLDocumentParser::runScriptsForPausedTreeBuilder() { 283 void HTMLDocumentParser::runScriptsForPausedTreeBuilder() {
275 ASSERT(scriptingContentIsAllowed(getParserContentPolicy())); 284 ASSERT(scriptingContentIsAllowed(getParserContentPolicy()));
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 if (!isPaused() && !isScheduledForResume()) { 391 if (!isPaused() && !isScheduledForResume()) {
383 if (m_tasksWereSuspended) 392 if (m_tasksWereSuspended)
384 m_parserScheduler->forceResumeAfterYield(); 393 m_parserScheduler->forceResumeAfterYield();
385 else 394 else
386 m_parserScheduler->scheduleForResume(); 395 m_parserScheduler->scheduleForResume();
387 } 396 }
388 } 397 }
389 398
390 void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser( 399 void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser(
391 const DocumentEncodingData& data) { 400 const DocumentEncodingData& data) {
392 if (!isParsing())
393 return;
394 document()->setEncodingData(data); 401 document()->setEncodingData(data);
395 } 402 }
396 403
397 void HTMLDocumentParser::validateSpeculations( 404 void HTMLDocumentParser::validateSpeculations(
398 std::unique_ptr<TokenizedChunk> chunk) { 405 std::unique_ptr<TokenizedChunk> chunk) {
399 ASSERT(chunk); 406 ASSERT(chunk);
400 // TODO(kouhei): We should simplify codepath here by disallowing 407 // TODO(kouhei): We should simplify codepath here by disallowing
401 // validateSpeculations 408 // validateSpeculations
402 // while isPaused, and m_lastChunkBeforePause can simply be 409 // while isPaused, and m_lastChunkBeforePause can simply be
403 // pushed to m_speculations. 410 // pushed to m_speculations.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 } 444 }
438 445
439 discardSpeculationsAndResumeFrom(std::move(chunk), std::move(token), 446 discardSpeculationsAndResumeFrom(std::move(chunk), std::move(token),
440 std::move(tokenizer)); 447 std::move(tokenizer));
441 } 448 }
442 449
443 void HTMLDocumentParser::discardSpeculationsAndResumeFrom( 450 void HTMLDocumentParser::discardSpeculationsAndResumeFrom(
444 std::unique_ptr<TokenizedChunk> lastChunkBeforeScript, 451 std::unique_ptr<TokenizedChunk> lastChunkBeforeScript,
445 std::unique_ptr<HTMLToken> token, 452 std::unique_ptr<HTMLToken> token,
446 std::unique_ptr<HTMLTokenizer> tokenizer) { 453 std::unique_ptr<HTMLTokenizer> tokenizer) {
454 m_weakFactory.revokeAll();
455
447 size_t discardedTokenCount = 0; 456 size_t discardedTokenCount = 0;
448 for (const auto& speculation : m_speculations) { 457 for (const auto& speculation : m_speculations) {
449 discardedTokenCount += speculation->tokens->size(); 458 discardedTokenCount += speculation->tokens->size();
450 } 459 }
451 DEFINE_STATIC_LOCAL(CustomCountHistogram, discardedTokenCountHistogram, 460 DEFINE_STATIC_LOCAL(CustomCountHistogram, discardedTokenCountHistogram,
452 ("Parser.DiscardedTokenCount", 1, 100000, 50)); 461 ("Parser.DiscardedTokenCount", 1, 100000, 50));
453 discardedTokenCountHistogram.count(discardedTokenCount); 462 discardedTokenCountHistogram.count(discardedTokenCount);
454 463
455 m_speculations.clear(); 464 m_speculations.clear();
456 m_pendingCSPMetaToken = nullptr; 465 m_pendingCSPMetaToken = nullptr;
457 m_queuedPreloads.clear(); 466 m_queuedPreloads.clear();
458 467
459 std::unique_ptr<BackgroundHTMLParser::Checkpoint> checkpoint = 468 std::unique_ptr<BackgroundHTMLParser::Checkpoint> checkpoint =
460 WTF::wrapUnique(new BackgroundHTMLParser::Checkpoint); 469 WTF::wrapUnique(new BackgroundHTMLParser::Checkpoint);
470 checkpoint->parser = m_weakFactory.createWeakPtr();
461 checkpoint->token = std::move(token); 471 checkpoint->token = std::move(token);
462 checkpoint->tokenizer = std::move(tokenizer); 472 checkpoint->tokenizer = std::move(tokenizer);
463 checkpoint->treeBuilderState = 473 checkpoint->treeBuilderState =
464 HTMLTreeBuilderSimulator::stateFor(m_treeBuilder.get()); 474 HTMLTreeBuilderSimulator::stateFor(m_treeBuilder.get());
465 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint; 475 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint;
466 checkpoint->preloadScannerCheckpoint = 476 checkpoint->preloadScannerCheckpoint =
467 lastChunkBeforeScript->preloadScannerCheckpoint; 477 lastChunkBeforeScript->preloadScannerCheckpoint;
468 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy(); 478 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy();
469 // FIXME: This should be passed in instead of cleared. 479 // FIXME: This should be passed in instead of cleared.
470 m_input.current().clear(); 480 m_input.current().clear();
471 481
472 ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread()); 482 ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread());
473 m_backgroundParser->resumeFrom(std::move(checkpoint)); 483 m_loadingTaskRunner->postTask(
484 BLINK_FROM_HERE,
485 WTF::bind(&BackgroundHTMLParser::resumeFrom, m_backgroundParser,
486 WTF::passed(std::move(checkpoint))));
474 } 487 }
475 488
476 size_t HTMLDocumentParser::processTokenizedChunkFromBackgroundParser( 489 size_t HTMLDocumentParser::processTokenizedChunkFromBackgroundParser(
477 std::unique_ptr<TokenizedChunk> popChunk) { 490 std::unique_ptr<TokenizedChunk> popChunk) {
478 TRACE_EVENT_WITH_FLOW0( 491 TRACE_EVENT_WITH_FLOW0(
479 "blink,loading", 492 "blink,loading",
480 "HTMLDocumentParser::processTokenizedChunkFromBackgroundParser", 493 "HTMLDocumentParser::processTokenizedChunkFromBackgroundParser",
481 popChunk.get(), TRACE_EVENT_FLAG_FLOW_IN); 494 popChunk.get(), TRACE_EVENT_FLAG_FLOW_IN);
482 AutoReset<bool> hasLineNumber(&m_isParsingAtLineNumber, true); 495 AutoReset<bool> hasLineNumber(&m_isParsingAtLineNumber, true);
483 496
484 SECURITY_DCHECK(m_pumpSpeculationsSessionNestingLevel == 1); 497 SECURITY_DCHECK(m_pumpSpeculationsSessionNestingLevel == 1);
485 SECURITY_DCHECK(!inPumpSession()); 498 SECURITY_DCHECK(!inPumpSession());
486 ASSERT(!isParsingFragment()); 499 ASSERT(!isParsingFragment());
487 DCHECK(!isPaused()); 500 DCHECK(!isPaused());
488 ASSERT(!isStopped()); 501 ASSERT(!isStopped());
489 ASSERT(shouldUseThreading()); 502 ASSERT(shouldUseThreading());
490 ASSERT(!m_tokenizer); 503 ASSERT(!m_tokenizer);
491 ASSERT(!m_token); 504 ASSERT(!m_token);
492 DCHECK(!m_lastChunkBeforePause); 505 DCHECK(!m_lastChunkBeforePause);
493 506
494 std::unique_ptr<TokenizedChunk> chunk(std::move(popChunk)); 507 std::unique_ptr<TokenizedChunk> chunk(std::move(popChunk));
495 std::unique_ptr<CompactHTMLTokenStream> tokens = std::move(chunk->tokens); 508 std::unique_ptr<CompactHTMLTokenStream> tokens = std::move(chunk->tokens);
496 size_t elementTokenCount = 0; 509 size_t elementTokenCount = 0;
497 510
498 m_backgroundParser->startedChunkWithCheckpoint(chunk->inputCheckpoint); 511 m_loadingTaskRunner->postTask(
512 BLINK_FROM_HERE,
513 WTF::bind(&BackgroundHTMLParser::startedChunkWithCheckpoint,
514 m_backgroundParser, chunk->inputCheckpoint));
499 515
500 for (const auto& xssInfo : chunk->xssInfos) { 516 for (const auto& xssInfo : chunk->xssInfos) {
501 m_textPosition = xssInfo->m_textPosition; 517 m_textPosition = xssInfo->m_textPosition;
502 m_xssAuditorDelegate.didBlockScript(*xssInfo); 518 m_xssAuditorDelegate.didBlockScript(*xssInfo);
503 if (isStopped()) 519 if (isStopped())
504 break; 520 break;
505 } 521 }
506 // XSSAuditorDelegate can detach the parser if it decides to block the entire 522 // XSSAuditorDelegate can detach the parser if it decides to block the entire
507 // current document. 523 // current document.
508 if (isDetached()) 524 if (isDetached())
509 return elementTokenCount; 525 return elementTokenCount;
510 526
511 for (Vector<CompactHTMLToken>::const_iterator it = tokens->begin(); 527 for (Vector<CompactHTMLToken>::const_iterator it = tokens->begin();
512 it != tokens->end(); ++it) { 528 it != tokens->end(); ++it) {
513 ASSERT(!isWaitingForScripts()); 529 ASSERT(!isWaitingForScripts());
514 530
515 if (!chunk->startingScript && 531 if (!chunk->startingScript &&
516 (it->type() == HTMLToken::StartTag || it->type() == HTMLToken::EndTag)) 532 (it->type() == HTMLToken::StartTag || it->type() == HTMLToken::EndTag))
517 elementTokenCount++; 533 elementTokenCount++;
518 534
519 if (document()->frame() && 535 if (document()->frame() &&
520 document()->frame()->navigationScheduler().locationChangePending()) { 536 document()->frame()->navigationScheduler().locationChangePending()) {
521 // To match main-thread parser behavior (which never checks 537 // To match main-thread parser behavior (which never checks
522 // locationChangePending on the EOF path) we peek to see if this chunk has 538 // locationChangePending on the EOF path) we peek to see if this chunk has
523 // an EOF and process it anyway. 539 // an EOF and process it anyway.
524 if (tokens->back().type() == HTMLToken::EndOfFile) { 540 if (tokens->back().type() == HTMLToken::EndOfFile) {
525 // There should never be any chunks after the EOF. 541 ASSERT(
526 ASSERT(m_speculations.isEmpty()); 542 m_speculations
543 .isEmpty()); // There should never be any chunks after the EOF.
527 prepareToStopParsing(); 544 prepareToStopParsing();
528 } 545 }
529 break; 546 break;
530 } 547 }
531 548
532 m_textPosition = it->textPosition(); 549 m_textPosition = it->textPosition();
533 550
534 constructTreeFromCompactHTMLToken(*it); 551 constructTreeFromCompactHTMLToken(*it);
535 552
536 if (isStopped()) 553 if (isStopped())
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 InspectorParseHtmlEvent::endData(lineNumber().zeroBasedInt() - 1)); 647 InspectorParseHtmlEvent::endData(lineNumber().zeroBasedInt() - 1));
631 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), 648 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"),
632 "UpdateCounters", TRACE_EVENT_SCOPE_THREAD, "data", 649 "UpdateCounters", TRACE_EVENT_SCOPE_THREAD, "data",
633 InspectorUpdateCountersEvent::data()); 650 InspectorUpdateCountersEvent::data());
634 } 651 }
635 652
636 void HTMLDocumentParser::forcePlaintextForTextDocument() { 653 void HTMLDocumentParser::forcePlaintextForTextDocument() {
637 if (shouldUseThreading()) { 654 if (shouldUseThreading()) {
638 // This method is called before any data is appended, so we have to start 655 // This method is called before any data is appended, so we have to start
639 // the background parser ourselves. 656 // the background parser ourselves.
640 if (!m_backgroundParser) 657 if (!m_haveBackgroundParser)
641 startBackgroundParser(); 658 startBackgroundParser();
642 659
643 // This task should be synchronous, because otherwise synchronous 660 // This task should be synchronous, because otherwise synchronous
644 // tokenizing can happen before plaintext is forced. 661 // tokenizing can happen before plaintext is forced.
645 m_backgroundParser->forcePlaintextForTextDocument(); 662 m_backgroundParser->forcePlaintextForTextDocument();
646 } else 663 } else
647 m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState); 664 m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState);
648 } 665 }
649 666
650 void HTMLDocumentParser::pumpTokenizer() { 667 void HTMLDocumentParser::pumpTokenizer() {
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 787
771 void HTMLDocumentParser::insert(const SegmentedString& source) { 788 void HTMLDocumentParser::insert(const SegmentedString& source) {
772 if (isStopped()) 789 if (isStopped())
773 return; 790 return;
774 791
775 TRACE_EVENT1("blink", "HTMLDocumentParser::insert", "source_length", 792 TRACE_EVENT1("blink", "HTMLDocumentParser::insert", "source_length",
776 source.length()); 793 source.length());
777 794
778 if (!m_tokenizer) { 795 if (!m_tokenizer) {
779 ASSERT(!inPumpSession()); 796 ASSERT(!inPumpSession());
780 ASSERT(m_backgroundParser || wasCreatedByScript()); 797 ASSERT(m_haveBackgroundParser || wasCreatedByScript());
781 m_token = WTF::wrapUnique(new HTMLToken); 798 m_token = WTF::wrapUnique(new HTMLToken);
782 m_tokenizer = HTMLTokenizer::create(m_options); 799 m_tokenizer = HTMLTokenizer::create(m_options);
783 } 800 }
784 801
785 SegmentedString excludedLineNumberSource(source); 802 SegmentedString excludedLineNumberSource(source);
786 excludedLineNumberSource.setExcludeLineNumbers(); 803 excludedLineNumberSource.setExcludeLineNumbers();
787 m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource); 804 m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource);
788 pumpTokenizerIfPossible(); 805 pumpTokenizerIfPossible();
789 806
790 if (isPaused()) { 807 if (isPaused()) {
791 // Check the document.write() output with a separate preload scanner as 808 // Check the document.write() output with a separate preload scanner as
792 // the main scanner can't deal with insertions. 809 // the main scanner can't deal with insertions.
793 if (!m_insertionPreloadScanner) 810 if (!m_insertionPreloadScanner)
794 m_insertionPreloadScanner = createPreloadScanner(); 811 m_insertionPreloadScanner = createPreloadScanner();
795 m_insertionPreloadScanner->appendToEnd(source); 812 m_insertionPreloadScanner->appendToEnd(source);
796 scanAndPreload(m_insertionPreloadScanner.get()); 813 scanAndPreload(m_insertionPreloadScanner.get());
797 } 814 }
798 815
799 endIfDelayed(); 816 endIfDelayed();
800 } 817 }
801 818
802 void HTMLDocumentParser::startBackgroundParser() { 819 void HTMLDocumentParser::startBackgroundParser() {
803 ASSERT(!isStopped()); 820 ASSERT(!isStopped());
804 ASSERT(shouldUseThreading()); 821 ASSERT(shouldUseThreading());
805 ASSERT(!m_backgroundParser); 822 ASSERT(!m_haveBackgroundParser);
806 ASSERT(document()); 823 ASSERT(document());
824 m_haveBackgroundParser = true;
807 825
808 // TODO(csharrison): Remove WebFrameScheduler::setDocumentParsingInBackground. 826 // TODO(alexclarke): Remove WebFrameScheduler::setDocumentParsingInBackground
827 // when background parser goes away.
809 if (document()->frame() && document()->frame()->frameScheduler()) 828 if (document()->frame() && document()->frame()->frameScheduler())
810 document()->frame()->frameScheduler()->setDocumentParsingInBackground(true); 829 document()->frame()->frameScheduler()->setDocumentParsingInBackground(true);
811 830
812 // Make sure that a resolver is set up, so that the correct viewport 831 // Make sure that a resolver is set up, so that the correct viewport
813 // dimensions will be fed to the background parser and preload scanner. 832 // dimensions will be fed to the background parser and preload scanner.
814 if (document()->loader()) 833 if (document()->loader())
815 document()->ensureStyleResolver(); 834 document()->ensureStyleResolver();
816 835
817 std::unique_ptr<BackgroundHTMLParser::Configuration> config = 836 std::unique_ptr<BackgroundHTMLParser::Configuration> config =
818 WTF::wrapUnique(new BackgroundHTMLParser::Configuration); 837 WTF::wrapUnique(new BackgroundHTMLParser::Configuration);
819 config->options = m_options; 838 config->options = m_options;
839 config->parser = m_weakFactory.createWeakPtr();
820 config->xssAuditor = WTF::wrapUnique(new XSSAuditor); 840 config->xssAuditor = WTF::wrapUnique(new XSSAuditor);
821 config->xssAuditor->init(document(), &m_xssAuditorDelegate); 841 config->xssAuditor->init(document(), &m_xssAuditorDelegate);
822 842
823 config->decoder = takeDecoder(); 843 config->decoder = takeDecoder();
844 config->tokenizedChunkQueue = m_tokenizedChunkQueue.get();
824 if (document()->settings()) { 845 if (document()->settings()) {
825 if (document() 846 if (document()
826 ->settings() 847 ->settings()
827 ->getBackgroundHtmlParserOutstandingTokenLimit()) { 848 ->getBackgroundHtmlParserOutstandingTokenLimit()) {
828 config->outstandingTokenLimit = 849 config->outstandingTokenLimit =
829 document() 850 document()
830 ->settings() 851 ->settings()
831 ->getBackgroundHtmlParserOutstandingTokenLimit(); 852 ->getBackgroundHtmlParserOutstandingTokenLimit();
832 } 853 }
833 if (document()->settings()->getBackgroundHtmlParserPendingTokenLimit()) { 854 if (document()->settings()->getBackgroundHtmlParserPendingTokenLimit()) {
834 config->pendingTokenLimit = 855 config->pendingTokenLimit =
835 document()->settings()->getBackgroundHtmlParserPendingTokenLimit(); 856 document()->settings()->getBackgroundHtmlParserPendingTokenLimit();
836 } 857 }
837 } 858 }
838 859
839 ASSERT(config->xssAuditor->isSafeToSendToAnotherThread()); 860 ASSERT(config->xssAuditor->isSafeToSendToAnotherThread());
840 861
862 // The background parser is created on the main thread, but may otherwise
863 // only be used from the parser thread.
841 m_backgroundParser = 864 m_backgroundParser =
842 BackgroundHTMLParser::create(this, *document(), std::move(config)); 865 BackgroundHTMLParser::create(std::move(config), m_loadingTaskRunner);
866 // TODO(csharrison): This is a hack to initialize MediaValuesCached on the
867 // correct thread. We should get rid of it.
868 m_backgroundParser->init(
869 document()->url(), CachedDocumentParameters::create(document()),
870 MediaValuesCached::MediaValuesCachedData(*document()));
871 }
872
873 void HTMLDocumentParser::stopBackgroundParser() {
874 ASSERT(shouldUseThreading());
875 ASSERT(m_haveBackgroundParser);
876
877 if (m_haveBackgroundParser && document()->frame() &&
878 document()->frame()->frameScheduler())
879 document()->frame()->frameScheduler()->setDocumentParsingInBackground(
880 false);
881
882 m_haveBackgroundParser = false;
883
884 // Make this sync, as lsan triggers on some unittests if the task runner is
885 // used.
886 m_backgroundParser->stop();
887 m_weakFactory.revokeAll();
843 } 888 }
844 889
845 void HTMLDocumentParser::append(const String& inputSource) { 890 void HTMLDocumentParser::append(const String& inputSource) {
846 if (isStopped()) 891 if (isStopped())
847 return; 892 return;
848 893
849 // We should never reach this point if we're using a parser thread, as 894 // We should never reach this point if we're using a parser thread, as
850 // appendBytes() will directly ship the data to the thread. 895 // appendBytes() will directly ship the data to the thread.
851 ASSERT(!shouldUseThreading()); 896 ASSERT(!shouldUseThreading());
852 897
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
889 934
890 pumpTokenizerIfPossible(); 935 pumpTokenizerIfPossible();
891 936
892 endIfDelayed(); 937 endIfDelayed();
893 } 938 }
894 939
895 void HTMLDocumentParser::end() { 940 void HTMLDocumentParser::end() {
896 ASSERT(!isDetached()); 941 ASSERT(!isDetached());
897 ASSERT(!isScheduledForResume()); 942 ASSERT(!isScheduledForResume());
898 943
899 m_backgroundParser.clear(); 944 if (m_haveBackgroundParser)
945 stopBackgroundParser();
900 946
901 // Informs the the rest of WebCore that parsing is really finished (and 947 // Informs the the rest of WebCore that parsing is really finished (and
902 // deletes this). 948 // deletes this).
903 m_treeBuilder->finished(); 949 m_treeBuilder->finished();
904 950
905 DocumentParser::stopParsing(); 951 DocumentParser::stopParsing();
906 } 952 }
907 953
908 void HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd() { 954 void HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd() {
909 ASSERT(isStopping()); 955 ASSERT(isStopping());
910 // FIXME: It may not be correct to disable this for the background parser. 956 // FIXME: It may not be correct to disable this for the background parser.
911 // That means hasInsertionPoint() may not be correct in some cases. 957 // That means hasInsertionPoint() may not be correct in some cases.
912 ASSERT(!hasInsertionPoint() || m_backgroundParser); 958 ASSERT(!hasInsertionPoint() || m_haveBackgroundParser);
913 if (m_scriptRunner && !m_scriptRunner->executeScriptsWaitingForParsing()) 959 if (m_scriptRunner && !m_scriptRunner->executeScriptsWaitingForParsing())
914 return; 960 return;
915 end(); 961 end();
916 } 962 }
917 963
918 void HTMLDocumentParser::attemptToEnd() { 964 void HTMLDocumentParser::attemptToEnd() {
919 // finish() indicates we will not receive any more data. If we are waiting on 965 // finish() indicates we will not receive any more data. If we are waiting on
920 // an external script to load, we can't finish parsing quite yet. 966 // an external script to load, we can't finish parsing quite yet.
921 967
922 if (shouldDelayEnd()) { 968 if (shouldDelayEnd()) {
(...skipping 20 matching lines...) Expand all
943 // sense to call any methods on DocumentParser once it's been stopped. 989 // sense to call any methods on DocumentParser once it's been stopped.
944 // However, FrameLoader::stop calls DocumentParser::finish unconditionally. 990 // However, FrameLoader::stop calls DocumentParser::finish unconditionally.
945 991
946 flush(); 992 flush();
947 if (isDetached()) 993 if (isDetached())
948 return; 994 return;
949 995
950 // Empty documents never got an append() call, and thus have never started a 996 // Empty documents never got an append() call, and thus have never started a
951 // background parser. In those cases, we ignore shouldUseThreading() and fall 997 // background parser. In those cases, we ignore shouldUseThreading() and fall
952 // through to the non-threading case. 998 // through to the non-threading case.
953 if (m_backgroundParser) { 999 if (m_haveBackgroundParser) {
954 if (!m_input.haveSeenEndOfFile()) 1000 if (!m_input.haveSeenEndOfFile())
955 m_input.closeWithoutMarkingEndOfFile(); 1001 m_input.closeWithoutMarkingEndOfFile();
956 m_backgroundParser->finish(); 1002 m_loadingTaskRunner->postTask(
1003 BLINK_FROM_HERE,
1004 WTF::bind(&BackgroundHTMLParser::finish, m_backgroundParser));
957 return; 1005 return;
958 } 1006 }
959 1007
960 if (!m_tokenizer) { 1008 if (!m_tokenizer) {
961 ASSERT(!m_token); 1009 ASSERT(!m_token);
962 // We're finishing before receiving any data. Rather than booting up the 1010 // We're finishing before receiving any data. Rather than booting up the
963 // background parser just to spin it down, we finish parsing synchronously. 1011 // background parser just to spin it down, we finish parsing synchronously.
964 m_token = WTF::wrapUnique(new HTMLToken); 1012 m_token = WTF::wrapUnique(new HTMLToken);
965 m_tokenizer = HTMLTokenizer::create(m_options); 1013 m_tokenizer = HTMLTokenizer::create(m_options);
966 } 1014 }
(...skipping 12 matching lines...) Expand all
979 return false; 1027 return false;
980 return m_scriptRunner->isExecutingScript(); 1028 return m_scriptRunner->isExecutingScript();
981 } 1029 }
982 1030
983 bool HTMLDocumentParser::isParsingAtLineNumber() const { 1031 bool HTMLDocumentParser::isParsingAtLineNumber() const {
984 return m_isParsingAtLineNumber && 1032 return m_isParsingAtLineNumber &&
985 ScriptableDocumentParser::isParsingAtLineNumber(); 1033 ScriptableDocumentParser::isParsingAtLineNumber();
986 } 1034 }
987 1035
988 OrdinalNumber HTMLDocumentParser::lineNumber() const { 1036 OrdinalNumber HTMLDocumentParser::lineNumber() const {
989 if (m_backgroundParser) 1037 if (m_haveBackgroundParser)
990 return m_textPosition.m_line; 1038 return m_textPosition.m_line;
991 1039
992 return m_input.current().currentLine(); 1040 return m_input.current().currentLine();
993 } 1041 }
994 1042
995 TextPosition HTMLDocumentParser::textPosition() const { 1043 TextPosition HTMLDocumentParser::textPosition() const {
996 if (m_backgroundParser) 1044 if (m_haveBackgroundParser)
997 return m_textPosition; 1045 return m_textPosition;
998 1046
999 const SegmentedString& currentString = m_input.current(); 1047 const SegmentedString& currentString = m_input.current();
1000 OrdinalNumber line = currentString.currentLine(); 1048 OrdinalNumber line = currentString.currentLine();
1001 OrdinalNumber column = currentString.currentColumn(); 1049 OrdinalNumber column = currentString.currentColumn();
1002 1050
1003 return TextPosition(line, column); 1051 return TextPosition(line, column);
1004 } 1052 }
1005 1053
1006 bool HTMLDocumentParser::isWaitingForScripts() const { 1054 bool HTMLDocumentParser::isWaitingForScripts() const {
(...skipping 16 matching lines...) Expand all
1023 } 1071 }
1024 1072
1025 void HTMLDocumentParser::resumeParsingAfterPause() { 1073 void HTMLDocumentParser::resumeParsingAfterPause() {
1026 ASSERT(!isExecutingScript()); 1074 ASSERT(!isExecutingScript());
1027 DCHECK(!isPaused()); 1075 DCHECK(!isPaused());
1028 1076
1029 checkIfBodyStylesheetAdded(); 1077 checkIfBodyStylesheetAdded();
1030 if (isPaused()) 1078 if (isPaused())
1031 return; 1079 return;
1032 1080
1033 if (m_backgroundParser) { 1081 if (m_haveBackgroundParser) {
1034 if (m_lastChunkBeforePause) { 1082 if (m_lastChunkBeforePause) {
1035 validateSpeculations(std::move(m_lastChunkBeforePause)); 1083 validateSpeculations(std::move(m_lastChunkBeforePause));
1036 DCHECK(!m_lastChunkBeforePause); 1084 DCHECK(!m_lastChunkBeforePause);
1037 pumpPendingSpeculations(); 1085 pumpPendingSpeculations();
1038 } 1086 }
1039 return; 1087 return;
1040 } 1088 }
1041 1089
1042 m_insertionPreloadScanner.reset(); 1090 m_insertionPreloadScanner.reset();
1043 if (m_tokenizer) { 1091 if (m_tokenizer) {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 if (m_parserScheduler) 1184 if (m_parserScheduler)
1137 m_parserScheduler->resume(); 1185 m_parserScheduler->resume();
1138 } 1186 }
1139 1187
1140 void HTMLDocumentParser::appendBytes(const char* data, size_t length) { 1188 void HTMLDocumentParser::appendBytes(const char* data, size_t length) {
1141 if (!length || isStopped()) 1189 if (!length || isStopped())
1142 return; 1190 return;
1143 1191
1144 if (shouldUseThreading()) { 1192 if (shouldUseThreading()) {
1145 double bytesReceivedTime = monotonicallyIncreasingTimeMS(); 1193 double bytesReceivedTime = monotonicallyIncreasingTimeMS();
1146 if (!m_backgroundParser) 1194 if (!m_haveBackgroundParser)
1147 startBackgroundParser(); 1195 startBackgroundParser();
1148 1196
1149 std::unique_ptr<Vector<char>> buffer = 1197 std::unique_ptr<Vector<char>> buffer =
1150 WTF::makeUnique<Vector<char>>(length); 1198 WTF::makeUnique<Vector<char>>(length);
1151 memcpy(buffer->data(), data, length); 1199 memcpy(buffer->data(), data, length);
1152 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.debug"), 1200 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.debug"),
1153 "HTMLDocumentParser::appendBytes", "size", (unsigned)length); 1201 "HTMLDocumentParser::appendBytes", "size", (unsigned)length);
1154 1202
1155 m_backgroundParser->appendRawBytesFromMainThread(std::move(buffer), 1203 m_loadingTaskRunner->postTask(
1156 bytesReceivedTime); 1204 BLINK_FROM_HERE,
1205 WTF::bind(&BackgroundHTMLParser::appendRawBytesFromMainThread,
1206 m_backgroundParser, WTF::passed(std::move(buffer)),
1207 bytesReceivedTime));
1157 return; 1208 return;
1158 } 1209 }
1159 1210
1160 DecodedDataDocumentParser::appendBytes(data, length); 1211 DecodedDataDocumentParser::appendBytes(data, length);
1161 } 1212 }
1162 1213
1163 void HTMLDocumentParser::flush() { 1214 void HTMLDocumentParser::flush() {
1164 // If we've got no decoder, we never received any data. 1215 // If we've got no decoder, we never received any data.
1165 if (isDetached() || needsDecoder()) 1216 if (isDetached() || needsDecoder())
1166 return; 1217 return;
1167 1218
1168 if (shouldUseThreading()) { 1219 if (shouldUseThreading()) {
1169 // In some cases, flush() is called without any invocation of appendBytes. 1220 // In some cases, flush() is called without any invocation of appendBytes.
1170 // Fallback to synchronous parsing in that case. 1221 // Fallback to synchronous parsing in that case.
1171 if (!m_backgroundParser) { 1222 if (!m_haveBackgroundParser) {
1172 m_shouldUseThreading = false; 1223 m_shouldUseThreading = false;
1173 m_token = WTF::wrapUnique(new HTMLToken); 1224 m_token = WTF::wrapUnique(new HTMLToken);
1174 m_tokenizer = HTMLTokenizer::create(m_options); 1225 m_tokenizer = HTMLTokenizer::create(m_options);
1175 DecodedDataDocumentParser::flush(); 1226 DecodedDataDocumentParser::flush();
1176 return; 1227 return;
1177 } 1228 }
1178 m_backgroundParser->flush(); 1229
1230 m_loadingTaskRunner->postTask(
1231 BLINK_FROM_HERE,
1232 WTF::bind(&BackgroundHTMLParser::flush, m_backgroundParser));
1179 } else { 1233 } else {
1180 DecodedDataDocumentParser::flush(); 1234 DecodedDataDocumentParser::flush();
1181 } 1235 }
1182 } 1236 }
1183 1237
1184 void HTMLDocumentParser::setDecoder( 1238 void HTMLDocumentParser::setDecoder(
1185 std::unique_ptr<TextResourceDecoder> decoder) { 1239 std::unique_ptr<TextResourceDecoder> decoder) {
1186 ASSERT(decoder); 1240 ASSERT(decoder);
1187 DecodedDataDocumentParser::setDecoder(std::move(decoder)); 1241 DecodedDataDocumentParser::setDecoder(std::move(decoder));
1188 1242
1189 if (m_backgroundParser) 1243 if (m_haveBackgroundParser) {
1190 m_backgroundParser->setDecoder(takeDecoder()); 1244 m_loadingTaskRunner->postTask(
1245 BLINK_FROM_HERE,
1246 WTF::bind(&BackgroundHTMLParser::setDecoder, m_backgroundParser,
1247 WTF::passed(takeDecoder())));
1248 }
1191 } 1249 }
1192 1250
1193 void HTMLDocumentParser::documentElementAvailable() { 1251 void HTMLDocumentParser::documentElementAvailable() {
1194 TRACE_EVENT0("blink,loader", "HTMLDocumentParser::documentElementAvailable"); 1252 TRACE_EVENT0("blink,loader", "HTMLDocumentParser::documentElementAvailable");
1195 DCHECK(document()->documentElement()); 1253 DCHECK(document()->documentElement());
1196 fetchQueuedPreloads(); 1254 fetchQueuedPreloads();
1197 } 1255 }
1198 1256
1199 std::unique_ptr<HTMLPreloadScanner> HTMLDocumentParser::createPreloadScanner() { 1257 std::unique_ptr<HTMLPreloadScanner> HTMLDocumentParser::createPreloadScanner() {
1200 return HTMLPreloadScanner::create( 1258 return HTMLPreloadScanner::create(
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1272 successHistogram.count(duration); 1330 successHistogram.count(duration);
1273 } else { 1331 } else {
1274 DEFINE_STATIC_LOCAL( 1332 DEFINE_STATIC_LOCAL(
1275 CustomCountHistogram, failureHistogram, 1333 CustomCountHistogram, failureHistogram,
1276 ("PreloadScanner.DocumentWrite.ExecutionTime.Failure", 1, 10000, 50)); 1334 ("PreloadScanner.DocumentWrite.ExecutionTime.Failure", 1, 10000, 50));
1277 failureHistogram.count(duration); 1335 failureHistogram.count(duration);
1278 } 1336 }
1279 } 1337 }
1280 1338
1281 } // namespace blink 1339 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698