| OLD | NEW |
| 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 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 checkpoint->parser = m_weakFactory.createWeakPtr(); | 389 checkpoint->parser = m_weakFactory.createWeakPtr(); |
| 390 checkpoint->token = std::move(token); | 390 checkpoint->token = std::move(token); |
| 391 checkpoint->tokenizer = std::move(tokenizer); | 391 checkpoint->tokenizer = std::move(tokenizer); |
| 392 checkpoint->treeBuilderState = HTMLTreeBuilderSimulator::stateFor(m_treeBuil
der.get()); | 392 checkpoint->treeBuilderState = HTMLTreeBuilderSimulator::stateFor(m_treeBuil
der.get()); |
| 393 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint; | 393 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint; |
| 394 checkpoint->preloadScannerCheckpoint = lastChunkBeforeScript->preloadScanner
Checkpoint; | 394 checkpoint->preloadScannerCheckpoint = lastChunkBeforeScript->preloadScanner
Checkpoint; |
| 395 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy(); | 395 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy(); |
| 396 m_input.current().clear(); // FIXME: This should be passed in instead of cle
ared. | 396 m_input.current().clear(); // FIXME: This should be passed in instead of cle
ared. |
| 397 | 397 |
| 398 ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread()); | 398 ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread()); |
| 399 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParser::r
esumeFrom, AllowCrossThreadAccess(m_backgroundParser), passed(std::move(checkpoi
nt)))); | 399 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParser::r
esumeFrom, m_backgroundParser, passed(std::move(checkpoint)))); |
| 400 } | 400 } |
| 401 | 401 |
| 402 size_t HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Par
sedChunk> popChunk) | 402 size_t HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Par
sedChunk> popChunk) |
| 403 { | 403 { |
| 404 TRACE_EVENT_WITH_FLOW0("blink,loading", "HTMLDocumentParser::processParsedCh
unkFromBackgroundParser", popChunk.get(), TRACE_EVENT_FLAG_FLOW_IN); | 404 TRACE_EVENT_WITH_FLOW0("blink,loading", "HTMLDocumentParser::processParsedCh
unkFromBackgroundParser", popChunk.get(), TRACE_EVENT_FLAG_FLOW_IN); |
| 405 TemporaryChange<bool> hasLineNumber(m_isParsingAtLineNumber, true); | 405 TemporaryChange<bool> hasLineNumber(m_isParsingAtLineNumber, true); |
| 406 | 406 |
| 407 ASSERT_WITH_SECURITY_IMPLICATION(m_pumpSpeculationsSessionNestingLevel == 1)
; | 407 ASSERT_WITH_SECURITY_IMPLICATION(m_pumpSpeculationsSessionNestingLevel == 1)
; |
| 408 ASSERT_WITH_SECURITY_IMPLICATION(!inPumpSession()); | 408 ASSERT_WITH_SECURITY_IMPLICATION(!inPumpSession()); |
| 409 ASSERT(!isParsingFragment()); | 409 ASSERT(!isParsingFragment()); |
| 410 ASSERT(!isWaitingForScripts()); | 410 ASSERT(!isWaitingForScripts()); |
| 411 ASSERT(!isStopped()); | 411 ASSERT(!isStopped()); |
| 412 ASSERT(shouldUseThreading()); | 412 ASSERT(shouldUseThreading()); |
| 413 ASSERT(!m_tokenizer); | 413 ASSERT(!m_tokenizer); |
| 414 ASSERT(!m_token); | 414 ASSERT(!m_token); |
| 415 ASSERT(!m_lastChunkBeforeScript); | 415 ASSERT(!m_lastChunkBeforeScript); |
| 416 | 416 |
| 417 OwnPtr<ParsedChunk> chunk(std::move(popChunk)); | 417 OwnPtr<ParsedChunk> chunk(std::move(popChunk)); |
| 418 OwnPtr<CompactHTMLTokenStream> tokens = std::move(chunk->tokens); | 418 OwnPtr<CompactHTMLTokenStream> tokens = std::move(chunk->tokens); |
| 419 size_t elementTokenCount = 0; | 419 size_t elementTokenCount = 0; |
| 420 | 420 |
| 421 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParser::s
tartedChunkWithCheckpoint, AllowCrossThreadAccess(m_backgroundParser), chunk->in
putCheckpoint)); | 421 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParser::s
tartedChunkWithCheckpoint, m_backgroundParser, chunk->inputCheckpoint)); |
| 422 | 422 |
| 423 for (const auto& xssInfo : chunk->xssInfos) { | 423 for (const auto& xssInfo : chunk->xssInfos) { |
| 424 m_textPosition = xssInfo->m_textPosition; | 424 m_textPosition = xssInfo->m_textPosition; |
| 425 m_xssAuditorDelegate.didBlockScript(*xssInfo); | 425 m_xssAuditorDelegate.didBlockScript(*xssInfo); |
| 426 if (isStopped()) | 426 if (isStopped()) |
| 427 break; | 427 break; |
| 428 } | 428 } |
| 429 // XSSAuditorDelegate can detach the parser if it decides to block the entir
e current document. | 429 // XSSAuditorDelegate can detach the parser if it decides to block the entir
e current document. |
| 430 if (isDetached()) | 430 if (isDetached()) |
| 431 return elementTokenCount; | 431 return elementTokenCount; |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 } | 544 } |
| 545 | 545 |
| 546 void HTMLDocumentParser::forcePlaintextForTextDocument() | 546 void HTMLDocumentParser::forcePlaintextForTextDocument() |
| 547 { | 547 { |
| 548 if (shouldUseThreading()) { | 548 if (shouldUseThreading()) { |
| 549 // This method is called before any data is appended, so we have to star
t | 549 // This method is called before any data is appended, so we have to star
t |
| 550 // the background parser ourselves. | 550 // the background parser ourselves. |
| 551 if (!m_haveBackgroundParser) | 551 if (!m_haveBackgroundParser) |
| 552 startBackgroundParser(); | 552 startBackgroundParser(); |
| 553 | 553 |
| 554 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::forcePlaintextForTextDocument, AllowCrossThreadAccess(m_backgroundParser))); | 554 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::forcePlaintextForTextDocument, m_backgroundParser)); |
| 555 } else | 555 } else |
| 556 m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState); | 556 m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState); |
| 557 } | 557 } |
| 558 | 558 |
| 559 void HTMLDocumentParser::pumpTokenizer() | 559 void HTMLDocumentParser::pumpTokenizer() |
| 560 { | 560 { |
| 561 ASSERT(!isStopped()); | 561 ASSERT(!isStopped()); |
| 562 ASSERT(m_tokenizer); | 562 ASSERT(m_tokenizer); |
| 563 ASSERT(m_token); | 563 ASSERT(m_token); |
| 564 | 564 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 736 MediaValuesCached::MediaValuesCachedData(*document()), | 736 MediaValuesCached::MediaValuesCachedData(*document()), |
| 737 passed(adoptPtr(m_loadingTaskRunner->clone())))); | 737 passed(adoptPtr(m_loadingTaskRunner->clone())))); |
| 738 } | 738 } |
| 739 | 739 |
| 740 void HTMLDocumentParser::stopBackgroundParser() | 740 void HTMLDocumentParser::stopBackgroundParser() |
| 741 { | 741 { |
| 742 ASSERT(shouldUseThreading()); | 742 ASSERT(shouldUseThreading()); |
| 743 ASSERT(m_haveBackgroundParser); | 743 ASSERT(m_haveBackgroundParser); |
| 744 m_haveBackgroundParser = false; | 744 m_haveBackgroundParser = false; |
| 745 | 745 |
| 746 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParser::s
top, AllowCrossThreadAccess(m_backgroundParser))); | 746 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParser::s
top, m_backgroundParser)); |
| 747 m_weakFactory.revokeAll(); | 747 m_weakFactory.revokeAll(); |
| 748 } | 748 } |
| 749 | 749 |
| 750 void HTMLDocumentParser::append(const String& inputSource) | 750 void HTMLDocumentParser::append(const String& inputSource) |
| 751 { | 751 { |
| 752 if (isStopped()) | 752 if (isStopped()) |
| 753 return; | 753 return; |
| 754 | 754 |
| 755 // We should never reach this point if we're using a parser thread, | 755 // We should never reach this point if we're using a parser thread, |
| 756 // as appendBytes() will directly ship the data to the thread. | 756 // as appendBytes() will directly ship the data to the thread. |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 844 flush(); | 844 flush(); |
| 845 if (isDetached()) | 845 if (isDetached()) |
| 846 return; | 846 return; |
| 847 | 847 |
| 848 // Empty documents never got an append() call, and thus have never started | 848 // Empty documents never got an append() call, and thus have never started |
| 849 // a background parser. In those cases, we ignore shouldUseThreading() | 849 // a background parser. In those cases, we ignore shouldUseThreading() |
| 850 // and fall through to the non-threading case. | 850 // and fall through to the non-threading case. |
| 851 if (m_haveBackgroundParser) { | 851 if (m_haveBackgroundParser) { |
| 852 if (!m_input.haveSeenEndOfFile()) | 852 if (!m_input.haveSeenEndOfFile()) |
| 853 m_input.closeWithoutMarkingEndOfFile(); | 853 m_input.closeWithoutMarkingEndOfFile(); |
| 854 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::finish, AllowCrossThreadAccess(m_backgroundParser))); | 854 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::finish, m_backgroundParser)); |
| 855 return; | 855 return; |
| 856 } | 856 } |
| 857 | 857 |
| 858 if (!m_tokenizer) { | 858 if (!m_tokenizer) { |
| 859 ASSERT(!m_token); | 859 ASSERT(!m_token); |
| 860 // We're finishing before receiving any data. Rather than booting up | 860 // We're finishing before receiving any data. Rather than booting up |
| 861 // the background parser just to spin it down, we finish parsing | 861 // the background parser just to spin it down, we finish parsing |
| 862 // synchronously. | 862 // synchronously. |
| 863 m_token = adoptPtr(new HTMLToken); | 863 m_token = adoptPtr(new HTMLToken); |
| 864 m_tokenizer = HTMLTokenizer::create(m_options); | 864 m_tokenizer = HTMLTokenizer::create(m_options); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1009 return; | 1009 return; |
| 1010 | 1010 |
| 1011 if (shouldUseThreading()) { | 1011 if (shouldUseThreading()) { |
| 1012 if (!m_haveBackgroundParser) | 1012 if (!m_haveBackgroundParser) |
| 1013 startBackgroundParser(); | 1013 startBackgroundParser(); |
| 1014 | 1014 |
| 1015 OwnPtr<Vector<char>> buffer = adoptPtr(new Vector<char>(length)); | 1015 OwnPtr<Vector<char>> buffer = adoptPtr(new Vector<char>(length)); |
| 1016 memcpy(buffer->data(), data, length); | 1016 memcpy(buffer->data(), data, length); |
| 1017 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.debug"), "HTMLDocumentPars
er::appendBytes", "size", (unsigned)length); | 1017 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.debug"), "HTMLDocumentPars
er::appendBytes", "size", (unsigned)length); |
| 1018 | 1018 |
| 1019 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::appendRawBytesFromMainThread, AllowCrossThreadAccess(m_backgroundParser), pas
sed(std::move(buffer)))); | 1019 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::appendRawBytesFromMainThread, m_backgroundParser, passed(std::move(buffer))))
; |
| 1020 return; | 1020 return; |
| 1021 } | 1021 } |
| 1022 | 1022 |
| 1023 DecodedDataDocumentParser::appendBytes(data, length); | 1023 DecodedDataDocumentParser::appendBytes(data, length); |
| 1024 } | 1024 } |
| 1025 | 1025 |
| 1026 void HTMLDocumentParser::flush() | 1026 void HTMLDocumentParser::flush() |
| 1027 { | 1027 { |
| 1028 // If we've got no decoder, we never received any data. | 1028 // If we've got no decoder, we never received any data. |
| 1029 if (isDetached() || needsDecoder()) | 1029 if (isDetached() || needsDecoder()) |
| 1030 return; | 1030 return; |
| 1031 | 1031 |
| 1032 if (shouldUseThreading()) { | 1032 if (shouldUseThreading()) { |
| 1033 // In some cases, flush() is called without any invocation of | 1033 // In some cases, flush() is called without any invocation of |
| 1034 // appendBytes. Fallback to synchronous parsing in that case. | 1034 // appendBytes. Fallback to synchronous parsing in that case. |
| 1035 if (!m_haveBackgroundParser) { | 1035 if (!m_haveBackgroundParser) { |
| 1036 m_shouldUseThreading = false; | 1036 m_shouldUseThreading = false; |
| 1037 m_token = adoptPtr(new HTMLToken); | 1037 m_token = adoptPtr(new HTMLToken); |
| 1038 m_tokenizer = HTMLTokenizer::create(m_options); | 1038 m_tokenizer = HTMLTokenizer::create(m_options); |
| 1039 DecodedDataDocumentParser::flush(); | 1039 DecodedDataDocumentParser::flush(); |
| 1040 return; | 1040 return; |
| 1041 } | 1041 } |
| 1042 | 1042 |
| 1043 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::flush, AllowCrossThreadAccess(m_backgroundParser))); | 1043 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::flush, m_backgroundParser)); |
| 1044 } else { | 1044 } else { |
| 1045 DecodedDataDocumentParser::flush(); | 1045 DecodedDataDocumentParser::flush(); |
| 1046 } | 1046 } |
| 1047 } | 1047 } |
| 1048 | 1048 |
| 1049 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder) | 1049 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder) |
| 1050 { | 1050 { |
| 1051 ASSERT(decoder); | 1051 ASSERT(decoder); |
| 1052 DecodedDataDocumentParser::setDecoder(std::move(decoder)); | 1052 DecodedDataDocumentParser::setDecoder(std::move(decoder)); |
| 1053 | 1053 |
| 1054 if (m_haveBackgroundParser) | 1054 if (m_haveBackgroundParser) |
| 1055 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::setDecoder, AllowCrossThreadAccess(m_backgroundParser), passed(takeDecoder())
)); | 1055 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::setDecoder, m_backgroundParser, passed(takeDecoder()))); |
| 1056 } | 1056 } |
| 1057 | 1057 |
| 1058 void HTMLDocumentParser::pumpPreloadQueue() | 1058 void HTMLDocumentParser::pumpPreloadQueue() |
| 1059 { | 1059 { |
| 1060 if (!document()->documentElement()) | 1060 if (!document()->documentElement()) |
| 1061 return; | 1061 return; |
| 1062 | 1062 |
| 1063 for (const String& scriptSource : m_queuedDocumentWriteScripts) { | 1063 for (const String& scriptSource : m_queuedDocumentWriteScripts) { |
| 1064 evaluateAndPreloadScriptForDocumentWrite(scriptSource); | 1064 evaluateAndPreloadScriptForDocumentWrite(scriptSource); |
| 1065 } | 1065 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1112 DEFINE_STATIC_LOCAL(CustomCountHistogram, successHistogram, ("PreloadSca
nner.DocumentWrite.ExecutionTime.Success", 1, 10000, 50)); | 1112 DEFINE_STATIC_LOCAL(CustomCountHistogram, successHistogram, ("PreloadSca
nner.DocumentWrite.ExecutionTime.Success", 1, 10000, 50)); |
| 1113 successHistogram.count(duration); | 1113 successHistogram.count(duration); |
| 1114 } else { | 1114 } else { |
| 1115 DEFINE_STATIC_LOCAL(CustomCountHistogram, failureHistogram, ("PreloadSca
nner.DocumentWrite.ExecutionTime.Failure", 1, 10000, 50)); | 1115 DEFINE_STATIC_LOCAL(CustomCountHistogram, failureHistogram, ("PreloadSca
nner.DocumentWrite.ExecutionTime.Failure", 1, 10000, 50)); |
| 1116 failureHistogram.count(duration); | 1116 failureHistogram.count(duration); |
| 1117 } | 1117 } |
| 1118 | 1118 |
| 1119 } | 1119 } |
| 1120 | 1120 |
| 1121 } // namespace blink | 1121 } // namespace blink |
| OLD | NEW |