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 |