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

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

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

Powered by Google App Engine
This is Rietveld 408576698