Chromium Code Reviews| Index: third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp |
| diff --git a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp |
| index 5a8861007025afa7d2415ea3bb3b954e6edce6a5..f52c9055c2ede6818df3c1135bfc0b3153718ee8 100644 |
| --- a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp |
| +++ b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp |
| @@ -25,6 +25,7 @@ |
| #include "core/html/parser/HTMLDocumentParser.h" |
| +#include <memory> |
| #include "bindings/core/v8/DocumentWriteEvaluator.h" |
| #include "core/HTMLNames.h" |
| #include "core/css/MediaValuesCached.h" |
| @@ -51,6 +52,7 @@ |
| #include "platform/SharedBuffer.h" |
| #include "platform/WebFrameScheduler.h" |
| #include "platform/heap/Handle.h" |
| +#include "platform/heap/Persistent.h" |
| #include "platform/instrumentation/tracing/TraceEvent.h" |
| #include "platform/loader/fetch/ResourceFetcher.h" |
| #include "public/platform/Platform.h" |
| @@ -59,7 +61,6 @@ |
| #include "public/platform/WebThread.h" |
| #include "wtf/AutoReset.h" |
| #include "wtf/PtrUtil.h" |
| -#include <memory> |
| namespace blink { |
| @@ -131,21 +132,19 @@ HTMLDocumentParser::HTMLDocumentParser(Document& document, |
| m_tokenizer(syncPolicy == ForceSynchronousParsing |
| ? HTMLTokenizer::create(m_options) |
| : nullptr), |
| - m_loadingTaskRunner( |
| - TaskRunnerHelper::get(TaskType::Networking, &document)), |
| m_parserScheduler( |
| syncPolicy == AllowAsynchronousParsing |
| - ? HTMLParserScheduler::create(this, m_loadingTaskRunner.get()) |
| + ? HTMLParserScheduler::create( |
| + this, |
| + TaskRunnerHelper::get(TaskType::Networking, &document)) |
| : nullptr), |
| m_xssAuditorDelegate(&document), |
| - m_weakFactory(this), |
| m_preloader(HTMLResourcePreloader::create(document)), |
| m_tokenizedChunkQueue(TokenizedChunkQueue::create()), |
| m_evaluator(DocumentWriteEvaluator::create(document)), |
| m_pendingCSPMetaToken(nullptr), |
| m_shouldUseThreading(syncPolicy == AllowAsynchronousParsing), |
| m_endWasDelayed(false), |
| - m_haveBackgroundParser(false), |
| m_tasksWereSuspended(false), |
| m_pumpSessionNestingLevel(0), |
| m_pumpSpeculationsSessionNestingLevel(0), |
| @@ -160,18 +159,12 @@ HTMLDocumentParser::HTMLDocumentParser(Document& document, |
| HTMLDocumentParser::~HTMLDocumentParser() {} |
| -void HTMLDocumentParser::dispose() { |
| - // In Oilpan, HTMLDocumentParser can die together with Document, and detach() |
| - // is not called in this case. |
| - if (m_haveBackgroundParser) |
| - stopBackgroundParser(); |
| -} |
| - |
| DEFINE_TRACE(HTMLDocumentParser) { |
| visitor->trace(m_treeBuilder); |
| visitor->trace(m_parserScheduler); |
| visitor->trace(m_xssAuditorDelegate); |
| visitor->trace(m_scriptRunner); |
| + visitor->trace(m_backgroundParser); |
| visitor->trace(m_preloader); |
| ScriptableDocumentParser::trace(visitor); |
| HTMLParserScriptRunnerHost::trace(visitor); |
| @@ -190,8 +183,7 @@ void HTMLDocumentParser::detach() { |
| m_tokenizedChunkQueue->peakPendingTokenCount()); |
| } |
| - if (m_haveBackgroundParser) |
| - stopBackgroundParser(); |
| + m_backgroundParser.clear(); |
| DocumentParser::detach(); |
| if (m_scriptRunner) |
| m_scriptRunner->detach(); |
| @@ -218,8 +210,7 @@ void HTMLDocumentParser::stopParsing() { |
| m_parserScheduler->detach(); |
| m_parserScheduler.clear(); |
| } |
| - if (m_haveBackgroundParser) |
| - stopBackgroundParser(); |
| + m_backgroundParser.clear(); |
| } |
| // This kicks off "Once the user agent stops parsing" as described by: |
| @@ -227,11 +218,11 @@ void HTMLDocumentParser::stopParsing() { |
| void HTMLDocumentParser::prepareToStopParsing() { |
| // FIXME: It may not be correct to disable this for the background parser. |
| // That means hasInsertionPoint() may not be correct in some cases. |
| - ASSERT(!hasInsertionPoint() || m_haveBackgroundParser); |
| + ASSERT(!hasInsertionPoint() || m_backgroundParser); |
| // NOTE: This pump should only ever emit buffered character tokens. |
| if (m_tokenizer) { |
| - ASSERT(!m_haveBackgroundParser); |
| + ASSERT(!m_backgroundParser); |
| pumpTokenizerIfPossible(); |
| } |
| @@ -271,7 +262,7 @@ bool HTMLDocumentParser::isScheduledForResume() const { |
| // Used by HTMLParserScheduler |
| void HTMLDocumentParser::resumeParsingAfterYield() { |
| ASSERT(shouldUseThreading()); |
| - ASSERT(m_haveBackgroundParser); |
| + ASSERT(m_backgroundParser); |
| checkIfBodyStlyesheetAdded(); |
| if (isStopped() || isPaused()) |
| @@ -398,6 +389,8 @@ void HTMLDocumentParser::notifyPendingTokenizedChunks() { |
| void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser( |
| const DocumentEncodingData& data) { |
| + if (!isParsing()) |
|
Yoav Weiss
2017/02/09 10:39:00
Could you explain why you added that? Is that rela
|
| + return; |
| document()->setEncodingData(data); |
| } |
| @@ -451,8 +444,6 @@ void HTMLDocumentParser::discardSpeculationsAndResumeFrom( |
| std::unique_ptr<TokenizedChunk> lastChunkBeforeScript, |
| std::unique_ptr<HTMLToken> token, |
| std::unique_ptr<HTMLTokenizer> tokenizer) { |
| - m_weakFactory.revokeAll(); |
| - |
| size_t discardedTokenCount = 0; |
| for (const auto& speculation : m_speculations) { |
| discardedTokenCount += speculation->tokens->size(); |
| @@ -467,7 +458,6 @@ void HTMLDocumentParser::discardSpeculationsAndResumeFrom( |
| std::unique_ptr<BackgroundHTMLParser::Checkpoint> checkpoint = |
| WTF::wrapUnique(new BackgroundHTMLParser::Checkpoint); |
| - checkpoint->parser = m_weakFactory.createWeakPtr(); |
| checkpoint->token = std::move(token); |
| checkpoint->tokenizer = std::move(tokenizer); |
| checkpoint->treeBuilderState = |
| @@ -480,10 +470,7 @@ void HTMLDocumentParser::discardSpeculationsAndResumeFrom( |
| m_input.current().clear(); |
| ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread()); |
| - m_loadingTaskRunner->postTask( |
| - BLINK_FROM_HERE, |
| - WTF::bind(&BackgroundHTMLParser::resumeFrom, m_backgroundParser, |
| - WTF::passed(std::move(checkpoint)))); |
| + m_backgroundParser->resumeFrom(std::move(checkpoint)); |
| } |
| size_t HTMLDocumentParser::processTokenizedChunkFromBackgroundParser( |
| @@ -508,10 +495,7 @@ size_t HTMLDocumentParser::processTokenizedChunkFromBackgroundParser( |
| std::unique_ptr<CompactHTMLTokenStream> tokens = std::move(chunk->tokens); |
| size_t elementTokenCount = 0; |
| - m_loadingTaskRunner->postTask( |
| - BLINK_FROM_HERE, |
| - WTF::bind(&BackgroundHTMLParser::startedChunkWithCheckpoint, |
| - m_backgroundParser, chunk->inputCheckpoint)); |
| + m_backgroundParser->startedChunkWithCheckpoint(chunk->inputCheckpoint); |
| for (const auto& xssInfo : chunk->xssInfos) { |
| m_textPosition = xssInfo->m_textPosition; |
| @@ -538,9 +522,8 @@ size_t HTMLDocumentParser::processTokenizedChunkFromBackgroundParser( |
| // locationChangePending on the EOF path) we peek to see if this chunk has |
| // an EOF and process it anyway. |
| if (tokens->back().type() == HTMLToken::EndOfFile) { |
| - ASSERT( |
| - m_speculations |
| - .isEmpty()); // There should never be any chunks after the EOF. |
| + // There should never be any chunks after the EOF. |
| + ASSERT(m_speculations.isEmpty()); |
| prepareToStopParsing(); |
| } |
| break; |
| @@ -654,7 +637,7 @@ void HTMLDocumentParser::forcePlaintextForTextDocument() { |
| if (shouldUseThreading()) { |
| // This method is called before any data is appended, so we have to start |
| // the background parser ourselves. |
| - if (!m_haveBackgroundParser) |
| + if (!m_backgroundParser) |
| startBackgroundParser(); |
| // This task should be synchronous, because otherwise synchronous |
| @@ -794,7 +777,7 @@ void HTMLDocumentParser::insert(const SegmentedString& source) { |
| if (!m_tokenizer) { |
| ASSERT(!inPumpSession()); |
| - ASSERT(m_haveBackgroundParser || wasCreatedByScript()); |
| + ASSERT(m_backgroundParser || wasCreatedByScript()); |
| m_token = WTF::wrapUnique(new HTMLToken); |
| m_tokenizer = HTMLTokenizer::create(m_options); |
| } |
| @@ -819,12 +802,10 @@ void HTMLDocumentParser::insert(const SegmentedString& source) { |
| void HTMLDocumentParser::startBackgroundParser() { |
| ASSERT(!isStopped()); |
| ASSERT(shouldUseThreading()); |
| - ASSERT(!m_haveBackgroundParser); |
| + ASSERT(!m_backgroundParser); |
| ASSERT(document()); |
| - m_haveBackgroundParser = true; |
| - // TODO(alexclarke): Remove WebFrameScheduler::setDocumentParsingInBackground |
| - // when background parser goes away. |
| + // TODO(csharrison): Remove WebFrameScheduler::setDocumentParsingInBackground. |
| if (document()->frame() && document()->frame()->frameScheduler()) |
| document()->frame()->frameScheduler()->setDocumentParsingInBackground(true); |
| @@ -836,7 +817,6 @@ void HTMLDocumentParser::startBackgroundParser() { |
| std::unique_ptr<BackgroundHTMLParser::Configuration> config = |
| WTF::wrapUnique(new BackgroundHTMLParser::Configuration); |
| config->options = m_options; |
| - config->parser = m_weakFactory.createWeakPtr(); |
| config->xssAuditor = WTF::wrapUnique(new XSSAuditor); |
| config->xssAuditor->init(document(), &m_xssAuditorDelegate); |
| @@ -859,32 +839,8 @@ void HTMLDocumentParser::startBackgroundParser() { |
| ASSERT(config->xssAuditor->isSafeToSendToAnotherThread()); |
| - // The background parser is created on the main thread, but may otherwise |
| - // only be used from the parser thread. |
| m_backgroundParser = |
| - BackgroundHTMLParser::create(std::move(config), m_loadingTaskRunner); |
| - // TODO(csharrison): This is a hack to initialize MediaValuesCached on the |
| - // correct thread. We should get rid of it. |
| - m_backgroundParser->init( |
| - document()->url(), CachedDocumentParameters::create(document()), |
| - MediaValuesCached::MediaValuesCachedData(*document())); |
| -} |
| - |
| -void HTMLDocumentParser::stopBackgroundParser() { |
| - ASSERT(shouldUseThreading()); |
| - ASSERT(m_haveBackgroundParser); |
| - |
| - if (m_haveBackgroundParser && document()->frame() && |
| - document()->frame()->frameScheduler()) |
| - document()->frame()->frameScheduler()->setDocumentParsingInBackground( |
| - false); |
| - |
| - m_haveBackgroundParser = false; |
| - |
| - // Make this sync, as lsan triggers on some unittests if the task runner is |
| - // used. |
| - m_backgroundParser->stop(); |
| - m_weakFactory.revokeAll(); |
| + BackgroundHTMLParser::create(this, *document(), std::move(config)); |
| } |
| void HTMLDocumentParser::append(const String& inputSource) { |
| @@ -941,8 +897,7 @@ void HTMLDocumentParser::end() { |
| ASSERT(!isDetached()); |
| ASSERT(!isScheduledForResume()); |
| - if (m_haveBackgroundParser) |
| - stopBackgroundParser(); |
| + m_backgroundParser.clear(); |
| // Informs the the rest of WebCore that parsing is really finished (and |
| // deletes this). |
| @@ -955,7 +910,7 @@ void HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd() { |
| ASSERT(isStopping()); |
| // FIXME: It may not be correct to disable this for the background parser. |
| // That means hasInsertionPoint() may not be correct in some cases. |
| - ASSERT(!hasInsertionPoint() || m_haveBackgroundParser); |
| + ASSERT(!hasInsertionPoint() || m_backgroundParser); |
| if (m_scriptRunner && !m_scriptRunner->executeScriptsWaitingForParsing()) |
| return; |
| end(); |
| @@ -996,12 +951,10 @@ void HTMLDocumentParser::finish() { |
| // Empty documents never got an append() call, and thus have never started a |
| // background parser. In those cases, we ignore shouldUseThreading() and fall |
| // through to the non-threading case. |
| - if (m_haveBackgroundParser) { |
| + if (m_backgroundParser) { |
| if (!m_input.haveSeenEndOfFile()) |
| m_input.closeWithoutMarkingEndOfFile(); |
| - m_loadingTaskRunner->postTask( |
| - BLINK_FROM_HERE, |
| - WTF::bind(&BackgroundHTMLParser::finish, m_backgroundParser)); |
| + m_backgroundParser->finish(); |
| return; |
| } |
| @@ -1034,14 +987,14 @@ bool HTMLDocumentParser::isParsingAtLineNumber() const { |
| } |
| OrdinalNumber HTMLDocumentParser::lineNumber() const { |
| - if (m_haveBackgroundParser) |
| + if (m_backgroundParser) |
| return m_textPosition.m_line; |
| return m_input.current().currentLine(); |
| } |
| TextPosition HTMLDocumentParser::textPosition() const { |
| - if (m_haveBackgroundParser) |
| + if (m_backgroundParser) |
| return m_textPosition; |
| const SegmentedString& currentString = m_input.current(); |
| @@ -1078,7 +1031,7 @@ void HTMLDocumentParser::resumeParsingAfterPause() { |
| if (isPaused()) |
| return; |
| - if (m_haveBackgroundParser) { |
| + if (m_backgroundParser) { |
| if (m_lastChunkBeforePause) { |
| validateSpeculations(std::move(m_lastChunkBeforePause)); |
| DCHECK(!m_lastChunkBeforePause); |
| @@ -1191,7 +1144,7 @@ void HTMLDocumentParser::appendBytes(const char* data, size_t length) { |
| if (shouldUseThreading()) { |
| double bytesReceivedTime = monotonicallyIncreasingTimeMS(); |
| - if (!m_haveBackgroundParser) |
| + if (!m_backgroundParser) |
| startBackgroundParser(); |
| std::unique_ptr<Vector<char>> buffer = |
| @@ -1200,11 +1153,8 @@ void HTMLDocumentParser::appendBytes(const char* data, size_t length) { |
| TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.debug"), |
| "HTMLDocumentParser::appendBytes", "size", (unsigned)length); |
| - m_loadingTaskRunner->postTask( |
| - BLINK_FROM_HERE, |
| - WTF::bind(&BackgroundHTMLParser::appendRawBytesFromMainThread, |
| - m_backgroundParser, WTF::passed(std::move(buffer)), |
| - bytesReceivedTime)); |
| + m_backgroundParser->appendRawBytesFromMainThread(std::move(buffer), |
| + bytesReceivedTime); |
| return; |
| } |
| @@ -1219,17 +1169,14 @@ void HTMLDocumentParser::flush() { |
| if (shouldUseThreading()) { |
| // In some cases, flush() is called without any invocation of appendBytes. |
| // Fallback to synchronous parsing in that case. |
| - if (!m_haveBackgroundParser) { |
| + if (!m_backgroundParser) { |
| m_shouldUseThreading = false; |
| m_token = WTF::wrapUnique(new HTMLToken); |
| m_tokenizer = HTMLTokenizer::create(m_options); |
| DecodedDataDocumentParser::flush(); |
| return; |
| } |
| - |
| - m_loadingTaskRunner->postTask( |
| - BLINK_FROM_HERE, |
| - WTF::bind(&BackgroundHTMLParser::flush, m_backgroundParser)); |
| + m_backgroundParser->flush(); |
| } else { |
| DecodedDataDocumentParser::flush(); |
| } |
| @@ -1240,12 +1187,8 @@ void HTMLDocumentParser::setDecoder( |
| ASSERT(decoder); |
| DecodedDataDocumentParser::setDecoder(std::move(decoder)); |
| - if (m_haveBackgroundParser) { |
| - m_loadingTaskRunner->postTask( |
| - BLINK_FROM_HERE, |
| - WTF::bind(&BackgroundHTMLParser::setDecoder, m_backgroundParser, |
| - WTF::passed(takeDecoder()))); |
| - } |
| + if (m_backgroundParser) |
| + m_backgroundParser->setDecoder(takeDecoder()); |
| } |
| void HTMLDocumentParser::documentElementAvailable() { |