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

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: rebase on 405128 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 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 LookaheadParserTaskSynchrony policy = document()->settings() && document ()->settings()->parseHTMLOnMainThreadSyncTokenize() ? Synchronous : Asynchronous ; 1036 LookaheadParserTaskSynchrony policy = document()->settings() && document ()->settings()->parseHTMLOnMainThreadSyncTokenize() ? Synchronous : Asynchronous ;
1036 postTaskToLookaheadParser(crossThreadBind(&BackgroundHTMLParser::appendR awBytesFromMainThread, m_backgroundParser, passed(std::move(buffer)), bytesRecei vedTime), policy); 1037 postTaskToLookaheadParser(policy, &BackgroundHTMLParser::appendRawBytesF romMainThread, m_backgroundParser, passed(std::move(buffer)), bytesReceivedTime) ;
1037 return; 1038 return;
1038 } 1039 }
1039 1040
1040 DecodedDataDocumentParser::appendBytes(data, length); 1041 DecodedDataDocumentParser::appendBytes(data, length);
1041 } 1042 }
1042 1043
1043 void HTMLDocumentParser::flush() 1044 void HTMLDocumentParser::flush()
1044 { 1045 {
1045 // If we've got no decoder, we never received any data. 1046 // If we've got no decoder, we never received any data.
1046 if (isDetached() || needsDecoder()) 1047 if (isDetached() || needsDecoder())
1047 return; 1048 return;
1048 1049
1049 if (shouldUseThreading()) { 1050 if (shouldUseThreading()) {
1050 // In some cases, flush() is called without any invocation of 1051 // In some cases, flush() is called without any invocation of
1051 // appendBytes. Fallback to synchronous parsing in that case. 1052 // appendBytes. Fallback to synchronous parsing in that case.
1052 if (!m_haveBackgroundParser) { 1053 if (!m_haveBackgroundParser) {
1053 m_shouldUseThreading = false; 1054 m_shouldUseThreading = false;
1054 m_token = wrapUnique(new HTMLToken); 1055 m_token = wrapUnique(new HTMLToken);
1055 m_tokenizer = HTMLTokenizer::create(m_options); 1056 m_tokenizer = HTMLTokenizer::create(m_options);
1056 DecodedDataDocumentParser::flush(); 1057 DecodedDataDocumentParser::flush();
1057 return; 1058 return;
1058 } 1059 }
1059 1060
1060 postTaskToLookaheadParser(crossThreadBind(&BackgroundHTMLParser::flush, m_backgroundParser)); 1061 postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::flush, m_ backgroundParser);
1061 } else { 1062 } else {
1062 DecodedDataDocumentParser::flush(); 1063 DecodedDataDocumentParser::flush();
1063 } 1064 }
1064 } 1065 }
1065 1066
1066 void HTMLDocumentParser::setDecoder(std::unique_ptr<TextResourceDecoder> decoder ) 1067 void HTMLDocumentParser::setDecoder(std::unique_ptr<TextResourceDecoder> decoder )
1067 { 1068 {
1068 ASSERT(decoder); 1069 ASSERT(decoder);
1069 DecodedDataDocumentParser::setDecoder(std::move(decoder)); 1070 DecodedDataDocumentParser::setDecoder(std::move(decoder));
1070 1071
1071 if (m_haveBackgroundParser) 1072 if (m_haveBackgroundParser)
1072 postTaskToLookaheadParser(crossThreadBind(&BackgroundHTMLParser::setDeco der, m_backgroundParser, passed(takeDecoder()))); 1073 postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::setDecode r, m_backgroundParser, passed(takeDecoder()));
1073 } 1074 }
1074 1075
1075 void HTMLDocumentParser::documentElementAvailable() 1076 void HTMLDocumentParser::documentElementAvailable()
1076 { 1077 {
1077 TRACE_EVENT0("blink,loader", "HTMLDocumentParser::documentElementAvailable") ; 1078 TRACE_EVENT0("blink,loader", "HTMLDocumentParser::documentElementAvailable") ;
1078 DCHECK(document()->documentElement()); 1079 DCHECK(document()->documentElement());
1079 if (!m_queuedPreloads.isEmpty()) 1080 if (!m_queuedPreloads.isEmpty())
1080 m_preloader->takeAndPreload(m_queuedPreloads); 1081 m_preloader->takeAndPreload(m_queuedPreloads);
1081 1082
1082 for (const String& scriptSource : m_queuedDocumentWriteScripts) { 1083 for (const String& scriptSource : m_queuedDocumentWriteScripts) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1127 1128
1128 if (numPreloads) { 1129 if (numPreloads) {
1129 DEFINE_STATIC_LOCAL(CustomCountHistogram, successHistogram, ("PreloadSca nner.DocumentWrite.ExecutionTime.Success", 1, 10000, 50)); 1130 DEFINE_STATIC_LOCAL(CustomCountHistogram, successHistogram, ("PreloadSca nner.DocumentWrite.ExecutionTime.Success", 1, 10000, 50));
1130 successHistogram.count(duration); 1131 successHistogram.count(duration);
1131 } else { 1132 } else {
1132 DEFINE_STATIC_LOCAL(CustomCountHistogram, failureHistogram, ("PreloadSca nner.DocumentWrite.ExecutionTime.Failure", 1, 10000, 50)); 1133 DEFINE_STATIC_LOCAL(CustomCountHistogram, failureHistogram, ("PreloadSca nner.DocumentWrite.ExecutionTime.Failure", 1, 10000, 50));
1133 failureHistogram.count(duration); 1134 failureHistogram.count(duration);
1134 } 1135 }
1135 } 1136 }
1136 1137
1137 void HTMLDocumentParser::postTaskToLookaheadParser(std::unique_ptr<CrossThreadCl osure> closure, LookaheadParserTaskSynchrony synchronyPolicy) 1138 template <typename FunctionType, typename... Ps>
1139 void HTMLDocumentParser::postTaskToLookaheadParser(LookaheadParserTaskSynchrony synchronyPolicy, FunctionType function, Ps&&... parameters)
1138 { 1140 {
1139 if (!RuntimeEnabledFeatures::parseHTMLOnMainThreadEnabled()) { 1141 if (!RuntimeEnabledFeatures::parseHTMLOnMainThreadEnabled()) {
1140 HTMLParserThread::shared()->postTask(std::move(closure)); 1142 HTMLParserThread::shared()->postTask(crossThreadBind(function, std::forw ard<Ps>(parameters)...));
1141 return; 1143 return;
1142 } 1144 }
1143 1145
1144 // Some messages to the lookahead parser should be synchronous. Otherwise, 1146 // Some messages to the lookahead parser should be synchronous. Otherwise,
1145 // just post to the loading task runner. 1147 // just post to the loading task runner.
1146 switch (synchronyPolicy) { 1148 switch (synchronyPolicy) {
1147 case Synchronous: 1149 case Synchronous:
1148 (*closure)(); 1150 (*WTF::bind(function, std::forward<Ps>(parameters)...))();
1149 return; 1151 return;
1150 case Asynchronous: 1152 case Asynchronous:
1151 m_loadingTaskRunner->postTask(BLINK_FROM_HERE, std::move(closure)); 1153 m_loadingTaskRunner->postTask(BLINK_FROM_HERE, WTF::bind(function, std:: forward<Ps>(parameters)...));
1152 return; 1154 return;
1153 } 1155 }
1154 NOTREACHED(); 1156 NOTREACHED();
1155 } 1157 }
1156 1158
1157 } // namespace blink 1159 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698