Changeset 141328 in webkit
- Timestamp:
- Jan 30, 2013 3:16:03 PM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r141327 r141328 1 2013-01-30 Adam Barth <abarth@webkit.org> 2 3 HTMLDocumentParser::insert should be aware of threaded parsing 4 https://bugs.webkit.org/show_bug.cgi?id=107764 5 6 Reviewed by Eric Seidel. 7 8 This patch is an incremental step towards recovering from 9 document.write invalidating our speculative parsing buffer. The 10 approach I've taken is to make it possible to transfer the 11 HTMLDocumentParser's HTMLTokenizer and HTMLToken to the background 12 thread. To make that possible, I've taught the HTMLDocumentParser how 13 to operate without a tokenizer or a token. 14 15 Not having a tokenizer or a token while parsing in the background also 16 helps us avoid accidentially feeding input to the main thread's 17 tokenizer when we're supposed to feed it to the background thread. 18 19 This patch shouldn't have any behavior change (other than possibly 20 fixing a crash in fast/parser when threading parsing is enabled). 21 22 * html/parser/HTMLDocumentParser.cpp: 23 (WebCore::HTMLDocumentParser::HTMLDocumentParser): 24 (WebCore::HTMLDocumentParser::didFailSpeculation): 25 (WebCore): 26 (WebCore::HTMLDocumentParser::insert): 27 (WebCore::HTMLDocumentParser::finish): 28 (WebCore::HTMLDocumentParser::resumeParsingAfterScriptExecution): 29 * html/parser/HTMLDocumentParser.h: 30 (HTMLDocumentParser): 31 * html/parser/HTMLTreeBuilder.cpp: 32 (WebCore::HTMLTreeBuilder::constructTree): 33 (WebCore::HTMLTreeBuilder::processStartTagForInBody): 34 (WebCore::HTMLTreeBuilder::processEndTag): 35 (WebCore::HTMLTreeBuilder::processGenericRCDATAStartTag): 36 (WebCore::HTMLTreeBuilder::processGenericRawTextStartTag): 37 (WebCore::HTMLTreeBuilder::processScriptStartTag): 38 * html/parser/TextDocumentParser.cpp: 39 (WebCore::TextDocumentParser::TextDocumentParser): 40 1 41 2013-01-30 Rafael Weinstein <rafaelw@chromium.org> 2 42 -
trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp
r141071 r141328 78 78 : ScriptableDocumentParser(document) 79 79 , m_options(document) 80 , m_token( adoptPtr(new HTMLToken))81 , m_tokenizer( HTMLTokenizer::create(m_options))80 , m_token(m_options.useThreading ? nullptr : adoptPtr(new HTMLToken)) 81 , m_tokenizer(m_options.useThreading ? nullptr : HTMLTokenizer::create(m_options)) 82 82 , m_scriptRunner(HTMLScriptRunner::create(document, this)) 83 83 , m_treeBuilder(HTMLTreeBuilder::create(this, document, reportErrors, m_options)) … … 91 91 , m_pumpSessionNestingLevel(0) 92 92 { 93 ASSERT(shouldUseThreading() || (m_token && m_tokenizer)); 93 94 } 94 95 … … 109 110 , m_pumpSessionNestingLevel(0) 110 111 { 112 ASSERT(!shouldUseThreading()); 111 113 bool reportErrors = false; // For now document fragment parsing never reports errors. 112 114 m_tokenizer->setState(tokenizerStateForContextElement(contextElement, reportErrors, m_options)); … … 283 285 ASSERT(m_pendingTokens.isEmpty()); 284 286 processTokensFromBackgroundParser(tokens); 287 } 288 289 void HTMLDocumentParser::didFailSpeculation(PassOwnPtr<HTMLToken>, PassOwnPtr<HTMLTokenizer>) 290 { 291 // FIXME: Tell the background parser to resume parsing with this token and tokenizer. 285 292 } 286 293 … … 447 454 RefPtr<HTMLDocumentParser> protect(this); 448 455 456 #if ENABLE(THREADED_HTML_PARSER) 457 if (!m_tokenizer) { 458 ASSERT(!inPumpSession()); 459 ASSERT(m_haveBackgroundParser || wasCreatedByScript()); 460 m_token = adoptPtr(new HTMLToken); 461 m_tokenizer = HTMLTokenizer::create(m_options); 462 } 463 #endif 464 449 465 SegmentedString excludedLineNumberSource(source); 450 466 excludedLineNumberSource.setExcludeLineNumbers(); 451 467 m_input.insertAtCurrentInsertionPoint(excludedLineNumberSource); 452 468 pumpTokenizerIfPossible(ForceSynchronous); 453 469 470 #if ENABLE(THREADED_HTML_PARSER) 471 if (!inPumpSession() && m_haveBackgroundParser) { 472 // FIXME: If the tokenizer is in the same state as when we started this function, 473 // then we haven't necessarily failed our speculation. 474 didFailSpeculation(m_token.release(), m_tokenizer.release()); 475 return; 476 } 477 #endif 478 454 479 if (isWaitingForScripts()) { 455 480 // Check the document.write() output with a separate preload scanner as … … 604 629 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::finishPartial, ParserMap::identifierForParser(this))); 605 630 return; 631 } 632 if (shouldUseThreading() && !wasCreatedByScript()) { 633 ASSERT(!m_tokenizer && !m_token); 634 // We're finishing before receiving any data. Rather than booting up 635 // the background parser just to spin it down, we finish parsing 636 // synchronously. 637 m_token = adoptPtr(new HTMLToken); 638 m_tokenizer = HTMLTokenizer::create(m_options); 606 639 } 607 640 #endif … … 671 704 while (!m_pendingTokens.isEmpty()) { 672 705 processTokensFromBackgroundParser(m_pendingTokens.takeFirst()); 673 if (isWaitingForScripts() )706 if (isWaitingForScripts() || isStopped()) 674 707 return; 675 708 } -
trunk/Source/WebCore/html/parser/HTMLDocumentParser.h
r141070 r141328 125 125 void startBackgroundParser(); 126 126 void stopBackgroundParser(); 127 void didFailSpeculation(PassOwnPtr<HTMLToken>, PassOwnPtr<HTMLTokenizer>); 127 128 void processTokensFromBackgroundParser(PassOwnPtr<CompactHTMLTokenStream>); 128 129 #endif -
trunk/Source/WebCore/html/parser/HTMLTreeBuilder.cpp
r141327 r141328 368 368 processToken(token); 369 369 370 bool inForeignContent = !m_tree.isEmpty() 371 && !m_tree.currentStackItem()->isInHTMLNamespace() 372 && !HTMLElementStack::isHTMLIntegrationPoint(m_tree.currentStackItem()) 373 && !HTMLElementStack::isMathMLTextIntegrationPoint(m_tree.currentStackItem()); 374 375 m_parser->tokenizer()->setForceNullCharacterReplacement(m_insertionMode == TextMode || inForeignContent); 376 m_parser->tokenizer()->setShouldAllowCDATA(inForeignContent); 370 if (m_parser->tokenizer()) { 371 bool inForeignContent = !m_tree.isEmpty() 372 && !m_tree.currentStackItem()->isInHTMLNamespace() 373 && !HTMLElementStack::isHTMLIntegrationPoint(m_tree.currentStackItem()) 374 && !HTMLElementStack::isMathMLTextIntegrationPoint(m_tree.currentStackItem()); 375 376 m_parser->tokenizer()->setForceNullCharacterReplacement(m_insertionMode == TextMode || inForeignContent); 377 m_parser->tokenizer()->setShouldAllowCDATA(inForeignContent); 378 } 377 379 378 380 m_tree.executeQueuedTasks(); … … 741 743 processFakePEndTagIfPInButtonScope(); 742 744 m_tree.insertHTMLElement(token); 743 m_parser->tokenizer()->setState(HTMLTokenizerState::PLAINTEXTState); 745 if (m_parser->tokenizer()) 746 m_parser->tokenizer()->setState(HTMLTokenizerState::PLAINTEXTState); 744 747 return; 745 748 } … … 851 854 m_tree.insertHTMLElement(token); 852 855 m_shouldSkipLeadingNewline = true; 853 m_parser->tokenizer()->setState(HTMLTokenizerState::RCDATAState); 856 if (m_parser->tokenizer()) 857 m_parser->tokenizer()->setState(HTMLTokenizerState::RCDATAState); 854 858 m_originalInsertionMode = m_insertionMode; 855 859 m_framesetOk = false; … … 2164 2168 setInsertionMode(m_originalInsertionMode); 2165 2169 2166 // This token will not have been created by the tokenizer if a 2167 // self-closing script tag was encountered and pre-HTML5 parser 2168 // quirks are enabled. We must set the tokenizer's state to 2169 // DataState explicitly if the tokenizer didn't have a chance to. 2170 ASSERT(m_parser->tokenizer()->state() == HTMLTokenizerState::DataState || m_options.usePreHTML5ParserQuirks || m_options.useThreading); 2171 m_parser->tokenizer()->setState(HTMLTokenizerState::DataState); 2170 if (m_parser->tokenizer()) { 2171 // This token will not have been created by the tokenizer if a 2172 // self-closing script tag was encountered and pre-HTML5 parser 2173 // quirks are enabled. We must set the tokenizer's state to 2174 // DataState explicitly if the tokenizer didn't have a chance to. 2175 ASSERT(m_parser->tokenizer()->state() == HTMLTokenizerState::DataState || m_options.usePreHTML5ParserQuirks || m_options.useThreading); 2176 m_parser->tokenizer()->setState(HTMLTokenizerState::DataState); 2177 } 2172 2178 return; 2173 2179 } … … 2707 2713 ASSERT(token->type() == HTMLTokenTypes::StartTag); 2708 2714 m_tree.insertHTMLElement(token); 2709 m_parser->tokenizer()->setState(HTMLTokenizerState::RCDATAState); 2715 if (m_parser->tokenizer()) 2716 m_parser->tokenizer()->setState(HTMLTokenizerState::RCDATAState); 2710 2717 m_originalInsertionMode = m_insertionMode; 2711 2718 setInsertionMode(TextMode); … … 2716 2723 ASSERT(token->type() == HTMLTokenTypes::StartTag); 2717 2724 m_tree.insertHTMLElement(token); 2718 m_parser->tokenizer()->setState(HTMLTokenizerState::RAWTEXTState); 2725 if (m_parser->tokenizer()) 2726 m_parser->tokenizer()->setState(HTMLTokenizerState::RAWTEXTState); 2719 2727 m_originalInsertionMode = m_insertionMode; 2720 2728 setInsertionMode(TextMode); … … 2725 2733 ASSERT(token->type() == HTMLTokenTypes::StartTag); 2726 2734 m_tree.insertScriptElement(token); 2727 m_parser->tokenizer()->setState(HTMLTokenizerState::ScriptDataState); 2735 if (m_parser->tokenizer()) 2736 m_parser->tokenizer()->setState(HTMLTokenizerState::ScriptDataState); 2728 2737 m_originalInsertionMode = m_insertionMode; 2729 2738 -
trunk/Source/WebCore/html/parser/TextDocumentParser.cpp
r139523 r141328 39 39 , m_haveInsertedFakePreElement(false) 40 40 { 41 tokenizer()->setState(HTMLTokenizerState::PLAINTEXTState); 41 // FIXME: If we're using threading, we need to tell the BackgroundHTMLParser to use PLAINTEXTState. 42 if (tokenizer()) 43 tokenizer()->setState(HTMLTokenizerState::PLAINTEXTState); 42 44 } 43 45
Note: See TracChangeset
for help on using the changeset viewer.