Changeset 140055 in webkit
- Timestamp:
- Jan 17, 2013 3:06:00 PM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r140050 r140055 1 2013-01-17 Eric Seidel <eric@webkit.org> 2 3 Threaded parser hangs when encountering an unmatched </script> tag 4 https://bugs.webkit.org/show_bug.cgi?id=107170 5 6 Reviewed by Adam Barth. 7 8 The bug was that the BackgroundHTMLParser naively yields to the 9 main thread every time it encounters a </script> 10 (as we may have to run script on the main thread). However, not every 11 </script> results in script execution, so the main thread needs to know 12 how to tell the BackgroundHTMLParser to continue in cases where no 13 script execution is needed. 14 15 This whole infrastructure will be replaced when we let the BackgroundHTMLParser 16 continue speculatively tokenizing after yielding. 17 18 * html/parser/BackgroundHTMLParser.cpp: 19 (WebCore::TokenDelivery::TokenDelivery): 20 (TokenDelivery): 21 (WebCore::TokenDelivery::execute): 22 (WebCore::BackgroundHTMLParser::sendTokensToMainThread): 23 * html/parser/HTMLDocumentParser.cpp: 24 (WebCore::HTMLDocumentParser::didReceiveTokensFromBackgroundParser): 25 * html/parser/HTMLDocumentParser.h: 26 (HTMLDocumentParser): 27 1 28 2013-01-17 Eric Seidel <eric@webkit.org> 2 29 -
trunk/Source/WebCore/html/parser/BackgroundHTMLParser.cpp
r139954 r140055 170 170 WTF_MAKE_NONCOPYABLE(TokenDelivery); 171 171 public: 172 TokenDelivery() { } 172 TokenDelivery() 173 : identifier(0) 174 , isPausedWaitingForScripts(false) 175 { 176 } 173 177 174 178 ParserIdentifier identifier; 175 179 Vector<CompactHTMLToken> tokens; 180 // FIXME: This bool will be replaced by a CheckPoint object once 181 // we implement speculative parsing. Then the main thread will decide 182 // to either accept the speculative tokens we've already given it 183 // (or ask for them, depending on who ends up owning them), or send 184 // us a "reset to checkpoint message". 185 bool isPausedWaitingForScripts; 176 186 177 187 static void execute(void* context) … … 180 190 HTMLDocumentParser* parser = parserMap().mainThreadParsers().get(delivery->identifier); 181 191 if (parser) 182 parser->didReceiveTokensFromBackgroundParser(delivery->tokens );192 parser->didReceiveTokensFromBackgroundParser(delivery->tokens, delivery->isPausedWaitingForScripts); 183 193 // FIXME: Ideally we wouldn't need to call delete manually. Instead 184 194 // we would like an API where the message queue owns the tasks and … … 193 203 delivery->identifier = m_parserIdentifer; 194 204 delivery->tokens.swap(m_pendingTokens); 205 delivery->isPausedWaitingForScripts = m_isPausedWaitingForScripts; 195 206 callOnMainThread(TokenDelivery::execute, delivery); 196 207 } -
trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp
r140050 r140055 260 260 #if ENABLE(THREADED_HTML_PARSER) 261 261 262 void HTMLDocumentParser::didReceiveTokensFromBackgroundParser(const Vector<CompactHTMLToken>& tokens )262 void HTMLDocumentParser::didReceiveTokensFromBackgroundParser(const Vector<CompactHTMLToken>& tokens, bool threadIsWaitingForScripts) 263 263 { 264 264 ASSERT(shouldUseThreading()); 265 265 266 // feedTokenscan cause this parser to be detached from the Document,266 // didReceiveTokensFromBackgroundParser can cause this parser to be detached from the Document, 267 267 // but we need to ensure it isn't deleted yet. 268 268 RefPtr<HTMLDocumentParser> protect(this); … … 283 283 284 284 if (isWaitingForScripts()) { 285 ASSERT(threadIsWaitingForScripts); // We expect that the thread is waiting for us. 285 286 runScriptsForPausedTreeBuilder(); 286 287 if (!isWaitingForScripts()) { … … 288 289 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::continuePartial, identifier)); 289 290 } 291 ASSERT(it + 1 == tokens.end()); // The </script> is assumed to be the last token of this bunch. 292 return; 290 293 } 291 294 … … 295 298 // attemptToEnd() instead. 296 299 if (it->type() == HTMLTokenTypes::EndOfFile) { 300 ASSERT(it + 1 == tokens.end()); // The EOF is assumed to be the last token of this bunch. 297 301 DocumentParser::prepareToStopParsing(); 298 302 document()->setReadyState(Document::Interactive); 299 303 end(); 304 return; 300 305 } 306 } 307 308 // If we got here and the parser thread is still waiting for scripts, then it paused unnecessarily 309 // (as can happen with a stray </script> tag), and we need to tell it to continue. 310 if (threadIsWaitingForScripts) { 311 ParserIdentifier identifier = ParserMap::identifierForParser(this); 312 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::continuePartial, identifier)); 301 313 } 302 314 } -
trunk/Source/WebCore/html/parser/HTMLDocumentParser.h
r140036 r140055 80 80 81 81 #if ENABLE(THREADED_HTML_PARSER) 82 void didReceiveTokensFromBackgroundParser(const Vector<CompactHTMLToken>& );82 void didReceiveTokensFromBackgroundParser(const Vector<CompactHTMLToken>&, bool threadIsWaitingForScripts); 83 83 #endif 84 84
Note: See TracChangeset
for help on using the changeset viewer.