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

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

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

Powered by Google App Engine
This is Rietveld 408576698