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

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

Issue 2134323002: Remove threading primitives from ParseHTMLOnMainThread (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove crossThreadBind from BackgroundHTMLParser Created 4 years, 5 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 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 checkpoint->parser = m_weakFactory.createWeakPtr(); 396 checkpoint->parser = m_weakFactory.createWeakPtr();
397 checkpoint->token = std::move(token); 397 checkpoint->token = std::move(token);
398 checkpoint->tokenizer = std::move(tokenizer); 398 checkpoint->tokenizer = std::move(tokenizer);
399 checkpoint->treeBuilderState = HTMLTreeBuilderSimulator::stateFor(m_treeBuil der.get()); 399 checkpoint->treeBuilderState = HTMLTreeBuilderSimulator::stateFor(m_treeBuil der.get());
400 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint; 400 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint;
401 checkpoint->preloadScannerCheckpoint = lastChunkBeforeScript->preloadScanner Checkpoint; 401 checkpoint->preloadScannerCheckpoint = lastChunkBeforeScript->preloadScanner Checkpoint;
402 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy(); 402 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy();
403 m_input.current().clear(); // FIXME: This should be passed in instead of cle ared. 403 m_input.current().clear(); // FIXME: This should be passed in instead of cle ared.
404 404
405 ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread()); 405 ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread());
406 postTaskToLookaheadParser(crossThreadBind(&BackgroundHTMLParser::resumeFrom, m_backgroundParser, passed(std::move(checkpoint)))); 406 postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::resumeFrom, m _backgroundParser, passed(std::move(checkpoint)));
407 } 407 }
408 408
409 size_t HTMLDocumentParser::processParsedChunkFromBackgroundParser(std::unique_pt r<ParsedChunk> popChunk) 409 size_t HTMLDocumentParser::processParsedChunkFromBackgroundParser(std::unique_pt r<ParsedChunk> popChunk)
410 { 410 {
411 TRACE_EVENT_WITH_FLOW0("blink,loading", "HTMLDocumentParser::processParsedCh unkFromBackgroundParser", popChunk.get(), TRACE_EVENT_FLAG_FLOW_IN); 411 TRACE_EVENT_WITH_FLOW0("blink,loading", "HTMLDocumentParser::processParsedCh unkFromBackgroundParser", popChunk.get(), TRACE_EVENT_FLAG_FLOW_IN);
412 TemporaryChange<bool> hasLineNumber(m_isParsingAtLineNumber, true); 412 TemporaryChange<bool> hasLineNumber(m_isParsingAtLineNumber, true);
413 413
414 ASSERT_WITH_SECURITY_IMPLICATION(m_pumpSpeculationsSessionNestingLevel == 1) ; 414 ASSERT_WITH_SECURITY_IMPLICATION(m_pumpSpeculationsSessionNestingLevel == 1) ;
415 ASSERT_WITH_SECURITY_IMPLICATION(!inPumpSession()); 415 ASSERT_WITH_SECURITY_IMPLICATION(!inPumpSession());
416 ASSERT(!isParsingFragment()); 416 ASSERT(!isParsingFragment());
417 ASSERT(!isWaitingForScripts()); 417 ASSERT(!isWaitingForScripts());
418 ASSERT(!isStopped()); 418 ASSERT(!isStopped());
419 ASSERT(shouldUseThreading()); 419 ASSERT(shouldUseThreading());
420 ASSERT(!m_tokenizer); 420 ASSERT(!m_tokenizer);
421 ASSERT(!m_token); 421 ASSERT(!m_token);
422 ASSERT(!m_lastChunkBeforeScript); 422 ASSERT(!m_lastChunkBeforeScript);
423 423
424 std::unique_ptr<ParsedChunk> chunk(std::move(popChunk)); 424 std::unique_ptr<ParsedChunk> chunk(std::move(popChunk));
425 std::unique_ptr<CompactHTMLTokenStream> tokens = std::move(chunk->tokens); 425 std::unique_ptr<CompactHTMLTokenStream> tokens = std::move(chunk->tokens);
426 size_t elementTokenCount = 0; 426 size_t elementTokenCount = 0;
427 427
428 postTaskToLookaheadParser(crossThreadBind(&BackgroundHTMLParser::startedChun kWithCheckpoint, m_backgroundParser, chunk->inputCheckpoint)); 428 postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::startedChunkW ithCheckpoint, m_backgroundParser, chunk->inputCheckpoint);
429 429
430 for (const auto& xssInfo : chunk->xssInfos) { 430 for (const auto& xssInfo : chunk->xssInfos) {
431 m_textPosition = xssInfo->m_textPosition; 431 m_textPosition = xssInfo->m_textPosition;
432 m_xssAuditorDelegate.didBlockScript(*xssInfo); 432 m_xssAuditorDelegate.didBlockScript(*xssInfo);
433 if (isStopped()) 433 if (isStopped())
434 break; 434 break;
435 } 435 }
436 // XSSAuditorDelegate can detach the parser if it decides to block the entir e current document. 436 // XSSAuditorDelegate can detach the parser if it decides to block the entir e current document.
437 if (isDetached()) 437 if (isDetached())
438 return elementTokenCount; 438 return elementTokenCount;
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 } 549 }
550 550
551 void HTMLDocumentParser::forcePlaintextForTextDocument() 551 void HTMLDocumentParser::forcePlaintextForTextDocument()
552 { 552 {
553 if (shouldUseThreading()) { 553 if (shouldUseThreading()) {
554 // This method is called before any data is appended, so we have to star t 554 // This method is called before any data is appended, so we have to star t
555 // the background parser ourselves. 555 // the background parser ourselves.
556 if (!m_haveBackgroundParser) 556 if (!m_haveBackgroundParser)
557 startBackgroundParser(); 557 startBackgroundParser();
558 558
559 postTaskToLookaheadParser(crossThreadBind(&BackgroundHTMLParser::forcePl aintextForTextDocument, m_backgroundParser)); 559 postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::forcePlai ntextForTextDocument, m_backgroundParser);
560 } else 560 } else
561 m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState); 561 m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState);
562 } 562 }
563 563
564 void HTMLDocumentParser::pumpTokenizer() 564 void HTMLDocumentParser::pumpTokenizer()
565 { 565 {
566 ASSERT(!isStopped()); 566 ASSERT(!isStopped());
567 ASSERT(m_tokenizer); 567 ASSERT(m_tokenizer);
568 ASSERT(m_token); 568 ASSERT(m_token);
569 569
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 config->decoder = takeDecoder(); 725 config->decoder = takeDecoder();
726 config->parsedChunkQueue = m_parsedChunkQueue.get(); 726 config->parsedChunkQueue = m_parsedChunkQueue.get();
727 if (document()->settings()) { 727 if (document()->settings()) {
728 if (document()->settings()->backgroundHtmlParserOutstandingTokenLimit()) 728 if (document()->settings()->backgroundHtmlParserOutstandingTokenLimit())
729 config->outstandingTokenLimit = document()->settings()->backgroundHt mlParserOutstandingTokenLimit(); 729 config->outstandingTokenLimit = document()->settings()->backgroundHt mlParserOutstandingTokenLimit();
730 if (document()->settings()->backgroundHtmlParserPendingTokenLimit()) 730 if (document()->settings()->backgroundHtmlParserPendingTokenLimit())
731 config->pendingTokenLimit = document()->settings()->backgroundHtmlPa rserPendingTokenLimit(); 731 config->pendingTokenLimit = document()->settings()->backgroundHtmlPa rserPendingTokenLimit();
732 } 732 }
733 733
734 ASSERT(config->xssAuditor->isSafeToSendToAnotherThread()); 734 ASSERT(config->xssAuditor->isSafeToSendToAnotherThread());
735 postTaskToLookaheadParser(crossThreadBind( 735 postTaskToLookaheadParser(
736 Synchronous,
736 &BackgroundHTMLParser::start, 737 &BackgroundHTMLParser::start,
737 reference.release(), 738 reference.release(),
738 passed(std::move(config)), 739 passed(std::move(config)),
739 document()->url(), 740 document()->url(),
740 passed(CachedDocumentParameters::create(document())), 741 passed(CachedDocumentParameters::create(document())),
741 MediaValuesCached::MediaValuesCachedData(*document()), 742 MediaValuesCached::MediaValuesCachedData(*document()),
742 passed(wrapUnique(m_loadingTaskRunner->clone()))), Synchronous); 743 passed(wrapUnique(m_loadingTaskRunner->clone())));
743 } 744 }
744 745
745 void HTMLDocumentParser::stopBackgroundParser() 746 void HTMLDocumentParser::stopBackgroundParser()
746 { 747 {
747 ASSERT(shouldUseThreading()); 748 ASSERT(shouldUseThreading());
748 ASSERT(m_haveBackgroundParser); 749 ASSERT(m_haveBackgroundParser);
749 m_haveBackgroundParser = false; 750 m_haveBackgroundParser = false;
750 751
751 // Make this sync, as lsan triggers on some unittests if the task runner is 752 // Make this sync, as lsan triggers on some unittests if the task runner is
752 // used. Note that these lifetimes will be much more concrete if 753 // used. Note that these lifetimes will be much more concrete if
753 // ParseHTMLOnMainThread lands (the lookahead parser will be a member). 754 // ParseHTMLOnMainThread lands (the lookahead parser will be a member).
754 postTaskToLookaheadParser(crossThreadBind(&BackgroundHTMLParser::stop, m_bac kgroundParser), Synchronous); 755 postTaskToLookaheadParser(Synchronous, &BackgroundHTMLParser::stop, m_backgr oundParser);
755 m_weakFactory.revokeAll(); 756 m_weakFactory.revokeAll();
756 } 757 }
757 758
758 void HTMLDocumentParser::append(const String& inputSource) 759 void HTMLDocumentParser::append(const String& inputSource)
759 { 760 {
760 if (isStopped()) 761 if (isStopped())
761 return; 762 return;
762 763
763 // We should never reach this point if we're using a parser thread, 764 // We should never reach this point if we're using a parser thread,
764 // as appendBytes() will directly ship the data to the thread. 765 // as appendBytes() will directly ship the data to the thread.
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
852 flush(); 853 flush();
853 if (isDetached()) 854 if (isDetached())
854 return; 855 return;
855 856
856 // Empty documents never got an append() call, and thus have never started 857 // Empty documents never got an append() call, and thus have never started
857 // a background parser. In those cases, we ignore shouldUseThreading() 858 // a background parser. In those cases, we ignore shouldUseThreading()
858 // and fall through to the non-threading case. 859 // and fall through to the non-threading case.
859 if (m_haveBackgroundParser) { 860 if (m_haveBackgroundParser) {
860 if (!m_input.haveSeenEndOfFile()) 861 if (!m_input.haveSeenEndOfFile())
861 m_input.closeWithoutMarkingEndOfFile(); 862 m_input.closeWithoutMarkingEndOfFile();
862 postTaskToLookaheadParser(crossThreadBind(&BackgroundHTMLParser::finish, m_backgroundParser)); 863 postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::finish, m _backgroundParser);
863 return; 864 return;
864 } 865 }
865 866
866 if (!m_tokenizer) { 867 if (!m_tokenizer) {
867 ASSERT(!m_token); 868 ASSERT(!m_token);
868 // We're finishing before receiving any data. Rather than booting up 869 // We're finishing before receiving any data. Rather than booting up
869 // the background parser just to spin it down, we finish parsing 870 // the background parser just to spin it down, we finish parsing
870 // synchronously. 871 // synchronously.
871 m_token = wrapUnique(new HTMLToken); 872 m_token = wrapUnique(new HTMLToken);
872 m_tokenizer = HTMLTokenizer::create(m_options); 873 m_tokenizer = HTMLTokenizer::create(m_options);
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 1019
1019 if (shouldUseThreading()) { 1020 if (shouldUseThreading()) {
1020 double bytesReceivedTime = monotonicallyIncreasingTimeMS(); 1021 double bytesReceivedTime = monotonicallyIncreasingTimeMS();
1021 if (!m_haveBackgroundParser) 1022 if (!m_haveBackgroundParser)
1022 startBackgroundParser(); 1023 startBackgroundParser();
1023 1024
1024 std::unique_ptr<Vector<char>> buffer = wrapUnique(new Vector<char>(lengt h)); 1025 std::unique_ptr<Vector<char>> buffer = wrapUnique(new Vector<char>(lengt h));
1025 memcpy(buffer->data(), data, length); 1026 memcpy(buffer->data(), data, length);
1026 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.debug"), "HTMLDocumentPars er::appendBytes", "size", (unsigned)length); 1027 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.debug"), "HTMLDocumentPars er::appendBytes", "size", (unsigned)length);
1027 1028
1028 postTaskToLookaheadParser(crossThreadBind(&BackgroundHTMLParser::appendR awBytesFromMainThread, m_backgroundParser, passed(std::move(buffer)), bytesRecei vedTime)); 1029 postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::appendRaw BytesFromMainThread, m_backgroundParser, passed(std::move(buffer)), bytesReceive dTime);
1029 return; 1030 return;
1030 } 1031 }
1031 1032
1032 DecodedDataDocumentParser::appendBytes(data, length); 1033 DecodedDataDocumentParser::appendBytes(data, length);
1033 } 1034 }
1034 1035
1035 void HTMLDocumentParser::flush() 1036 void HTMLDocumentParser::flush()
1036 { 1037 {
1037 // If we've got no decoder, we never received any data. 1038 // If we've got no decoder, we never received any data.
1038 if (isDetached() || needsDecoder()) 1039 if (isDetached() || needsDecoder())
1039 return; 1040 return;
1040 1041
1041 if (shouldUseThreading()) { 1042 if (shouldUseThreading()) {
1042 // In some cases, flush() is called without any invocation of 1043 // In some cases, flush() is called without any invocation of
1043 // appendBytes. Fallback to synchronous parsing in that case. 1044 // appendBytes. Fallback to synchronous parsing in that case.
1044 if (!m_haveBackgroundParser) { 1045 if (!m_haveBackgroundParser) {
1045 m_shouldUseThreading = false; 1046 m_shouldUseThreading = false;
1046 m_token = wrapUnique(new HTMLToken); 1047 m_token = wrapUnique(new HTMLToken);
1047 m_tokenizer = HTMLTokenizer::create(m_options); 1048 m_tokenizer = HTMLTokenizer::create(m_options);
1048 DecodedDataDocumentParser::flush(); 1049 DecodedDataDocumentParser::flush();
1049 return; 1050 return;
1050 } 1051 }
1051 1052
1052 postTaskToLookaheadParser(crossThreadBind(&BackgroundHTMLParser::flush, m_backgroundParser)); 1053 postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::flush, m_ backgroundParser);
1053 } else { 1054 } else {
1054 DecodedDataDocumentParser::flush(); 1055 DecodedDataDocumentParser::flush();
1055 } 1056 }
1056 } 1057 }
1057 1058
1058 void HTMLDocumentParser::setDecoder(std::unique_ptr<TextResourceDecoder> decoder ) 1059 void HTMLDocumentParser::setDecoder(std::unique_ptr<TextResourceDecoder> decoder )
1059 { 1060 {
1060 ASSERT(decoder); 1061 ASSERT(decoder);
1061 DecodedDataDocumentParser::setDecoder(std::move(decoder)); 1062 DecodedDataDocumentParser::setDecoder(std::move(decoder));
1062 1063
1063 if (m_haveBackgroundParser) 1064 if (m_haveBackgroundParser)
1064 postTaskToLookaheadParser(crossThreadBind(&BackgroundHTMLParser::setDeco der, m_backgroundParser, passed(takeDecoder()))); 1065 postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::setDecode r, m_backgroundParser, passed(takeDecoder()));
1065 } 1066 }
1066 1067
1067 void HTMLDocumentParser::documentElementAvailable() 1068 void HTMLDocumentParser::documentElementAvailable()
1068 { 1069 {
1069 TRACE_EVENT0("blink,loader", "HTMLDocumentParser::documentElementAvailable") ; 1070 TRACE_EVENT0("blink,loader", "HTMLDocumentParser::documentElementAvailable") ;
1070 DCHECK(document()->documentElement()); 1071 DCHECK(document()->documentElement());
1071 for (const String& scriptSource : m_queuedDocumentWriteScripts) { 1072 for (const String& scriptSource : m_queuedDocumentWriteScripts) {
1072 evaluateAndPreloadScriptForDocumentWrite(scriptSource); 1073 evaluateAndPreloadScriptForDocumentWrite(scriptSource);
1073 } 1074 }
1074 1075
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 1119
1119 if (numPreloads) { 1120 if (numPreloads) {
1120 DEFINE_STATIC_LOCAL(CustomCountHistogram, successHistogram, ("PreloadSca nner.DocumentWrite.ExecutionTime.Success", 1, 10000, 50)); 1121 DEFINE_STATIC_LOCAL(CustomCountHistogram, successHistogram, ("PreloadSca nner.DocumentWrite.ExecutionTime.Success", 1, 10000, 50));
1121 successHistogram.count(duration); 1122 successHistogram.count(duration);
1122 } else { 1123 } else {
1123 DEFINE_STATIC_LOCAL(CustomCountHistogram, failureHistogram, ("PreloadSca nner.DocumentWrite.ExecutionTime.Failure", 1, 10000, 50)); 1124 DEFINE_STATIC_LOCAL(CustomCountHistogram, failureHistogram, ("PreloadSca nner.DocumentWrite.ExecutionTime.Failure", 1, 10000, 50));
1124 failureHistogram.count(duration); 1125 failureHistogram.count(duration);
1125 } 1126 }
1126 } 1127 }
1127 1128
1128 void HTMLDocumentParser::postTaskToLookaheadParser(std::unique_ptr<CrossThreadCl osure> closure, LookaheadParserTaskSynchrony synchronyPolicy) 1129 template <typename FunctionType, typename... Ps>
1130 void HTMLDocumentParser::postTaskToLookaheadParser(LookaheadParserTaskSynchrony synchronyPolicy, FunctionType function, Ps&&... parameters)
1129 { 1131 {
1130 if (!RuntimeEnabledFeatures::parseHTMLOnMainThreadEnabled()) { 1132 if (!RuntimeEnabledFeatures::parseHTMLOnMainThreadEnabled()) {
1131 HTMLParserThread::shared()->postTask(std::move(closure)); 1133 HTMLParserThread::shared()->postTask(crossThreadBind(function, std::forw ard<Ps>(parameters)...));
1132 return; 1134 return;
1133 } 1135 }
1134 1136
1135 // Some messages to the lookahead parser should be synchronous. Otherwise, 1137 // Some messages to the lookahead parser should be synchronous. Otherwise,
1136 // just post to the loading task runner. 1138 // just post to the loading task runner.
1137 switch (synchronyPolicy) { 1139 switch (synchronyPolicy) {
1138 case Synchronous: 1140 case Synchronous:
1139 (*closure)(); 1141 (*WTF::bind(function, std::forward<Ps>(parameters)...))();
hiroshige 2016/07/12 05:33:12 Is this statement covered by tests?
Charlie Harrison 2016/07/12 12:18:36 Yes, ditto.
1140 return; 1142 return;
1141 case Asynchronous: 1143 case Asynchronous:
1142 m_loadingTaskRunner->postTask(BLINK_FROM_HERE, std::move(closure)); 1144 m_loadingTaskRunner->postTask(BLINK_FROM_HERE, WTF::bind(function, std:: forward<Ps>(parameters)...));
1143 return; 1145 return;
1144 } 1146 }
1145 NOTREACHED(); 1147 NOTREACHED();
1146 } 1148 }
1147 1149
1148 } // namespace blink 1150 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698