Chromium Code Reviews| 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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 113 , m_reentryPermit(HTMLParserReentryPermit::create()) | 113 , m_reentryPermit(HTMLParserReentryPermit::create()) |
| 114 , m_token(syncPolicy == ForceSynchronousParsing ? wrapUnique(new HTMLToken) : nullptr) | 114 , m_token(syncPolicy == ForceSynchronousParsing ? wrapUnique(new HTMLToken) : nullptr) |
| 115 , m_tokenizer(syncPolicy == ForceSynchronousParsing ? HTMLTokenizer::create( m_options) : nullptr) | 115 , m_tokenizer(syncPolicy == ForceSynchronousParsing ? HTMLTokenizer::create( m_options) : nullptr) |
| 116 , m_loadingTaskRunner(TaskRunnerHelper::get(TaskType::Networking, &document) ->clone()) | 116 , m_loadingTaskRunner(TaskRunnerHelper::get(TaskType::Networking, &document) ->clone()) |
| 117 , m_parserScheduler(syncPolicy == AllowAsynchronousParsing ? HTMLParserSched uler::create(this, m_loadingTaskRunner.get()) : nullptr) | 117 , m_parserScheduler(syncPolicy == AllowAsynchronousParsing ? HTMLParserSched uler::create(this, m_loadingTaskRunner.get()) : nullptr) |
| 118 , m_xssAuditorDelegate(&document) | 118 , m_xssAuditorDelegate(&document) |
| 119 , m_weakFactory(this) | 119 , m_weakFactory(this) |
| 120 , m_preloader(HTMLResourcePreloader::create(document)) | 120 , m_preloader(HTMLResourcePreloader::create(document)) |
| 121 , m_tokenizedChunkQueue(TokenizedChunkQueue::create()) | 121 , m_tokenizedChunkQueue(TokenizedChunkQueue::create()) |
| 122 , m_evaluator(DocumentWriteEvaluator::create(document)) | 122 , m_evaluator(DocumentWriteEvaluator::create(document)) |
| 123 , m_pendingCSPMetaToken(nullptr) | |
| 123 , m_shouldUseThreading(syncPolicy == AllowAsynchronousParsing) | 124 , m_shouldUseThreading(syncPolicy == AllowAsynchronousParsing) |
| 124 , m_endWasDelayed(false) | 125 , m_endWasDelayed(false) |
| 125 , m_haveBackgroundParser(false) | 126 , m_haveBackgroundParser(false) |
| 126 , m_tasksWereSuspended(false) | 127 , m_tasksWereSuspended(false) |
| 127 , m_pumpSessionNestingLevel(0) | 128 , m_pumpSessionNestingLevel(0) |
| 128 , m_pumpSpeculationsSessionNestingLevel(0) | 129 , m_pumpSpeculationsSessionNestingLevel(0) |
| 129 , m_isParsingAtLineNumber(false) | 130 , m_isParsingAtLineNumber(false) |
| 130 , m_triedLoadingLinkHeaders(false) | 131 , m_triedLoadingLinkHeaders(false) |
| 131 { | 132 { |
| 132 ASSERT(shouldUseThreading() || (m_token && m_tokenizer)); | 133 ASSERT(shouldUseThreading() || (m_token && m_tokenizer)); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 307 // ApplicationCache is initialized. Note: link rel preloads don't follow | 308 // ApplicationCache is initialized. Note: link rel preloads don't follow |
| 308 // this policy per the spec. These directives should initiate a fetch as | 309 // this policy per the spec. These directives should initiate a fetch as |
| 309 // fast as possible. | 310 // fast as possible. |
| 310 if (!m_triedLoadingLinkHeaders && document()->loader() && !pendingChunks.isE mpty()) { | 311 if (!m_triedLoadingLinkHeaders && document()->loader() && !pendingChunks.isE mpty()) { |
| 311 // Note that on commit, the loader dispatched preloads for all the | 312 // Note that on commit, the loader dispatched preloads for all the |
| 312 // non-media links. | 313 // non-media links. |
| 313 document()->loader()->dispatchLinkHeaderPreloads(&pendingChunks.first()- >viewport, LinkLoader::OnlyLoadMedia); | 314 document()->loader()->dispatchLinkHeaderPreloads(&pendingChunks.first()- >viewport, LinkLoader::OnlyLoadMedia); |
| 314 m_triedLoadingLinkHeaders = true; | 315 m_triedLoadingLinkHeaders = true; |
| 315 } | 316 } |
| 316 | 317 |
| 317 if (!document()->documentElement()) { | 318 // Defer preloads if any of the chunks contains a <meta> csp tag. |
| 319 for (auto& chunk : pendingChunks) { | |
|
kouhei (in TOK)
2016/08/22 05:34:03
Can we skip this if(m_pendingCSPToken)? or do we n
Charlie Harrison
2016/08/22 14:08:05
I chose to be conservative in this patch and alway
| |
| 320 if (chunk->pendingCSPMetaTokenIndex.has_value()) { | |
| 321 m_pendingCSPMetaToken = &chunk->tokens->at(chunk->pendingCSPMetaToke nIndex.value()); | |
| 322 } | |
| 323 } | |
| 324 | |
| 325 if (m_pendingCSPMetaToken || !document()->documentElement()) { | |
| 318 PreloadRequestStream linkRelPreloads; | 326 PreloadRequestStream linkRelPreloads; |
| 319 for (auto& chunk : pendingChunks) { | 327 for (auto& chunk : pendingChunks) { |
| 320 for (auto& request : chunk->preloads) { | 328 for (auto& request : chunk->preloads) { |
| 321 if (request->isLinkRelPreload()) | 329 // Link rel preloads don't need to wait for AppCache but they |
| 330 // should probably wait for CSP. | |
| 331 if (!m_pendingCSPMetaToken && request->isLinkRelPreload()) | |
| 322 linkRelPreloads.append(std::move(request)); | 332 linkRelPreloads.append(std::move(request)); |
| 323 else | 333 else |
| 324 m_queuedPreloads.append(std::move(request)); | 334 m_queuedPreloads.append(std::move(request)); |
| 325 } | 335 } |
| 326 for (auto& index : chunk->likelyDocumentWriteScriptIndices) { | 336 for (auto& index : chunk->likelyDocumentWriteScriptIndices) { |
| 327 const CompactHTMLToken& token = chunk->tokens->at(index); | 337 const CompactHTMLToken& token = chunk->tokens->at(index); |
| 328 ASSERT(token.type() == HTMLToken::TokenType::Character); | 338 ASSERT(token.type() == HTMLToken::TokenType::Character); |
| 329 m_queuedDocumentWriteScripts.append(token.data()); | 339 m_queuedDocumentWriteScripts.append(token.data()); |
| 330 } | 340 } |
| 331 } | 341 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 412 m_weakFactory.revokeAll(); | 422 m_weakFactory.revokeAll(); |
| 413 | 423 |
| 414 size_t discardedTokenCount = 0; | 424 size_t discardedTokenCount = 0; |
| 415 for (const auto& speculation : m_speculations) { | 425 for (const auto& speculation : m_speculations) { |
| 416 discardedTokenCount += speculation->tokens->size(); | 426 discardedTokenCount += speculation->tokens->size(); |
| 417 } | 427 } |
| 418 DEFINE_STATIC_LOCAL(CustomCountHistogram, discardedTokenCountHistogram, ("Pa rser.DiscardedTokenCount", 1, 100000, 50)); | 428 DEFINE_STATIC_LOCAL(CustomCountHistogram, discardedTokenCountHistogram, ("Pa rser.DiscardedTokenCount", 1, 100000, 50)); |
| 419 discardedTokenCountHistogram.count(discardedTokenCount); | 429 discardedTokenCountHistogram.count(discardedTokenCount); |
| 420 | 430 |
| 421 m_speculations.clear(); | 431 m_speculations.clear(); |
| 432 m_pendingCSPMetaToken = nullptr; | |
| 433 m_queuedPreloads.clear(); | |
| 422 | 434 |
| 423 std::unique_ptr<BackgroundHTMLParser::Checkpoint> checkpoint = wrapUnique(ne w BackgroundHTMLParser::Checkpoint); | 435 std::unique_ptr<BackgroundHTMLParser::Checkpoint> checkpoint = wrapUnique(ne w BackgroundHTMLParser::Checkpoint); |
| 424 checkpoint->parser = m_weakFactory.createWeakPtr(); | 436 checkpoint->parser = m_weakFactory.createWeakPtr(); |
| 425 checkpoint->token = std::move(token); | 437 checkpoint->token = std::move(token); |
| 426 checkpoint->tokenizer = std::move(tokenizer); | 438 checkpoint->tokenizer = std::move(tokenizer); |
| 427 checkpoint->treeBuilderState = HTMLTreeBuilderSimulator::stateFor(m_treeBuil der.get()); | 439 checkpoint->treeBuilderState = HTMLTreeBuilderSimulator::stateFor(m_treeBuil der.get()); |
| 428 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint; | 440 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint; |
| 429 checkpoint->preloadScannerCheckpoint = lastChunkBeforeScript->preloadScanner Checkpoint; | 441 checkpoint->preloadScannerCheckpoint = lastChunkBeforeScript->preloadScanner Checkpoint; |
| 430 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy(); | 442 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy(); |
| 431 m_input.current().clear(); // FIXME: This should be passed in instead of cle ared. | 443 m_input.current().clear(); // FIXME: This should be passed in instead of cle ared. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 482 break; | 494 break; |
| 483 } | 495 } |
| 484 | 496 |
| 485 m_textPosition = it->textPosition(); | 497 m_textPosition = it->textPosition(); |
| 486 | 498 |
| 487 constructTreeFromCompactHTMLToken(*it); | 499 constructTreeFromCompactHTMLToken(*it); |
| 488 | 500 |
| 489 if (isStopped()) | 501 if (isStopped()) |
| 490 break; | 502 break; |
| 491 | 503 |
| 504 // Preloads were queued if there was a <meta> csp token in a tokenized | |
| 505 // chunk. | |
| 506 if (m_pendingCSPMetaToken && it == m_pendingCSPMetaToken) { | |
| 507 m_pendingCSPMetaToken = nullptr; | |
| 508 fetchQueuedPreloads(); | |
| 509 } | |
| 510 | |
| 492 if (isWaitingForScripts()) { | 511 if (isWaitingForScripts()) { |
| 493 ASSERT(it + 1 == tokens->end()); // The </script> is assumed to be t he last token of this bunch. | 512 ASSERT(it + 1 == tokens->end()); // The </script> is assumed to be t he last token of this bunch. |
| 494 runScriptsForPausedTreeBuilder(); | 513 runScriptsForPausedTreeBuilder(); |
| 495 validateSpeculations(std::move(chunk)); | 514 validateSpeculations(std::move(chunk)); |
| 496 break; | 515 break; |
| 497 } | 516 } |
| 498 | 517 |
| 499 if (it->type() == HTMLToken::EndOfFile) { | 518 if (it->type() == HTMLToken::EndOfFile) { |
| 500 ASSERT(it + 1 == tokens->end()); // The EOF is assumed to be the las t token of this bunch. | 519 ASSERT(it + 1 == tokens->end()); // The EOF is assumed to be the las t token of this bunch. |
| 501 ASSERT(m_speculations.isEmpty()); // There should never be any chunk s after the EOF. | 520 ASSERT(m_speculations.isEmpty()); // There should never be any chunk s after the EOF. |
| (...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1092 DecodedDataDocumentParser::setDecoder(std::move(decoder)); | 1111 DecodedDataDocumentParser::setDecoder(std::move(decoder)); |
| 1093 | 1112 |
| 1094 if (m_haveBackgroundParser) | 1113 if (m_haveBackgroundParser) |
| 1095 postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::setDecode r, m_backgroundParser, passed(takeDecoder())); | 1114 postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::setDecode r, m_backgroundParser, passed(takeDecoder())); |
| 1096 } | 1115 } |
| 1097 | 1116 |
| 1098 void HTMLDocumentParser::documentElementAvailable() | 1117 void HTMLDocumentParser::documentElementAvailable() |
| 1099 { | 1118 { |
| 1100 TRACE_EVENT0("blink,loader", "HTMLDocumentParser::documentElementAvailable") ; | 1119 TRACE_EVENT0("blink,loader", "HTMLDocumentParser::documentElementAvailable") ; |
| 1101 DCHECK(document()->documentElement()); | 1120 DCHECK(document()->documentElement()); |
| 1102 if (!m_queuedPreloads.isEmpty()) | 1121 fetchQueuedPreloads(); |
| 1103 m_preloader->takeAndPreload(m_queuedPreloads); | |
| 1104 | |
| 1105 for (const String& scriptSource : m_queuedDocumentWriteScripts) { | |
| 1106 evaluateAndPreloadScriptForDocumentWrite(scriptSource); | |
| 1107 } | |
| 1108 | |
| 1109 m_queuedDocumentWriteScripts.clear(); | |
| 1110 } | 1122 } |
| 1111 | 1123 |
| 1112 std::unique_ptr<HTMLPreloadScanner> HTMLDocumentParser::createPreloadScanner() | 1124 std::unique_ptr<HTMLPreloadScanner> HTMLDocumentParser::createPreloadScanner() |
| 1113 { | 1125 { |
| 1114 return HTMLPreloadScanner::create( | 1126 return HTMLPreloadScanner::create( |
| 1115 m_options, | 1127 m_options, |
| 1116 document()->url(), | 1128 document()->url(), |
| 1117 CachedDocumentParameters::create(document()), | 1129 CachedDocumentParameters::create(document()), |
| 1118 MediaValuesCached::MediaValuesCachedData(*document())); | 1130 MediaValuesCached::MediaValuesCachedData(*document())); |
| 1119 } | 1131 } |
| 1120 | 1132 |
| 1133 void HTMLDocumentParser::fetchQueuedPreloads() | |
| 1134 { | |
| 1135 if (m_pendingCSPMetaToken || !document()->documentElement()) | |
| 1136 return; | |
| 1137 | |
| 1138 if (!m_queuedPreloads.isEmpty()) | |
| 1139 m_preloader->takeAndPreload(m_queuedPreloads); | |
| 1140 | |
| 1141 for (const String& scriptSource : m_queuedDocumentWriteScripts) { | |
| 1142 evaluateAndPreloadScriptForDocumentWrite(scriptSource); | |
| 1143 } | |
| 1144 | |
| 1145 m_queuedDocumentWriteScripts.clear(); | |
| 1146 } | |
| 1147 | |
| 1121 void HTMLDocumentParser::evaluateAndPreloadScriptForDocumentWrite(const String& source) | 1148 void HTMLDocumentParser::evaluateAndPreloadScriptForDocumentWrite(const String& source) |
| 1122 { | 1149 { |
| 1123 if (!m_evaluator->shouldEvaluate(source)) | 1150 if (!m_evaluator->shouldEvaluate(source)) |
| 1124 return; | 1151 return; |
| 1125 document()->loader()->didObserveLoadingBehavior(WebLoadingBehaviorFlag::WebL oadingBehaviorDocumentWriteEvaluator); | 1152 document()->loader()->didObserveLoadingBehavior(WebLoadingBehaviorFlag::WebL oadingBehaviorDocumentWriteEvaluator); |
| 1126 if (!RuntimeEnabledFeatures::documentWriteEvaluatorEnabled()) | 1153 if (!RuntimeEnabledFeatures::documentWriteEvaluatorEnabled()) |
| 1127 return; | 1154 return; |
| 1128 TRACE_EVENT0("blink", "HTMLDocumentParser::evaluateAndPreloadScriptForDocume ntWrite"); | 1155 TRACE_EVENT0("blink", "HTMLDocumentParser::evaluateAndPreloadScriptForDocume ntWrite"); |
| 1129 | 1156 |
| 1130 double initializeStartTime = monotonicallyIncreasingTimeMS(); | 1157 double initializeStartTime = monotonicallyIncreasingTimeMS(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1172 (*WTF::bind(function, std::forward<Ps>(parameters)...))(); | 1199 (*WTF::bind(function, std::forward<Ps>(parameters)...))(); |
| 1173 return; | 1200 return; |
| 1174 case Asynchronous: | 1201 case Asynchronous: |
| 1175 m_loadingTaskRunner->postTask(BLINK_FROM_HERE, WTF::bind(function, std:: forward<Ps>(parameters)...)); | 1202 m_loadingTaskRunner->postTask(BLINK_FROM_HERE, WTF::bind(function, std:: forward<Ps>(parameters)...)); |
| 1176 return; | 1203 return; |
| 1177 } | 1204 } |
| 1178 NOTREACHED(); | 1205 NOTREACHED(); |
| 1179 } | 1206 } |
| 1180 | 1207 |
| 1181 } // namespace blink | 1208 } // namespace blink |
| OLD | NEW |