Index: Source/core/html/parser/HTMLDocumentParser.cpp |
diff --git a/Source/core/html/parser/HTMLDocumentParser.cpp b/Source/core/html/parser/HTMLDocumentParser.cpp |
index 3a5c940aacbb84c63fd477645c69517bc5a0a320..9f9c44dbbffa480ec5f94314793f8f0bfcdf0140 100644 |
--- a/Source/core/html/parser/HTMLDocumentParser.cpp |
+++ b/Source/core/html/parser/HTMLDocumentParser.cpp |
@@ -317,31 +317,25 @@ |
{ |
TRACE_EVENT0("blink", "HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser"); |
- if (!isParsing()) |
- return; |
- |
- // ApplicationCache needs to be initialized before issuing preloads. |
- // We suspend preload until HTMLHTMLElement is inserted and |
- // ApplicationCache is initialized. |
- if (!document()->documentElement()) { |
- for (auto& request : chunk->preloads) |
- m_queuedPreloads.append(request.release()); |
- } else { |
- // We can safely assume that there are no queued preloads request after |
- // the document element is available, as we empty the queue immediately |
- // after the document element is created in pumpPendingSpeculations(). |
- ASSERT(m_queuedPreloads.isEmpty()); |
- m_preloader->takeAndPreload(chunk->preloads); |
- } |
- |
- m_speculations.append(chunk); |
- |
- if (!isWaitingForScripts() && !isScheduledForResume()) { |
+ // alert(), runModalDialog, and the JavaScript Debugger all run nested event loops |
+ // which can cause this method to be re-entered. We detect re-entry using |
+ // hasActiveParser(), save the chunk as a speculation, and return. |
+ if (isWaitingForScripts() || !m_speculations.isEmpty() || document()->activeParserCount() > 0 || m_tasksWereSuspended || isScheduledForResume()) { |
if (m_tasksWereSuspended) |
m_parserScheduler->forceResumeAfterYield(); |
- else |
- m_parserScheduler->scheduleForResume(); |
- } |
+ m_preloader->takeAndPreload(chunk->preloads); |
+ m_speculations.append(chunk); |
+ return; |
+ } |
+ |
+ // processParsedChunkFromBackgroundParser can cause this parser to be detached from the Document, |
+ // but we need to ensure it isn't deleted yet. |
+ RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this); |
+ |
+ ASSERT(m_speculations.isEmpty()); |
+ chunk->preloads.clear(); // We don't need to preload because we're going to parse immediately. |
+ m_speculations.append(chunk); |
+ pumpPendingSpeculations(); |
} |
void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser(const DocumentEncodingData& data) |
@@ -458,9 +452,6 @@ |
m_textPosition = it->textPosition(); |
constructTreeFromCompactHTMLToken(*it); |
- |
- if (!m_queuedPreloads.isEmpty() && document()->documentElement()) |
- m_preloader->takeAndPreload(m_queuedPreloads); |
if (isStopped()) |
break; |