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

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

Issue 2666993006: Enable ParseHTMLOnMainThread on TOT (Closed)
Patch Set: clean up virtual test suites 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
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 checkpoint->treeBuilderState = 474 checkpoint->treeBuilderState =
475 HTMLTreeBuilderSimulator::stateFor(m_treeBuilder.get()); 475 HTMLTreeBuilderSimulator::stateFor(m_treeBuilder.get());
476 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint; 476 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint;
477 checkpoint->preloadScannerCheckpoint = 477 checkpoint->preloadScannerCheckpoint =
478 lastChunkBeforeScript->preloadScannerCheckpoint; 478 lastChunkBeforeScript->preloadScannerCheckpoint;
479 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy(); 479 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy();
480 // FIXME: This should be passed in instead of cleared. 480 // FIXME: This should be passed in instead of cleared.
481 m_input.current().clear(); 481 m_input.current().clear();
482 482
483 ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread()); 483 ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread());
484 postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::resumeFrom, 484 m_loadingTaskRunner->postTask(
485 m_backgroundParser, 485 BLINK_FROM_HERE,
486 WTF::passed(std::move(checkpoint))); 486 WTF::bind(&BackgroundHTMLParser::resumeFrom, m_backgroundParser,
487 WTF::passed(std::move(checkpoint))));
487 } 488 }
488 489
489 size_t HTMLDocumentParser::processTokenizedChunkFromBackgroundParser( 490 size_t HTMLDocumentParser::processTokenizedChunkFromBackgroundParser(
490 std::unique_ptr<TokenizedChunk> popChunk) { 491 std::unique_ptr<TokenizedChunk> popChunk) {
491 TRACE_EVENT_WITH_FLOW0( 492 TRACE_EVENT_WITH_FLOW0(
492 "blink,loading", 493 "blink,loading",
493 "HTMLDocumentParser::processTokenizedChunkFromBackgroundParser", 494 "HTMLDocumentParser::processTokenizedChunkFromBackgroundParser",
494 popChunk.get(), TRACE_EVENT_FLAG_FLOW_IN); 495 popChunk.get(), TRACE_EVENT_FLAG_FLOW_IN);
495 AutoReset<bool> hasLineNumber(&m_isParsingAtLineNumber, true); 496 AutoReset<bool> hasLineNumber(&m_isParsingAtLineNumber, true);
496 497
497 SECURITY_DCHECK(m_pumpSpeculationsSessionNestingLevel == 1); 498 SECURITY_DCHECK(m_pumpSpeculationsSessionNestingLevel == 1);
498 SECURITY_DCHECK(!inPumpSession()); 499 SECURITY_DCHECK(!inPumpSession());
499 ASSERT(!isParsingFragment()); 500 ASSERT(!isParsingFragment());
500 DCHECK(!isPaused()); 501 DCHECK(!isPaused());
501 ASSERT(!isStopped()); 502 ASSERT(!isStopped());
502 ASSERT(shouldUseThreading()); 503 ASSERT(shouldUseThreading());
503 ASSERT(!m_tokenizer); 504 ASSERT(!m_tokenizer);
504 ASSERT(!m_token); 505 ASSERT(!m_token);
505 DCHECK(!m_lastChunkBeforePause); 506 DCHECK(!m_lastChunkBeforePause);
506 507
507 std::unique_ptr<TokenizedChunk> chunk(std::move(popChunk)); 508 std::unique_ptr<TokenizedChunk> chunk(std::move(popChunk));
508 std::unique_ptr<CompactHTMLTokenStream> tokens = std::move(chunk->tokens); 509 std::unique_ptr<CompactHTMLTokenStream> tokens = std::move(chunk->tokens);
509 size_t elementTokenCount = 0; 510 size_t elementTokenCount = 0;
510 511
511 postTaskToLookaheadParser(Asynchronous, 512 m_loadingTaskRunner->postTask(
512 &BackgroundHTMLParser::startedChunkWithCheckpoint, 513 BLINK_FROM_HERE,
513 m_backgroundParser, chunk->inputCheckpoint); 514 WTF::bind(&BackgroundHTMLParser::startedChunkWithCheckpoint,
515 m_backgroundParser, chunk->inputCheckpoint));
514 516
515 for (const auto& xssInfo : chunk->xssInfos) { 517 for (const auto& xssInfo : chunk->xssInfos) {
516 m_textPosition = xssInfo->m_textPosition; 518 m_textPosition = xssInfo->m_textPosition;
517 m_xssAuditorDelegate.didBlockScript(*xssInfo); 519 m_xssAuditorDelegate.didBlockScript(*xssInfo);
518 if (isStopped()) 520 if (isStopped())
519 break; 521 break;
520 } 522 }
521 // XSSAuditorDelegate can detach the parser if it decides to block the entire 523 // XSSAuditorDelegate can detach the parser if it decides to block the entire
522 // current document. 524 // current document.
523 if (isDetached()) 525 if (isDetached())
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 653
652 void HTMLDocumentParser::forcePlaintextForTextDocument() { 654 void HTMLDocumentParser::forcePlaintextForTextDocument() {
653 if (shouldUseThreading()) { 655 if (shouldUseThreading()) {
654 // This method is called before any data is appended, so we have to start 656 // This method is called before any data is appended, so we have to start
655 // the background parser ourselves. 657 // the background parser ourselves.
656 if (!m_haveBackgroundParser) 658 if (!m_haveBackgroundParser)
657 startBackgroundParser(); 659 startBackgroundParser();
658 660
659 // This task should be synchronous, because otherwise synchronous 661 // This task should be synchronous, because otherwise synchronous
660 // tokenizing can happen before plaintext is forced. 662 // tokenizing can happen before plaintext is forced.
661 postTaskToLookaheadParser( 663 m_backgroundParser->forcePlaintextForTextDocument();
662 Synchronous, &BackgroundHTMLParser::forcePlaintextForTextDocument,
663 m_backgroundParser);
664 } else 664 } else
665 m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState); 665 m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState);
666 } 666 }
667 667
668 void HTMLDocumentParser::pumpTokenizer() { 668 void HTMLDocumentParser::pumpTokenizer() {
669 ASSERT(!isStopped()); 669 ASSERT(!isStopped());
670 ASSERT(m_tokenizer); 670 ASSERT(m_tokenizer);
671 ASSERT(m_token); 671 ASSERT(m_token);
672 672
673 PumpSession session(m_pumpSessionNestingLevel); 673 PumpSession session(m_pumpSessionNestingLevel);
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 ->getBackgroundHtmlParserOutstandingTokenLimit()) { 849 ->getBackgroundHtmlParserOutstandingTokenLimit()) {
850 config->outstandingTokenLimit = 850 config->outstandingTokenLimit =
851 document() 851 document()
852 ->settings() 852 ->settings()
853 ->getBackgroundHtmlParserOutstandingTokenLimit(); 853 ->getBackgroundHtmlParserOutstandingTokenLimit();
854 } 854 }
855 if (document()->settings()->getBackgroundHtmlParserPendingTokenLimit()) { 855 if (document()->settings()->getBackgroundHtmlParserPendingTokenLimit()) {
856 config->pendingTokenLimit = 856 config->pendingTokenLimit =
857 document()->settings()->getBackgroundHtmlParserPendingTokenLimit(); 857 document()->settings()->getBackgroundHtmlParserPendingTokenLimit();
858 } 858 }
859 config->shouldCoalesceChunks =
860 document()->settings()->getParseHTMLOnMainThreadCoalesceChunks();
861 } 859 }
862 860
863 ASSERT(config->xssAuditor->isSafeToSendToAnotherThread()); 861 ASSERT(config->xssAuditor->isSafeToSendToAnotherThread());
864 862
865 // The background parser is created on the main thread, but may otherwise 863 // The background parser is created on the main thread, but may otherwise
866 // only be used from the parser thread. 864 // only be used from the parser thread.
867 m_backgroundParser = 865 m_backgroundParser =
868 BackgroundHTMLParser::create(std::move(config), m_loadingTaskRunner); 866 BackgroundHTMLParser::create(std::move(config), m_loadingTaskRunner);
869 // TODO(csharrison): This is a hack to initialize MediaValuesCached on the 867 // TODO(csharrison): This is a hack to initialize MediaValuesCached on the
870 // correct thread. We should get rid of it. 868 // correct thread. We should get rid of it.
871 postTaskToLookaheadParser( 869 m_backgroundParser->init(
872 Synchronous, &BackgroundHTMLParser::init, m_backgroundParser, 870 document()->url(), CachedDocumentParameters::create(document()),
873 document()->url(),
874 WTF::passed(CachedDocumentParameters::create(document())),
875 MediaValuesCached::MediaValuesCachedData(*document())); 871 MediaValuesCached::MediaValuesCachedData(*document()));
876 } 872 }
877 873
878 void HTMLDocumentParser::stopBackgroundParser() { 874 void HTMLDocumentParser::stopBackgroundParser() {
879 ASSERT(shouldUseThreading()); 875 ASSERT(shouldUseThreading());
880 ASSERT(m_haveBackgroundParser); 876 ASSERT(m_haveBackgroundParser);
881 877
882 if (m_haveBackgroundParser && document()->frame() && 878 if (m_haveBackgroundParser && document()->frame() &&
883 document()->frame()->frameScheduler()) 879 document()->frame()->frameScheduler())
884 document()->frame()->frameScheduler()->setDocumentParsingInBackground( 880 document()->frame()->frameScheduler()->setDocumentParsingInBackground(
885 false); 881 false);
886 882
887 m_haveBackgroundParser = false; 883 m_haveBackgroundParser = false;
888 884
889 // Make this sync, as lsan triggers on some unittests if the task runner is 885 // Make this sync, as lsan triggers on some unittests if the task runner is
890 // used. Note that these lifetimes will be much more concrete if 886 // used.
891 // ParseHTMLOnMainThread lands (the lookahead parser will be a member). 887 m_backgroundParser->stop();
892 postTaskToLookaheadParser(Synchronous, &BackgroundHTMLParser::stop,
893 m_backgroundParser);
894 m_weakFactory.revokeAll(); 888 m_weakFactory.revokeAll();
895 } 889 }
896 890
897 void HTMLDocumentParser::append(const String& inputSource) { 891 void HTMLDocumentParser::append(const String& inputSource) {
898 if (isStopped()) 892 if (isStopped())
899 return; 893 return;
900 894
901 // We should never reach this point if we're using a parser thread, as 895 // We should never reach this point if we're using a parser thread, as
902 // appendBytes() will directly ship the data to the thread. 896 // appendBytes() will directly ship the data to the thread.
903 ASSERT(!shouldUseThreading()); 897 ASSERT(!shouldUseThreading());
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 flush(); 993 flush();
1000 if (isDetached()) 994 if (isDetached())
1001 return; 995 return;
1002 996
1003 // Empty documents never got an append() call, and thus have never started a 997 // Empty documents never got an append() call, and thus have never started a
1004 // background parser. In those cases, we ignore shouldUseThreading() and fall 998 // background parser. In those cases, we ignore shouldUseThreading() and fall
1005 // through to the non-threading case. 999 // through to the non-threading case.
1006 if (m_haveBackgroundParser) { 1000 if (m_haveBackgroundParser) {
1007 if (!m_input.haveSeenEndOfFile()) 1001 if (!m_input.haveSeenEndOfFile())
1008 m_input.closeWithoutMarkingEndOfFile(); 1002 m_input.closeWithoutMarkingEndOfFile();
1009 postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::finish, 1003 m_loadingTaskRunner->postTask(
1010 m_backgroundParser); 1004 BLINK_FROM_HERE,
1005 WTF::bind(&BackgroundHTMLParser::finish, m_backgroundParser));
1011 return; 1006 return;
1012 } 1007 }
1013 1008
1014 if (!m_tokenizer) { 1009 if (!m_tokenizer) {
1015 ASSERT(!m_token); 1010 ASSERT(!m_token);
1016 // We're finishing before receiving any data. Rather than booting up the 1011 // We're finishing before receiving any data. Rather than booting up the
1017 // background parser just to spin it down, we finish parsing synchronously. 1012 // background parser just to spin it down, we finish parsing synchronously.
1018 m_token = WTF::wrapUnique(new HTMLToken); 1013 m_token = WTF::wrapUnique(new HTMLToken);
1019 m_tokenizer = HTMLTokenizer::create(m_options); 1014 m_tokenizer = HTMLTokenizer::create(m_options);
1020 } 1015 }
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1199 double bytesReceivedTime = monotonicallyIncreasingTimeMS(); 1194 double bytesReceivedTime = monotonicallyIncreasingTimeMS();
1200 if (!m_haveBackgroundParser) 1195 if (!m_haveBackgroundParser)
1201 startBackgroundParser(); 1196 startBackgroundParser();
1202 1197
1203 std::unique_ptr<Vector<char>> buffer = 1198 std::unique_ptr<Vector<char>> buffer =
1204 WTF::makeUnique<Vector<char>>(length); 1199 WTF::makeUnique<Vector<char>>(length);
1205 memcpy(buffer->data(), data, length); 1200 memcpy(buffer->data(), data, length);
1206 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.debug"), 1201 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.debug"),
1207 "HTMLDocumentParser::appendBytes", "size", (unsigned)length); 1202 "HTMLDocumentParser::appendBytes", "size", (unsigned)length);
1208 1203
1209 LookaheadParserTaskSynchrony policy = 1204 m_loadingTaskRunner->postTask(
1210 document()->settings() && 1205 BLINK_FROM_HERE,
1211 document()->settings()->getParseHTMLOnMainThreadSyncTokenize() 1206 WTF::bind(&BackgroundHTMLParser::appendRawBytesFromMainThread,
1212 ? Synchronous 1207 m_backgroundParser, WTF::passed(std::move(buffer)),
1213 : Asynchronous; 1208 bytesReceivedTime));
1214 postTaskToLookaheadParser(
1215 policy, &BackgroundHTMLParser::appendRawBytesFromMainThread,
1216 m_backgroundParser, WTF::passed(std::move(buffer)), bytesReceivedTime);
1217 return; 1209 return;
1218 } 1210 }
1219 1211
1220 DecodedDataDocumentParser::appendBytes(data, length); 1212 DecodedDataDocumentParser::appendBytes(data, length);
1221 } 1213 }
1222 1214
1223 void HTMLDocumentParser::flush() { 1215 void HTMLDocumentParser::flush() {
1224 // If we've got no decoder, we never received any data. 1216 // If we've got no decoder, we never received any data.
1225 if (isDetached() || needsDecoder()) 1217 if (isDetached() || needsDecoder())
1226 return; 1218 return;
1227 1219
1228 if (shouldUseThreading()) { 1220 if (shouldUseThreading()) {
1229 // In some cases, flush() is called without any invocation of appendBytes. 1221 // In some cases, flush() is called without any invocation of appendBytes.
1230 // Fallback to synchronous parsing in that case. 1222 // Fallback to synchronous parsing in that case.
1231 if (!m_haveBackgroundParser) { 1223 if (!m_haveBackgroundParser) {
1232 m_shouldUseThreading = false; 1224 m_shouldUseThreading = false;
1233 m_token = WTF::wrapUnique(new HTMLToken); 1225 m_token = WTF::wrapUnique(new HTMLToken);
1234 m_tokenizer = HTMLTokenizer::create(m_options); 1226 m_tokenizer = HTMLTokenizer::create(m_options);
1235 DecodedDataDocumentParser::flush(); 1227 DecodedDataDocumentParser::flush();
1236 return; 1228 return;
1237 } 1229 }
1238 1230
1239 postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::flush, 1231 m_loadingTaskRunner->postTask(
1240 m_backgroundParser); 1232 BLINK_FROM_HERE,
1233 WTF::bind(&BackgroundHTMLParser::flush, m_backgroundParser));
1241 } else { 1234 } else {
1242 DecodedDataDocumentParser::flush(); 1235 DecodedDataDocumentParser::flush();
1243 } 1236 }
1244 } 1237 }
1245 1238
1246 void HTMLDocumentParser::setDecoder( 1239 void HTMLDocumentParser::setDecoder(
1247 std::unique_ptr<TextResourceDecoder> decoder) { 1240 std::unique_ptr<TextResourceDecoder> decoder) {
1248 ASSERT(decoder); 1241 ASSERT(decoder);
1249 DecodedDataDocumentParser::setDecoder(std::move(decoder)); 1242 DecodedDataDocumentParser::setDecoder(std::move(decoder));
1250 1243
1251 if (m_haveBackgroundParser) { 1244 if (m_haveBackgroundParser) {
1252 postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::setDecoder, 1245 m_loadingTaskRunner->postTask(
1253 m_backgroundParser, WTF::passed(takeDecoder())); 1246 BLINK_FROM_HERE,
1247 WTF::bind(&BackgroundHTMLParser::setDecoder, m_backgroundParser,
1248 WTF::passed(takeDecoder())));
1254 } 1249 }
1255 } 1250 }
1256 1251
1257 void HTMLDocumentParser::documentElementAvailable() { 1252 void HTMLDocumentParser::documentElementAvailable() {
1258 TRACE_EVENT0("blink,loader", "HTMLDocumentParser::documentElementAvailable"); 1253 TRACE_EVENT0("blink,loader", "HTMLDocumentParser::documentElementAvailable");
1259 DCHECK(document()->documentElement()); 1254 DCHECK(document()->documentElement());
1260 fetchQueuedPreloads(); 1255 fetchQueuedPreloads();
1261 } 1256 }
1262 1257
1263 std::unique_ptr<HTMLPreloadScanner> HTMLDocumentParser::createPreloadScanner() { 1258 std::unique_ptr<HTMLPreloadScanner> HTMLDocumentParser::createPreloadScanner() {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 ("PreloadScanner.DocumentWrite.ExecutionTime.Success", 1, 10000, 50)); 1330 ("PreloadScanner.DocumentWrite.ExecutionTime.Success", 1, 10000, 50));
1336 successHistogram.count(duration); 1331 successHistogram.count(duration);
1337 } else { 1332 } else {
1338 DEFINE_STATIC_LOCAL( 1333 DEFINE_STATIC_LOCAL(
1339 CustomCountHistogram, failureHistogram, 1334 CustomCountHistogram, failureHistogram,
1340 ("PreloadScanner.DocumentWrite.ExecutionTime.Failure", 1, 10000, 50)); 1335 ("PreloadScanner.DocumentWrite.ExecutionTime.Failure", 1, 10000, 50));
1341 failureHistogram.count(duration); 1336 failureHistogram.count(duration);
1342 } 1337 }
1343 } 1338 }
1344 1339
1345 template <typename FunctionType, typename... Ps>
1346 void HTMLDocumentParser::postTaskToLookaheadParser(
1347 LookaheadParserTaskSynchrony synchronyPolicy,
1348 FunctionType function,
1349 Ps&&... parameters) {
1350 if (!RuntimeEnabledFeatures::parseHTMLOnMainThreadEnabled()) {
1351 HTMLParserThread::shared()->postTask(
1352 crossThreadBind(function, std::forward<Ps>(parameters)...));
1353 return;
1354 }
1355
1356 // Some messages to the lookahead parser should be synchronous. Otherwise,
1357 // just post to the loading task runner.
1358 switch (synchronyPolicy) {
1359 case Synchronous:
1360 (*WTF::bind(function, std::forward<Ps>(parameters)...))();
1361 return;
1362 case Asynchronous:
1363 m_loadingTaskRunner->postTask(
1364 BLINK_FROM_HERE,
1365 WTF::bind(function, std::forward<Ps>(parameters)...));
1366 return;
1367 }
1368 NOTREACHED();
1369 }
1370
1371 } // namespace blink 1340 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698