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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 #include "platform/Histogram.h" | 48 #include "platform/Histogram.h" |
49 #include "platform/SharedBuffer.h" | 49 #include "platform/SharedBuffer.h" |
50 #include "platform/ThreadSafeFunctional.h" | 50 #include "platform/ThreadSafeFunctional.h" |
51 #include "platform/TraceEvent.h" | 51 #include "platform/TraceEvent.h" |
52 #include "platform/heap/Handle.h" | 52 #include "platform/heap/Handle.h" |
53 #include "public/platform/Platform.h" | 53 #include "public/platform/Platform.h" |
54 #include "public/platform/WebFrameScheduler.h" | 54 #include "public/platform/WebFrameScheduler.h" |
55 #include "public/platform/WebLoadingBehaviorFlag.h" | 55 #include "public/platform/WebLoadingBehaviorFlag.h" |
56 #include "public/platform/WebScheduler.h" | 56 #include "public/platform/WebScheduler.h" |
57 #include "public/platform/WebThread.h" | 57 #include "public/platform/WebThread.h" |
| 58 #include "wtf/PtrUtil.h" |
58 #include "wtf/TemporaryChange.h" | 59 #include "wtf/TemporaryChange.h" |
| 60 #include <memory> |
59 | 61 |
60 namespace blink { | 62 namespace blink { |
61 | 63 |
62 using namespace HTMLNames; | 64 using namespace HTMLNames; |
63 | 65 |
64 // This is a direct transcription of step 4 from: | 66 // This is a direct transcription of step 4 from: |
65 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#frag
ment-case | 67 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#frag
ment-case |
66 static HTMLTokenizer::State tokenizerStateForContextElement(Element* contextElem
ent, bool reportErrors, const HTMLParserOptions& options) | 68 static HTMLTokenizer::State tokenizerStateForContextElement(Element* contextElem
ent, bool reportErrors, const HTMLParserOptions& options) |
67 { | 69 { |
68 if (!contextElement) | 70 if (!contextElement) |
(...skipping 13 matching lines...) Expand all Loading... |
82 if (contextTag.matches(scriptTag)) | 84 if (contextTag.matches(scriptTag)) |
83 return reportErrors ? HTMLTokenizer::ScriptDataState : HTMLTokenizer::PL
AINTEXTState; | 85 return reportErrors ? HTMLTokenizer::ScriptDataState : HTMLTokenizer::PL
AINTEXTState; |
84 if (contextTag.matches(plaintextTag)) | 86 if (contextTag.matches(plaintextTag)) |
85 return HTMLTokenizer::PLAINTEXTState; | 87 return HTMLTokenizer::PLAINTEXTState; |
86 return HTMLTokenizer::DataState; | 88 return HTMLTokenizer::DataState; |
87 } | 89 } |
88 | 90 |
89 HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document, ParserSynchroniza
tionPolicy syncPolicy) | 91 HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document, ParserSynchroniza
tionPolicy syncPolicy) |
90 : ScriptableDocumentParser(document) | 92 : ScriptableDocumentParser(document) |
91 , m_options(&document) | 93 , m_options(&document) |
92 , m_token(syncPolicy == ForceSynchronousParsing ? adoptPtr(new HTMLToken) :
nullptr) | 94 , m_token(syncPolicy == ForceSynchronousParsing ? wrapUnique(new HTMLToken)
: nullptr) |
93 , m_tokenizer(syncPolicy == ForceSynchronousParsing ? HTMLTokenizer::create(
m_options) : nullptr) | 95 , m_tokenizer(syncPolicy == ForceSynchronousParsing ? HTMLTokenizer::create(
m_options) : nullptr) |
94 , m_scriptRunner(HTMLScriptRunner::create(&document, this)) | 96 , m_scriptRunner(HTMLScriptRunner::create(&document, this)) |
95 , m_treeBuilder(HTMLTreeBuilder::create(this, &document, getParserContentPol
icy(), m_options)) | 97 , m_treeBuilder(HTMLTreeBuilder::create(this, &document, getParserContentPol
icy(), m_options)) |
96 , m_loadingTaskRunner(adoptPtr(document.loadingTaskRunner()->clone())) | 98 , m_loadingTaskRunner(wrapUnique(document.loadingTaskRunner()->clone())) |
97 , m_parserScheduler(HTMLParserScheduler::create(this, m_loadingTaskRunner.ge
t())) | 99 , m_parserScheduler(HTMLParserScheduler::create(this, m_loadingTaskRunner.ge
t())) |
98 , m_xssAuditorDelegate(&document) | 100 , m_xssAuditorDelegate(&document) |
99 , m_weakFactory(this) | 101 , m_weakFactory(this) |
100 , m_preloader(HTMLResourcePreloader::create(document)) | 102 , m_preloader(HTMLResourcePreloader::create(document)) |
101 , m_parsedChunkQueue(ParsedChunkQueue::create()) | 103 , m_parsedChunkQueue(ParsedChunkQueue::create()) |
102 , m_evaluator(DocumentWriteEvaluator::create(document)) | 104 , m_evaluator(DocumentWriteEvaluator::create(document)) |
103 , m_shouldUseThreading(syncPolicy == AllowAsynchronousParsing) | 105 , m_shouldUseThreading(syncPolicy == AllowAsynchronousParsing) |
104 , m_endWasDelayed(false) | 106 , m_endWasDelayed(false) |
105 , m_haveBackgroundParser(false) | 107 , m_haveBackgroundParser(false) |
106 , m_tasksWereSuspended(false) | 108 , m_tasksWereSuspended(false) |
107 , m_pumpSessionNestingLevel(0) | 109 , m_pumpSessionNestingLevel(0) |
108 , m_pumpSpeculationsSessionNestingLevel(0) | 110 , m_pumpSpeculationsSessionNestingLevel(0) |
109 , m_isParsingAtLineNumber(false) | 111 , m_isParsingAtLineNumber(false) |
110 , m_triedLoadingLinkHeaders(false) | 112 , m_triedLoadingLinkHeaders(false) |
111 { | 113 { |
112 ASSERT(shouldUseThreading() || (m_token && m_tokenizer)); | 114 ASSERT(shouldUseThreading() || (m_token && m_tokenizer)); |
113 } | 115 } |
114 | 116 |
115 // FIXME: Member variables should be grouped into self-initializing structs to | 117 // FIXME: Member variables should be grouped into self-initializing structs to |
116 // minimize code duplication between these constructors. | 118 // minimize code duplication between these constructors. |
117 HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* cont
extElement, ParserContentPolicy parserContentPolicy) | 119 HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* cont
extElement, ParserContentPolicy parserContentPolicy) |
118 : ScriptableDocumentParser(fragment->document(), parserContentPolicy) | 120 : ScriptableDocumentParser(fragment->document(), parserContentPolicy) |
119 , m_options(&fragment->document()) | 121 , m_options(&fragment->document()) |
120 , m_token(adoptPtr(new HTMLToken)) | 122 , m_token(wrapUnique(new HTMLToken)) |
121 , m_tokenizer(HTMLTokenizer::create(m_options)) | 123 , m_tokenizer(HTMLTokenizer::create(m_options)) |
122 , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, this
->getParserContentPolicy(), m_options)) | 124 , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, this
->getParserContentPolicy(), m_options)) |
123 , m_loadingTaskRunner(adoptPtr(fragment->document().loadingTaskRunner()->clo
ne())) | 125 , m_loadingTaskRunner(wrapUnique(fragment->document().loadingTaskRunner()->c
lone())) |
124 , m_xssAuditorDelegate(&fragment->document()) | 126 , m_xssAuditorDelegate(&fragment->document()) |
125 , m_weakFactory(this) | 127 , m_weakFactory(this) |
126 , m_shouldUseThreading(false) | 128 , m_shouldUseThreading(false) |
127 , m_endWasDelayed(false) | 129 , m_endWasDelayed(false) |
128 , m_haveBackgroundParser(false) | 130 , m_haveBackgroundParser(false) |
129 , m_tasksWereSuspended(false) | 131 , m_tasksWereSuspended(false) |
130 , m_pumpSessionNestingLevel(0) | 132 , m_pumpSessionNestingLevel(0) |
131 , m_pumpSpeculationsSessionNestingLevel(0) | 133 , m_pumpSpeculationsSessionNestingLevel(0) |
132 { | 134 { |
133 bool reportErrors = false; // For now document fragment parsing never report
s errors. | 135 bool reportErrors = false; // For now document fragment parsing never report
s errors. |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 return false; | 285 return false; |
284 | 286 |
285 return true; | 287 return true; |
286 } | 288 } |
287 | 289 |
288 void HTMLDocumentParser::notifyPendingParsedChunks() | 290 void HTMLDocumentParser::notifyPendingParsedChunks() |
289 { | 291 { |
290 TRACE_EVENT0("blink", "HTMLDocumentParser::notifyPendingParsedChunks"); | 292 TRACE_EVENT0("blink", "HTMLDocumentParser::notifyPendingParsedChunks"); |
291 ASSERT(m_parsedChunkQueue); | 293 ASSERT(m_parsedChunkQueue); |
292 | 294 |
293 Vector<OwnPtr<ParsedChunk>> pendingChunks; | 295 Vector<std::unique_ptr<ParsedChunk>> pendingChunks; |
294 m_parsedChunkQueue->takeAll(pendingChunks); | 296 m_parsedChunkQueue->takeAll(pendingChunks); |
295 | 297 |
296 if (!isParsing()) | 298 if (!isParsing()) |
297 return; | 299 return; |
298 | 300 |
299 // ApplicationCache needs to be initialized before issuing preloads. | 301 // ApplicationCache needs to be initialized before issuing preloads. |
300 // We suspend preload until HTMLHTMLElement is inserted and | 302 // We suspend preload until HTMLHTMLElement is inserted and |
301 // ApplicationCache is initialized. | 303 // ApplicationCache is initialized. |
302 if (!document()->documentElement()) { | 304 if (!document()->documentElement()) { |
303 for (auto& chunk : pendingChunks) { | 305 for (auto& chunk : pendingChunks) { |
(...skipping 30 matching lines...) Expand all Loading... |
334 else | 336 else |
335 m_parserScheduler->scheduleForResume(); | 337 m_parserScheduler->scheduleForResume(); |
336 } | 338 } |
337 } | 339 } |
338 | 340 |
339 void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser(const Docume
ntEncodingData& data) | 341 void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser(const Docume
ntEncodingData& data) |
340 { | 342 { |
341 document()->setEncodingData(data); | 343 document()->setEncodingData(data); |
342 } | 344 } |
343 | 345 |
344 void HTMLDocumentParser::validateSpeculations(PassOwnPtr<ParsedChunk> chunk) | 346 void HTMLDocumentParser::validateSpeculations(std::unique_ptr<ParsedChunk> chunk
) |
345 { | 347 { |
346 ASSERT(chunk); | 348 ASSERT(chunk); |
347 if (isWaitingForScripts()) { | 349 if (isWaitingForScripts()) { |
348 // We're waiting on a network script, just save the chunk, we'll get | 350 // We're waiting on a network script, just save the chunk, we'll get |
349 // a second validateSpeculations call after the script completes. | 351 // a second validateSpeculations call after the script completes. |
350 // This call should have been made immediately after runScriptsForPaused
TreeBuilder | 352 // This call should have been made immediately after runScriptsForPaused
TreeBuilder |
351 // which may have started a network load and left us waiting. | 353 // which may have started a network load and left us waiting. |
352 ASSERT(!m_lastChunkBeforeScript); | 354 ASSERT(!m_lastChunkBeforeScript); |
353 m_lastChunkBeforeScript = std::move(chunk); | 355 m_lastChunkBeforeScript = std::move(chunk); |
354 return; | 356 return; |
355 } | 357 } |
356 | 358 |
357 ASSERT(!m_lastChunkBeforeScript); | 359 ASSERT(!m_lastChunkBeforeScript); |
358 OwnPtr<HTMLTokenizer> tokenizer = std::move(m_tokenizer); | 360 std::unique_ptr<HTMLTokenizer> tokenizer = std::move(m_tokenizer); |
359 OwnPtr<HTMLToken> token = std::move(m_token); | 361 std::unique_ptr<HTMLToken> token = std::move(m_token); |
360 | 362 |
361 if (!tokenizer) { | 363 if (!tokenizer) { |
362 // There must not have been any changes to the HTMLTokenizer state on | 364 // There must not have been any changes to the HTMLTokenizer state on |
363 // the main thread, which means the speculation buffer is correct. | 365 // the main thread, which means the speculation buffer is correct. |
364 return; | 366 return; |
365 } | 367 } |
366 | 368 |
367 // Currently we're only smart enough to reuse the speculation buffer if the
tokenizer | 369 // Currently we're only smart enough to reuse the speculation buffer if the
tokenizer |
368 // both starts and ends in the DataState. That state is simplest because the
HTMLToken | 370 // both starts and ends in the DataState. That state is simplest because the
HTMLToken |
369 // is always in the Uninitialized state. We should consider whether we can r
euse the | 371 // is always in the Uninitialized state. We should consider whether we can r
euse the |
370 // speculation buffer in other states, but we'd likely need to do something
more | 372 // speculation buffer in other states, but we'd likely need to do something
more |
371 // sophisticated with the HTMLToken. | 373 // sophisticated with the HTMLToken. |
372 if (chunk->tokenizerState == HTMLTokenizer::DataState | 374 if (chunk->tokenizerState == HTMLTokenizer::DataState |
373 && tokenizer->getState() == HTMLTokenizer::DataState | 375 && tokenizer->getState() == HTMLTokenizer::DataState |
374 && m_input.current().isEmpty() | 376 && m_input.current().isEmpty() |
375 && chunk->treeBuilderState == HTMLTreeBuilderSimulator::stateFor(m_treeB
uilder.get())) { | 377 && chunk->treeBuilderState == HTMLTreeBuilderSimulator::stateFor(m_treeB
uilder.get())) { |
376 ASSERT(token->isUninitialized()); | 378 ASSERT(token->isUninitialized()); |
377 return; | 379 return; |
378 } | 380 } |
379 | 381 |
380 discardSpeculationsAndResumeFrom(std::move(chunk), std::move(token), std::mo
ve(tokenizer)); | 382 discardSpeculationsAndResumeFrom(std::move(chunk), std::move(token), std::mo
ve(tokenizer)); |
381 } | 383 } |
382 | 384 |
383 void HTMLDocumentParser::discardSpeculationsAndResumeFrom(PassOwnPtr<ParsedChunk
> lastChunkBeforeScript, PassOwnPtr<HTMLToken> token, PassOwnPtr<HTMLTokenizer>
tokenizer) | 385 void HTMLDocumentParser::discardSpeculationsAndResumeFrom(std::unique_ptr<Parsed
Chunk> lastChunkBeforeScript, std::unique_ptr<HTMLToken> token, std::unique_ptr<
HTMLTokenizer> tokenizer) |
384 { | 386 { |
385 m_weakFactory.revokeAll(); | 387 m_weakFactory.revokeAll(); |
386 m_speculations.clear(); | 388 m_speculations.clear(); |
387 | 389 |
388 OwnPtr<BackgroundHTMLParser::Checkpoint> checkpoint = adoptPtr(new Backgroun
dHTMLParser::Checkpoint); | 390 std::unique_ptr<BackgroundHTMLParser::Checkpoint> checkpoint = wrapUnique(ne
w BackgroundHTMLParser::Checkpoint); |
389 checkpoint->parser = m_weakFactory.createWeakPtr(); | 391 checkpoint->parser = m_weakFactory.createWeakPtr(); |
390 checkpoint->token = std::move(token); | 392 checkpoint->token = std::move(token); |
391 checkpoint->tokenizer = std::move(tokenizer); | 393 checkpoint->tokenizer = std::move(tokenizer); |
392 checkpoint->treeBuilderState = HTMLTreeBuilderSimulator::stateFor(m_treeBuil
der.get()); | 394 checkpoint->treeBuilderState = HTMLTreeBuilderSimulator::stateFor(m_treeBuil
der.get()); |
393 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint; | 395 checkpoint->inputCheckpoint = lastChunkBeforeScript->inputCheckpoint; |
394 checkpoint->preloadScannerCheckpoint = lastChunkBeforeScript->preloadScanner
Checkpoint; | 396 checkpoint->preloadScannerCheckpoint = lastChunkBeforeScript->preloadScanner
Checkpoint; |
395 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy(); | 397 checkpoint->unparsedInput = m_input.current().toString().isolatedCopy(); |
396 m_input.current().clear(); // FIXME: This should be passed in instead of cle
ared. | 398 m_input.current().clear(); // FIXME: This should be passed in instead of cle
ared. |
397 | 399 |
398 ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread()); | 400 ASSERT(checkpoint->unparsedInput.isSafeToSendToAnotherThread()); |
399 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParser::r
esumeFrom, m_backgroundParser, passed(std::move(checkpoint)))); | 401 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParser::r
esumeFrom, m_backgroundParser, passed(std::move(checkpoint)))); |
400 } | 402 } |
401 | 403 |
402 size_t HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Par
sedChunk> popChunk) | 404 size_t HTMLDocumentParser::processParsedChunkFromBackgroundParser(std::unique_pt
r<ParsedChunk> popChunk) |
403 { | 405 { |
404 TRACE_EVENT_WITH_FLOW0("blink,loading", "HTMLDocumentParser::processParsedCh
unkFromBackgroundParser", popChunk.get(), TRACE_EVENT_FLAG_FLOW_IN); | 406 TRACE_EVENT_WITH_FLOW0("blink,loading", "HTMLDocumentParser::processParsedCh
unkFromBackgroundParser", popChunk.get(), TRACE_EVENT_FLAG_FLOW_IN); |
405 TemporaryChange<bool> hasLineNumber(m_isParsingAtLineNumber, true); | 407 TemporaryChange<bool> hasLineNumber(m_isParsingAtLineNumber, true); |
406 | 408 |
407 ASSERT_WITH_SECURITY_IMPLICATION(m_pumpSpeculationsSessionNestingLevel == 1)
; | 409 ASSERT_WITH_SECURITY_IMPLICATION(m_pumpSpeculationsSessionNestingLevel == 1)
; |
408 ASSERT_WITH_SECURITY_IMPLICATION(!inPumpSession()); | 410 ASSERT_WITH_SECURITY_IMPLICATION(!inPumpSession()); |
409 ASSERT(!isParsingFragment()); | 411 ASSERT(!isParsingFragment()); |
410 ASSERT(!isWaitingForScripts()); | 412 ASSERT(!isWaitingForScripts()); |
411 ASSERT(!isStopped()); | 413 ASSERT(!isStopped()); |
412 ASSERT(shouldUseThreading()); | 414 ASSERT(shouldUseThreading()); |
413 ASSERT(!m_tokenizer); | 415 ASSERT(!m_tokenizer); |
414 ASSERT(!m_token); | 416 ASSERT(!m_token); |
415 ASSERT(!m_lastChunkBeforeScript); | 417 ASSERT(!m_lastChunkBeforeScript); |
416 | 418 |
417 OwnPtr<ParsedChunk> chunk(std::move(popChunk)); | 419 std::unique_ptr<ParsedChunk> chunk(std::move(popChunk)); |
418 OwnPtr<CompactHTMLTokenStream> tokens = std::move(chunk->tokens); | 420 std::unique_ptr<CompactHTMLTokenStream> tokens = std::move(chunk->tokens); |
419 size_t elementTokenCount = 0; | 421 size_t elementTokenCount = 0; |
420 | 422 |
421 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParser::s
tartedChunkWithCheckpoint, m_backgroundParser, chunk->inputCheckpoint)); | 423 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParser::s
tartedChunkWithCheckpoint, m_backgroundParser, chunk->inputCheckpoint)); |
422 | 424 |
423 for (const auto& xssInfo : chunk->xssInfos) { | 425 for (const auto& xssInfo : chunk->xssInfos) { |
424 m_textPosition = xssInfo->m_textPosition; | 426 m_textPosition = xssInfo->m_textPosition; |
425 m_xssAuditorDelegate.didBlockScript(*xssInfo); | 427 m_xssAuditorDelegate.didBlockScript(*xssInfo); |
426 if (isStopped()) | 428 if (isStopped()) |
427 break; | 429 break; |
428 } | 430 } |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 m_sourceTracker.start(m_input.current(), m_tokenizer.get(), token())
; | 579 m_sourceTracker.start(m_input.current(), m_tokenizer.get(), token())
; |
578 | 580 |
579 if (!m_tokenizer->nextToken(m_input.current(), token())) | 581 if (!m_tokenizer->nextToken(m_input.current(), token())) |
580 break; | 582 break; |
581 | 583 |
582 if (m_xssAuditor.isEnabled()) { | 584 if (m_xssAuditor.isEnabled()) { |
583 m_sourceTracker.end(m_input.current(), m_tokenizer.get(), token()); | 585 m_sourceTracker.end(m_input.current(), m_tokenizer.get(), token()); |
584 | 586 |
585 // We do not XSS filter innerHTML, which means we (intentionally) fa
il | 587 // We do not XSS filter innerHTML, which means we (intentionally) fa
il |
586 // http/tests/security/xssAuditor/dom-write-innerHTML.html | 588 // http/tests/security/xssAuditor/dom-write-innerHTML.html |
587 if (OwnPtr<XSSInfo> xssInfo = m_xssAuditor.filterToken(FilterTokenRe
quest(token(), m_sourceTracker, m_tokenizer->shouldAllowCDATA()))) | 589 if (std::unique_ptr<XSSInfo> xssInfo = m_xssAuditor.filterToken(Filt
erTokenRequest(token(), m_sourceTracker, m_tokenizer->shouldAllowCDATA()))) |
588 m_xssAuditorDelegate.didBlockScript(*xssInfo); | 590 m_xssAuditorDelegate.didBlockScript(*xssInfo); |
589 } | 591 } |
590 | 592 |
591 constructTreeFromHTMLToken(); | 593 constructTreeFromHTMLToken(); |
592 ASSERT(isStopped() || token().isUninitialized()); | 594 ASSERT(isStopped() || token().isUninitialized()); |
593 } | 595 } |
594 | 596 |
595 if (isStopped()) | 597 if (isStopped()) |
596 return; | 598 return; |
597 | 599 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
666 void HTMLDocumentParser::insert(const SegmentedString& source) | 668 void HTMLDocumentParser::insert(const SegmentedString& source) |
667 { | 669 { |
668 if (isStopped()) | 670 if (isStopped()) |
669 return; | 671 return; |
670 | 672 |
671 TRACE_EVENT1("blink", "HTMLDocumentParser::insert", "source_length", source.
length()); | 673 TRACE_EVENT1("blink", "HTMLDocumentParser::insert", "source_length", source.
length()); |
672 | 674 |
673 if (!m_tokenizer) { | 675 if (!m_tokenizer) { |
674 ASSERT(!inPumpSession()); | 676 ASSERT(!inPumpSession()); |
675 ASSERT(m_haveBackgroundParser || wasCreatedByScript()); | 677 ASSERT(m_haveBackgroundParser || wasCreatedByScript()); |
676 m_token = adoptPtr(new HTMLToken); | 678 m_token = wrapUnique(new HTMLToken); |
677 m_tokenizer = HTMLTokenizer::create(m_options); | 679 m_tokenizer = HTMLTokenizer::create(m_options); |
678 } | 680 } |
679 | 681 |
680 SegmentedString excludedLineNumberSource(source); | 682 SegmentedString excludedLineNumberSource(source); |
681 excludedLineNumberSource.setExcludeLineNumbers(); | 683 excludedLineNumberSource.setExcludeLineNumbers(); |
682 m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource); | 684 m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource); |
683 pumpTokenizerIfPossible(); | 685 pumpTokenizerIfPossible(); |
684 | 686 |
685 if (isWaitingForScripts()) { | 687 if (isWaitingForScripts()) { |
686 // Check the document.write() output with a separate preload scanner as | 688 // Check the document.write() output with a separate preload scanner as |
(...skipping 15 matching lines...) Expand all Loading... |
702 ASSERT(document()); | 704 ASSERT(document()); |
703 m_haveBackgroundParser = true; | 705 m_haveBackgroundParser = true; |
704 | 706 |
705 // Make sure that a resolver is set up, so that the correct viewport dimensi
ons will be fed to the background parser and preload scanner. | 707 // Make sure that a resolver is set up, so that the correct viewport dimensi
ons will be fed to the background parser and preload scanner. |
706 if (document()->loader()) | 708 if (document()->loader()) |
707 document()->ensureStyleResolver(); | 709 document()->ensureStyleResolver(); |
708 | 710 |
709 RefPtr<WeakReference<BackgroundHTMLParser>> reference = WeakReference<Backgr
oundHTMLParser>::createUnbound(); | 711 RefPtr<WeakReference<BackgroundHTMLParser>> reference = WeakReference<Backgr
oundHTMLParser>::createUnbound(); |
710 m_backgroundParser = WeakPtr<BackgroundHTMLParser>(reference); | 712 m_backgroundParser = WeakPtr<BackgroundHTMLParser>(reference); |
711 | 713 |
712 OwnPtr<BackgroundHTMLParser::Configuration> config = adoptPtr(new Background
HTMLParser::Configuration); | 714 std::unique_ptr<BackgroundHTMLParser::Configuration> config = wrapUnique(new
BackgroundHTMLParser::Configuration); |
713 config->options = m_options; | 715 config->options = m_options; |
714 config->parser = m_weakFactory.createWeakPtr(); | 716 config->parser = m_weakFactory.createWeakPtr(); |
715 config->xssAuditor = adoptPtr(new XSSAuditor); | 717 config->xssAuditor = wrapUnique(new XSSAuditor); |
716 config->xssAuditor->init(document(), &m_xssAuditorDelegate); | 718 config->xssAuditor->init(document(), &m_xssAuditorDelegate); |
717 | 719 |
718 config->decoder = takeDecoder(); | 720 config->decoder = takeDecoder(); |
719 config->parsedChunkQueue = m_parsedChunkQueue.get(); | 721 config->parsedChunkQueue = m_parsedChunkQueue.get(); |
720 if (document()->settings()) { | 722 if (document()->settings()) { |
721 if (document()->settings()->backgroundHtmlParserOutstandingTokenLimit()) | 723 if (document()->settings()->backgroundHtmlParserOutstandingTokenLimit()) |
722 config->outstandingTokenLimit = document()->settings()->backgroundHt
mlParserOutstandingTokenLimit(); | 724 config->outstandingTokenLimit = document()->settings()->backgroundHt
mlParserOutstandingTokenLimit(); |
723 if (document()->settings()->backgroundHtmlParserPendingTokenLimit()) | 725 if (document()->settings()->backgroundHtmlParserPendingTokenLimit()) |
724 config->pendingTokenLimit = document()->settings()->backgroundHtmlPa
rserPendingTokenLimit(); | 726 config->pendingTokenLimit = document()->settings()->backgroundHtmlPa
rserPendingTokenLimit(); |
725 } | 727 } |
726 | 728 |
727 ASSERT(config->xssAuditor->isSafeToSendToAnotherThread()); | 729 ASSERT(config->xssAuditor->isSafeToSendToAnotherThread()); |
728 HTMLParserThread::shared()->postTask(threadSafeBind( | 730 HTMLParserThread::shared()->postTask(threadSafeBind( |
729 &BackgroundHTMLParser::start, | 731 &BackgroundHTMLParser::start, |
730 reference.release(), | 732 reference.release(), |
731 passed(std::move(config)), | 733 passed(std::move(config)), |
732 document()->url(), | 734 document()->url(), |
733 passed(CachedDocumentParameters::create(document())), | 735 passed(CachedDocumentParameters::create(document())), |
734 MediaValuesCached::MediaValuesCachedData(*document()), | 736 MediaValuesCached::MediaValuesCachedData(*document()), |
735 passed(adoptPtr(m_loadingTaskRunner->clone())))); | 737 passed(wrapUnique(m_loadingTaskRunner->clone())))); |
736 } | 738 } |
737 | 739 |
738 void HTMLDocumentParser::stopBackgroundParser() | 740 void HTMLDocumentParser::stopBackgroundParser() |
739 { | 741 { |
740 ASSERT(shouldUseThreading()); | 742 ASSERT(shouldUseThreading()); |
741 ASSERT(m_haveBackgroundParser); | 743 ASSERT(m_haveBackgroundParser); |
742 m_haveBackgroundParser = false; | 744 m_haveBackgroundParser = false; |
743 | 745 |
744 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParser::s
top, m_backgroundParser)); | 746 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParser::s
top, m_backgroundParser)); |
745 m_weakFactory.revokeAll(); | 747 m_weakFactory.revokeAll(); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
851 m_input.closeWithoutMarkingEndOfFile(); | 853 m_input.closeWithoutMarkingEndOfFile(); |
852 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::finish, m_backgroundParser)); | 854 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::finish, m_backgroundParser)); |
853 return; | 855 return; |
854 } | 856 } |
855 | 857 |
856 if (!m_tokenizer) { | 858 if (!m_tokenizer) { |
857 ASSERT(!m_token); | 859 ASSERT(!m_token); |
858 // We're finishing before receiving any data. Rather than booting up | 860 // We're finishing before receiving any data. Rather than booting up |
859 // the background parser just to spin it down, we finish parsing | 861 // the background parser just to spin it down, we finish parsing |
860 // synchronously. | 862 // synchronously. |
861 m_token = adoptPtr(new HTMLToken); | 863 m_token = wrapUnique(new HTMLToken); |
862 m_tokenizer = HTMLTokenizer::create(m_options); | 864 m_tokenizer = HTMLTokenizer::create(m_options); |
863 } | 865 } |
864 | 866 |
865 // We're not going to get any more data off the network, so we tell the | 867 // We're not going to get any more data off the network, so we tell the |
866 // input stream we've reached the end of file. finish() can be called more | 868 // input stream we've reached the end of file. finish() can be called more |
867 // than once, if the first time does not call end(). | 869 // than once, if the first time does not call end(). |
868 if (!m_input.haveSeenEndOfFile()) | 870 if (!m_input.haveSeenEndOfFile()) |
869 m_input.markEndOfFile(); | 871 m_input.markEndOfFile(); |
870 | 872 |
871 attemptToEnd(); | 873 attemptToEnd(); |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1003 | 1005 |
1004 void HTMLDocumentParser::appendBytes(const char* data, size_t length) | 1006 void HTMLDocumentParser::appendBytes(const char* data, size_t length) |
1005 { | 1007 { |
1006 if (!length || isStopped()) | 1008 if (!length || isStopped()) |
1007 return; | 1009 return; |
1008 | 1010 |
1009 if (shouldUseThreading()) { | 1011 if (shouldUseThreading()) { |
1010 if (!m_haveBackgroundParser) | 1012 if (!m_haveBackgroundParser) |
1011 startBackgroundParser(); | 1013 startBackgroundParser(); |
1012 | 1014 |
1013 OwnPtr<Vector<char>> buffer = adoptPtr(new Vector<char>(length)); | 1015 std::unique_ptr<Vector<char>> buffer = wrapUnique(new Vector<char>(lengt
h)); |
1014 memcpy(buffer->data(), data, length); | 1016 memcpy(buffer->data(), data, length); |
1015 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); |
1016 | 1018 |
1017 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::appendRawBytesFromMainThread, m_backgroundParser, passed(std::move(buffer))))
; | 1019 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::appendRawBytesFromMainThread, m_backgroundParser, passed(std::move(buffer))))
; |
1018 return; | 1020 return; |
1019 } | 1021 } |
1020 | 1022 |
1021 DecodedDataDocumentParser::appendBytes(data, length); | 1023 DecodedDataDocumentParser::appendBytes(data, length); |
1022 } | 1024 } |
1023 | 1025 |
1024 void HTMLDocumentParser::flush() | 1026 void HTMLDocumentParser::flush() |
1025 { | 1027 { |
1026 // If we've got no decoder, we never received any data. | 1028 // If we've got no decoder, we never received any data. |
1027 if (isDetached() || needsDecoder()) | 1029 if (isDetached() || needsDecoder()) |
1028 return; | 1030 return; |
1029 | 1031 |
1030 if (shouldUseThreading()) { | 1032 if (shouldUseThreading()) { |
1031 // In some cases, flush() is called without any invocation of | 1033 // In some cases, flush() is called without any invocation of |
1032 // appendBytes. Fallback to synchronous parsing in that case. | 1034 // appendBytes. Fallback to synchronous parsing in that case. |
1033 if (!m_haveBackgroundParser) { | 1035 if (!m_haveBackgroundParser) { |
1034 m_shouldUseThreading = false; | 1036 m_shouldUseThreading = false; |
1035 m_token = adoptPtr(new HTMLToken); | 1037 m_token = wrapUnique(new HTMLToken); |
1036 m_tokenizer = HTMLTokenizer::create(m_options); | 1038 m_tokenizer = HTMLTokenizer::create(m_options); |
1037 DecodedDataDocumentParser::flush(); | 1039 DecodedDataDocumentParser::flush(); |
1038 return; | 1040 return; |
1039 } | 1041 } |
1040 | 1042 |
1041 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::flush, m_backgroundParser)); | 1043 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::flush, m_backgroundParser)); |
1042 } else { | 1044 } else { |
1043 DecodedDataDocumentParser::flush(); | 1045 DecodedDataDocumentParser::flush(); |
1044 } | 1046 } |
1045 } | 1047 } |
1046 | 1048 |
1047 void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder) | 1049 void HTMLDocumentParser::setDecoder(std::unique_ptr<TextResourceDecoder> decoder
) |
1048 { | 1050 { |
1049 ASSERT(decoder); | 1051 ASSERT(decoder); |
1050 DecodedDataDocumentParser::setDecoder(std::move(decoder)); | 1052 DecodedDataDocumentParser::setDecoder(std::move(decoder)); |
1051 | 1053 |
1052 if (m_haveBackgroundParser) | 1054 if (m_haveBackgroundParser) |
1053 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::setDecoder, m_backgroundParser, passed(takeDecoder()))); | 1055 HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParse
r::setDecoder, m_backgroundParser, passed(takeDecoder()))); |
1054 } | 1056 } |
1055 | 1057 |
1056 void HTMLDocumentParser::documentElementAvailable() | 1058 void HTMLDocumentParser::documentElementAvailable() |
1057 { | 1059 { |
1058 TRACE_EVENT0("blink,loader", "HTMLDocumentParser::documentElementAvailable")
; | 1060 TRACE_EVENT0("blink,loader", "HTMLDocumentParser::documentElementAvailable")
; |
1059 DCHECK(document()->documentElement()); | 1061 DCHECK(document()->documentElement()); |
1060 for (const String& scriptSource : m_queuedDocumentWriteScripts) { | 1062 for (const String& scriptSource : m_queuedDocumentWriteScripts) { |
1061 evaluateAndPreloadScriptForDocumentWrite(scriptSource); | 1063 evaluateAndPreloadScriptForDocumentWrite(scriptSource); |
1062 } | 1064 } |
1063 | 1065 |
1064 m_queuedDocumentWriteScripts.clear(); | 1066 m_queuedDocumentWriteScripts.clear(); |
1065 if (!m_queuedPreloads.isEmpty()) | 1067 if (!m_queuedPreloads.isEmpty()) |
1066 m_preloader->takeAndPreload(m_queuedPreloads); | 1068 m_preloader->takeAndPreload(m_queuedPreloads); |
1067 } | 1069 } |
1068 | 1070 |
1069 PassOwnPtr<HTMLPreloadScanner> HTMLDocumentParser::createPreloadScanner() | 1071 std::unique_ptr<HTMLPreloadScanner> HTMLDocumentParser::createPreloadScanner() |
1070 { | 1072 { |
1071 return HTMLPreloadScanner::create( | 1073 return HTMLPreloadScanner::create( |
1072 m_options, | 1074 m_options, |
1073 document()->url(), | 1075 document()->url(), |
1074 CachedDocumentParameters::create(document()), | 1076 CachedDocumentParameters::create(document()), |
1075 MediaValuesCached::MediaValuesCachedData(*document())); | 1077 MediaValuesCached::MediaValuesCachedData(*document())); |
1076 } | 1078 } |
1077 | 1079 |
1078 void HTMLDocumentParser::evaluateAndPreloadScriptForDocumentWrite(const String&
source) | 1080 void HTMLDocumentParser::evaluateAndPreloadScriptForDocumentWrite(const String&
source) |
1079 { | 1081 { |
1080 if (!m_evaluator->shouldEvaluate(source)) | 1082 if (!m_evaluator->shouldEvaluate(source)) |
1081 return; | 1083 return; |
1082 document()->loader()->didObserveLoadingBehavior(WebLoadingBehaviorFlag::WebL
oadingBehaviorDocumentWriteEvaluator); | 1084 document()->loader()->didObserveLoadingBehavior(WebLoadingBehaviorFlag::WebL
oadingBehaviorDocumentWriteEvaluator); |
1083 if (!RuntimeEnabledFeatures::documentWriteEvaluatorEnabled()) | 1085 if (!RuntimeEnabledFeatures::documentWriteEvaluatorEnabled()) |
1084 return; | 1086 return; |
1085 TRACE_EVENT0("blink", "HTMLDocumentParser::evaluateAndPreloadScriptForDocume
ntWrite"); | 1087 TRACE_EVENT0("blink", "HTMLDocumentParser::evaluateAndPreloadScriptForDocume
ntWrite"); |
1086 | 1088 |
1087 double initializeStartTime = monotonicallyIncreasingTimeMS(); | 1089 double initializeStartTime = monotonicallyIncreasingTimeMS(); |
1088 bool neededInitialization = m_evaluator->ensureEvaluationContext(); | 1090 bool neededInitialization = m_evaluator->ensureEvaluationContext(); |
1089 double initializationDuration = monotonicallyIncreasingTimeMS() - initialize
StartTime; | 1091 double initializationDuration = monotonicallyIncreasingTimeMS() - initialize
StartTime; |
1090 | 1092 |
1091 double startTime = monotonicallyIncreasingTimeMS(); | 1093 double startTime = monotonicallyIncreasingTimeMS(); |
1092 String writtenSource = m_evaluator->evaluateAndEmitWrittenSource(source); | 1094 String writtenSource = m_evaluator->evaluateAndEmitWrittenSource(source); |
1093 double duration = monotonicallyIncreasingTimeMS() - startTime; | 1095 double duration = monotonicallyIncreasingTimeMS() - startTime; |
1094 | 1096 |
1095 int currentPreloadCount = document()->loader()->fetcher()->countPreloads(); | 1097 int currentPreloadCount = document()->loader()->fetcher()->countPreloads(); |
1096 OwnPtr<HTMLPreloadScanner> scanner = createPreloadScanner(); | 1098 std::unique_ptr<HTMLPreloadScanner> scanner = createPreloadScanner(); |
1097 scanner->appendToEnd(SegmentedString(writtenSource)); | 1099 scanner->appendToEnd(SegmentedString(writtenSource)); |
1098 scanner->scanAndPreload(m_preloader.get(), document()->baseElementURL(), nul
lptr); | 1100 scanner->scanAndPreload(m_preloader.get(), document()->baseElementURL(), nul
lptr); |
1099 int numPreloads = document()->loader()->fetcher()->countPreloads() - current
PreloadCount; | 1101 int numPreloads = document()->loader()->fetcher()->countPreloads() - current
PreloadCount; |
1100 | 1102 |
1101 TRACE_EVENT_INSTANT2("blink", "HTMLDocumentParser::evaluateAndPreloadScriptF
orDocumentWrite.data", TRACE_EVENT_SCOPE_THREAD, "numPreloads", numPreloads, "sc
riptLength", source.length()); | 1103 TRACE_EVENT_INSTANT2("blink", "HTMLDocumentParser::evaluateAndPreloadScriptF
orDocumentWrite.data", TRACE_EVENT_SCOPE_THREAD, "numPreloads", numPreloads, "sc
riptLength", source.length()); |
1102 | 1104 |
1103 if (neededInitialization) { | 1105 if (neededInitialization) { |
1104 DEFINE_STATIC_LOCAL(CustomCountHistogram, initializeHistograms, ("Preloa
dScanner.DocumentWrite.InitializationTime", 1, 10000, 50)); | 1106 DEFINE_STATIC_LOCAL(CustomCountHistogram, initializeHistograms, ("Preloa
dScanner.DocumentWrite.InitializationTime", 1, 10000, 50)); |
1105 initializeHistograms.count(initializationDuration); | 1107 initializeHistograms.count(initializationDuration); |
1106 } | 1108 } |
1107 | 1109 |
1108 if (numPreloads) { | 1110 if (numPreloads) { |
1109 DEFINE_STATIC_LOCAL(CustomCountHistogram, successHistogram, ("PreloadSca
nner.DocumentWrite.ExecutionTime.Success", 1, 10000, 50)); | 1111 DEFINE_STATIC_LOCAL(CustomCountHistogram, successHistogram, ("PreloadSca
nner.DocumentWrite.ExecutionTime.Success", 1, 10000, 50)); |
1110 successHistogram.count(duration); | 1112 successHistogram.count(duration); |
1111 } else { | 1113 } else { |
1112 DEFINE_STATIC_LOCAL(CustomCountHistogram, failureHistogram, ("PreloadSca
nner.DocumentWrite.ExecutionTime.Failure", 1, 10000, 50)); | 1114 DEFINE_STATIC_LOCAL(CustomCountHistogram, failureHistogram, ("PreloadSca
nner.DocumentWrite.ExecutionTime.Failure", 1, 10000, 50)); |
1113 failureHistogram.count(duration); | 1115 failureHistogram.count(duration); |
1114 } | 1116 } |
1115 | 1117 |
1116 } | 1118 } |
1117 | 1119 |
1118 } // namespace blink | 1120 } // namespace blink |
OLD | NEW |