| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |