Changeset 147383 in webkit
- Timestamp:
- Apr 1, 2013 10:34:38 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r147382 r147383 1 2013-04-01 Adam Barth <abarth@webkit.org> 2 3 Assertion failure !m_lastChunkBeforeScript in HTMLDocumentParser during inspector/debugger/pause-in-inline-script.html 4 https://bugs.webkit.org/show_bug.cgi?id=112369 5 6 Reviewed by Eric Seidel. 7 8 Unskip test that is now passing. 9 10 * platform/chromium/TestExpectations: 11 1 12 2013-04-01 Michael Pruett <michael@68k.org> 2 13 -
trunk/LayoutTests/platform/chromium/TestExpectations
r147380 r147383 3784 3784 webkit.org/b/91611 media/media-higher-prio-audio-stream.html [ Skip ] 3785 3785 3786 # Flaky assertion failures on debug bots3787 webkit.org/b/112369 [ Debug ] inspector/debugger/pause-in-inline-script.html [ Pass Crash Timeout ]3788 3789 3786 # Needs rebaseline on all platforms 3790 3787 Bug(leviw) fast/text/shaping/shaping-selection-rect.html [ Failure ] -
trunk/Source/WebCore/ChangeLog
r147382 r147383 1 2013-04-01 Adam Barth <abarth@webkit.org> 2 3 Assertion failure !m_lastChunkBeforeScript in HTMLDocumentParser during inspector/debugger/pause-in-inline-script.html 4 https://bugs.webkit.org/show_bug.cgi?id=112369 5 6 Reviewed by Eric Seidel. 7 8 The threaded HTML parser wasn't correctly handling the nested event 9 loops that can arise from the JavaScript debugger and from 10 showModalDialog. When the parser received a chunk from the background 11 parser, it was always processing it immediately, which lead to 12 re-entrancy. Now, we'll queue the chunk in the speculation buffer and 13 process it once the stack unwinds. 14 15 * html/parser/HTMLDocumentParser.cpp: 16 (WebCore::HTMLDocumentParser::~HTMLDocumentParser): 17 (WebCore::HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser): 18 (WebCore::HTMLDocumentParser::processParsedChunkFromBackgroundParser): 19 (WebCore::HTMLDocumentParser::pumpPendingSpeculations): 20 (WebCore::HTMLDocumentParser::insert): 21 * html/parser/HTMLParserScheduler.cpp: 22 (WebCore::PumpSession::PumpSession): 23 * html/parser/HTMLParserScheduler.h: 24 1 25 2013-04-01 Michael Pruett <michael@68k.org> 2 26 -
trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp
r146264 r147383 128 128 ASSERT(!m_insertionPreloadScanner); 129 129 ASSERT(!m_haveBackgroundParser); 130 // FIXME: We should be able to ASSERT(m_speculations.isEmpty()), 131 // but there are cases where that's not true currently. For example, 132 // we we're told to stop parsing before we've consumed all the input. 130 133 } 131 134 … … 312 315 void HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(PassOwnPtr<ParsedChunk> chunk) 313 316 { 314 if (isWaitingForScripts() || !m_speculations.isEmpty()) { 317 // alert(), runModalDialog, and the JavaScript Debugger all run nested event loops 318 // which can cause this method to be re-entered. We detect re-entry using 319 // inPumpSession(), save the chunk as a speculation, and return. 320 if (isWaitingForScripts() || !m_speculations.isEmpty() || inPumpSession()) { 315 321 m_preloader->takeAndPreload(chunk->preloads); 316 322 m_speculations.append(chunk); … … 322 328 RefPtr<HTMLDocumentParser> protect(this); 323 329 324 InspectorInstrumentationCookie cookie = InspectorInstrumentation::willWriteHTML(document(), lineNumber().zeroBasedInt());325 326 330 ASSERT(m_speculations.isEmpty()); 327 331 chunk->preloads.clear(); // We don't need to preload because we're going to parse immediately. 328 processParsedChunkFromBackgroundParser(chunk); 329 330 InspectorInstrumentation::didWriteHTML(cookie, lineNumber().zeroBasedInt()); 332 m_speculations.append(chunk); 333 pumpPendingSpeculations(); 331 334 } 332 335 … … 391 394 void HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<ParsedChunk> popChunk) 392 395 { 396 ASSERT_WITH_SECURITY_IMPLICATION(!inPumpSession()); 397 ASSERT(!isParsingFragment()); 398 ASSERT(!isWaitingForScripts()); 399 ASSERT(!isStopped()); 393 400 // ASSERT that this object is both attached to the Document and protected. 394 401 ASSERT(refCount() >= 2); … … 398 405 ASSERT(!m_lastChunkBeforeScript); 399 406 400 ActiveParserSession session(contextForParsingSession()); 407 PumpSession session(m_pumpSessionNestingLevel, contextForParsingSession()); 408 401 409 OwnPtr<ParsedChunk> chunk(popChunk); 402 410 OwnPtr<CompactHTMLTokenStream> tokens = chunk->tokens.release(); … … 427 435 // we peek to see if this chunk has an EOF and process it anyway. 428 436 if (tokens->last().type() == HTMLToken::EndOfFile) { 429 ASSERT(m_speculations.isEmpty()); 437 ASSERT(m_speculations.isEmpty()); // There should never be any chunks after the EOF. 430 438 prepareToStopParsing(); 431 439 } … … 442 450 if (it->type() == HTMLToken::EndOfFile) { 443 451 ASSERT(it + 1 == tokens->end()); // The EOF is assumed to be the last token of this bunch. 444 ASSERT(m_speculations.isEmpty()); 452 ASSERT(m_speculations.isEmpty()); // There should never be any chunks after the EOF. 445 453 prepareToStopParsing(); 446 454 break; … … 464 472 ASSERT(!m_token); 465 473 ASSERT(!m_lastChunkBeforeScript); 474 ASSERT(!isWaitingForScripts()); 475 ASSERT(!isStopped()); 466 476 467 477 // FIXME: Pass in current input length. … … 630 640 #if ENABLE(THREADED_HTML_PARSER) 631 641 if (!m_tokenizer) { 632 ASSERT(!inPumpSession());633 642 ASSERT(m_haveBackgroundParser || wasCreatedByScript()); 634 643 m_token = adoptPtr(new HTMLToken); -
trunk/Source/WebCore/html/parser/HTMLParserScheduler.cpp
r143845 r147383 78 78 79 79 PumpSession::PumpSession(unsigned& nestingLevel, Document* document) 80 : NestingLevelIncrementer(nestingLevel)81 , ActiveParserSession(document)80 : ActiveParserSession(document) 81 , NestingLevelIncrementer(nestingLevel) 82 82 // Setting processedTokens to INT_MAX causes us to check for yields 83 83 // after any token during any parse where yielding is allowed. -
trunk/Source/WebCore/html/parser/HTMLParserScheduler.h
r142378 r147383 48 48 }; 49 49 50 class PumpSession : public NestingLevelIncrementer, public ActiveParserSession { 50 // In C++, base classes are destructed from right to left, which means 51 // ~NestingLevelIncrementer will run before ~ActiveParserSession. This 52 // is important because ~ActiveParserSession calls Document::decrementActiveParserCount, 53 // which cares about the pump nesting level of the parser. 54 class PumpSession : public ActiveParserSession, public NestingLevelIncrementer { 51 55 public: 52 56 PumpSession(unsigned& nestingLevel, Document*);
Note: See TracChangeset
for help on using the changeset viewer.