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

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

Issue 2242223003: Preload tokens even if a <meta> csp tag is found (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added another layout test. Use index into |tokens| in TokenizedChunk Created 4 years, 4 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
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698