Index: third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp |
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp b/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp |
index e1b14f284a4d4af8aa807151ba8e4b7dde9d0fac..3ecfed5d3673cbcc2c42c533770e00babe8f83d4 100644 |
--- a/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp |
+++ b/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp |
@@ -48,25 +48,21 @@ using namespace HTMLNames; |
HTMLScriptRunner::HTMLScriptRunner(Document* document, HTMLScriptRunnerHost* host) |
: m_document(document) |
, m_host(host) |
+ , m_parserBlockingScript(PendingScript::create(nullptr, nullptr)) |
, m_scriptNestingLevel(0) |
, m_hasScriptsWaitingForResources(false) |
, m_parserBlockingScriptAlreadyLoaded(false) |
{ |
ASSERT(m_host); |
+#if ENABLE(OILPAN) |
+ ThreadState::current()->registerPreFinalizer(this); |
+#endif |
} |
HTMLScriptRunner::~HTMLScriptRunner() |
{ |
-#if ENABLE(OILPAN) |
- // If the document is destructed without having explicitly |
- // detached the parser (and this script runner object), perform |
- // detach steps now. This will happen if the Document, the parser |
- // and this script runner object are swept out in the same GC. |
- detach(); |
-#else |
// Verify that detach() has been called. |
ASSERT(!m_document); |
-#endif |
} |
void HTMLScriptRunner::detach() |
@@ -74,13 +70,13 @@ void HTMLScriptRunner::detach() |
if (!m_document) |
return; |
- m_parserBlockingScript.stopWatchingForLoad(this); |
- m_parserBlockingScript.releaseElementAndClear(); |
+ m_parserBlockingScript->stopWatchingForLoad(this); |
+ m_parserBlockingScript->releaseElementAndClear(); |
while (!m_scriptsToExecuteAfterParsing.isEmpty()) { |
- PendingScript pendingScript = m_scriptsToExecuteAfterParsing.takeFirst(); |
- pendingScript.stopWatchingForLoad(this); |
- pendingScript.releaseElementAndClear(); |
+ OwnPtrWillBeRawPtr<PendingScript> pendingScript = m_scriptsToExecuteAfterParsing.takeFirst(); |
+ pendingScript->stopWatchingForLoad(this); |
+ pendingScript->releaseElementAndClear(); |
} |
m_document = nullptr; |
} |
@@ -105,12 +101,12 @@ inline PassRefPtrWillBeRawPtr<Event> createScriptLoadEvent() |
return Event::create(EventTypeNames::load); |
} |
-bool HTMLScriptRunner::isPendingScriptReady(const PendingScript& script) |
+bool HTMLScriptRunner::isPendingScriptReady(const PendingScript* script) |
{ |
m_hasScriptsWaitingForResources = !m_document->isScriptExecutionReady(); |
if (m_hasScriptsWaitingForResources) |
return false; |
- return script.isReady(); |
+ return script->isReady(); |
} |
void HTMLScriptRunner::executeParsingBlockingScript() |
@@ -118,24 +114,24 @@ void HTMLScriptRunner::executeParsingBlockingScript() |
ASSERT(m_document); |
ASSERT(!isExecutingScript()); |
ASSERT(m_document->isScriptExecutionReady()); |
- ASSERT(isPendingScriptReady(m_parserBlockingScript)); |
+ ASSERT(isPendingScriptReady(m_parserBlockingScript.get())); |
InsertionPointRecord insertionPointRecord(m_host->inputStream()); |
- executePendingScriptAndDispatchEvent(m_parserBlockingScript, PendingScript::ParsingBlocking); |
+ executePendingScriptAndDispatchEvent(m_parserBlockingScript.get(), ScriptStreamer::ParsingBlocking); |
} |
-void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendingScript, PendingScript::Type pendingScriptType) |
+void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript* pendingScript, ScriptStreamer::Type pendingScriptType) |
{ |
bool errorOccurred = false; |
- double loadFinishTime = pendingScript.resource() && pendingScript.resource()->url().protocolIsInHTTPFamily() ? pendingScript.resource()->loadFinishTime() : 0; |
- ScriptSourceCode sourceCode = pendingScript.getSource(documentURLForScriptExecution(m_document), errorOccurred); |
+ double loadFinishTime = pendingScript->resource() && pendingScript->resource()->url().protocolIsInHTTPFamily() ? pendingScript->resource()->loadFinishTime() : 0; |
+ ScriptSourceCode sourceCode = pendingScript->getSource(documentURLForScriptExecution(m_document), errorOccurred); |
// Stop watching loads before executeScript to prevent recursion if the script reloads itself. |
- pendingScript.stopWatchingForLoad(this); |
+ pendingScript->stopWatchingForLoad(this); |
if (!isExecutingScript()) { |
Microtask::performCheckpoint(V8PerIsolateData::mainThreadIsolate()); |
- if (pendingScriptType == PendingScript::ParsingBlocking) { |
+ if (pendingScriptType == ScriptStreamer::ParsingBlocking) { |
m_hasScriptsWaitingForResources = !m_document->isScriptExecutionReady(); |
// The parser cannot be unblocked as a microtask requested another resource |
if (m_hasScriptsWaitingForResources) |
@@ -144,7 +140,7 @@ void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendi |
} |
// Clear the pending script before possible rentrancy from executeScript() |
- RefPtrWillBeRawPtr<Element> element = pendingScript.releaseElementAndClear(); |
+ RefPtrWillBeRawPtr<Element> element = pendingScript->releaseElementAndClear(); |
double compilationFinishTime = 0; |
if (ScriptLoader* scriptLoader = toScriptLoaderIfPossible(element.get())) { |
NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel); |
@@ -162,7 +158,7 @@ void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendi |
} |
// The exact value doesn't matter; valid time stamps are much bigger than this value. |
const double epsilon = 1; |
- if (pendingScriptType == PendingScript::ParsingBlocking && !m_parserBlockingScriptAlreadyLoaded && compilationFinishTime > epsilon && loadFinishTime > epsilon) { |
+ if (pendingScriptType == ScriptStreamer::ParsingBlocking && !m_parserBlockingScriptAlreadyLoaded && compilationFinishTime > epsilon && loadFinishTime > epsilon) { |
Platform::current()->histogramCustomCounts("WebCore.Scripts.ParsingBlocking.TimeBetweenLoadedAndCompiled", (compilationFinishTime - loadFinishTime) * 1000, 0, 10000, 50); |
} |
@@ -171,15 +167,15 @@ void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendi |
void HTMLScriptRunner::stopWatchingResourceForLoad(Resource* resource) |
{ |
- if (m_parserBlockingScript.resource() == resource) { |
- m_parserBlockingScript.stopWatchingForLoad(this); |
- m_parserBlockingScript.releaseElementAndClear(); |
+ if (m_parserBlockingScript->resource() == resource) { |
+ m_parserBlockingScript->stopWatchingForLoad(this); |
+ m_parserBlockingScript->releaseElementAndClear(); |
return; |
} |
- for (PendingScript& script : m_scriptsToExecuteAfterParsing) { |
- if (script.resource() == resource) { |
- script.stopWatchingForLoad(this); |
- script.releaseElementAndClear(); |
+ for (auto& script : m_scriptsToExecuteAfterParsing) { |
+ if (script->resource() == resource) { |
+ script->stopWatchingForLoad(this); |
+ script->releaseElementAndClear(); |
return; |
} |
} |
@@ -225,12 +221,12 @@ void HTMLScriptRunner::execute(PassRefPtrWillBeRawPtr<Element> scriptElement, co |
bool HTMLScriptRunner::hasParserBlockingScript() const |
{ |
- return !!m_parserBlockingScript.element(); |
+ return !!m_parserBlockingScript->element(); |
} |
void HTMLScriptRunner::executeParsingBlockingScripts() |
{ |
- while (hasParserBlockingScript() && isPendingScriptReady(m_parserBlockingScript)) |
+ while (hasParserBlockingScript() && isPendingScriptReady(m_parserBlockingScript.get())) |
executeParsingBlockingScript(); |
} |
@@ -238,8 +234,8 @@ void HTMLScriptRunner::executeScriptsWaitingForLoad(Resource* resource) |
{ |
ASSERT(!isExecutingScript()); |
ASSERT(hasParserBlockingScript()); |
- ASSERT_UNUSED(resource, m_parserBlockingScript.resource() == resource); |
- ASSERT(m_parserBlockingScript.isReady()); |
+ ASSERT_UNUSED(resource, m_parserBlockingScript->resource() == resource); |
+ ASSERT(m_parserBlockingScript->isReady()); |
executeParsingBlockingScripts(); |
} |
@@ -259,13 +255,13 @@ bool HTMLScriptRunner::executeScriptsWaitingForParsing() |
while (!m_scriptsToExecuteAfterParsing.isEmpty()) { |
ASSERT(!isExecutingScript()); |
ASSERT(!hasParserBlockingScript()); |
- ASSERT(m_scriptsToExecuteAfterParsing.first().resource()); |
- if (!m_scriptsToExecuteAfterParsing.first().isReady()) { |
- m_scriptsToExecuteAfterParsing.first().watchForLoad(this); |
+ ASSERT(m_scriptsToExecuteAfterParsing.first()->resource()); |
+ if (!m_scriptsToExecuteAfterParsing.first()->isReady()) { |
+ m_scriptsToExecuteAfterParsing.first()->watchForLoad(this); |
return false; |
} |
- PendingScript first = m_scriptsToExecuteAfterParsing.takeFirst(); |
- executePendingScriptAndDispatchEvent(first, PendingScript::Deferred); |
+ OwnPtrWillBeRawPtr<PendingScript> first = m_scriptsToExecuteAfterParsing.takeFirst(); |
+ executePendingScriptAndDispatchEvent(first.get(), ScriptStreamer::Deferred); |
// FIXME: What is this m_document check for? |
if (!m_document) |
return false; |
@@ -275,52 +271,52 @@ bool HTMLScriptRunner::executeScriptsWaitingForParsing() |
void HTMLScriptRunner::requestParsingBlockingScript(Element* element) |
{ |
- if (!requestPendingScript(m_parserBlockingScript, element)) |
+ if (!requestPendingScript(m_parserBlockingScript.get(), element)) |
return; |
- ASSERT(m_parserBlockingScript.resource()); |
+ ASSERT(m_parserBlockingScript->resource()); |
// We only care about a load callback if resource is not already |
// in the cache. Callers will attempt to run the m_parserBlockingScript |
// if possible before returning control to the parser. |
- if (!m_parserBlockingScript.isReady()) { |
+ if (!m_parserBlockingScript->isReady()) { |
if (m_document->frame()) { |
ScriptState* scriptState = ScriptState::forMainWorld(m_document->frame()); |
if (scriptState) |
- ScriptStreamer::startStreaming(m_parserBlockingScript, PendingScript::ParsingBlocking, m_document->frame()->settings(), scriptState, m_document->loadingTaskRunner()); |
+ ScriptStreamer::startStreaming(m_parserBlockingScript.get(), ScriptStreamer::ParsingBlocking, m_document->frame()->settings(), scriptState, m_document->loadingTaskRunner()); |
} |
- m_parserBlockingScript.watchForLoad(this); |
+ m_parserBlockingScript->watchForLoad(this); |
} |
} |
void HTMLScriptRunner::requestDeferredScript(Element* element) |
{ |
- PendingScript pendingScript; |
- if (!requestPendingScript(pendingScript, element)) |
+ OwnPtrWillBeRawPtr<PendingScript> pendingScript = PendingScript::create(nullptr, nullptr); |
+ if (!requestPendingScript(pendingScript.get(), element)) |
return; |
- if (m_document->frame() && !pendingScript.isReady()) { |
+ if (m_document->frame() && !pendingScript->isReady()) { |
ScriptState* scriptState = ScriptState::forMainWorld(m_document->frame()); |
if (scriptState) |
- ScriptStreamer::startStreaming(pendingScript, PendingScript::Deferred, m_document->frame()->settings(), scriptState, m_document->loadingTaskRunner()); |
+ ScriptStreamer::startStreaming(pendingScript.get(), ScriptStreamer::Deferred, m_document->frame()->settings(), scriptState, m_document->loadingTaskRunner()); |
} |
- ASSERT(pendingScript.resource()); |
- m_scriptsToExecuteAfterParsing.append(pendingScript); |
+ ASSERT(pendingScript->resource()); |
+ m_scriptsToExecuteAfterParsing.append(pendingScript.release()); |
} |
-bool HTMLScriptRunner::requestPendingScript(PendingScript& pendingScript, Element* script) const |
+bool HTMLScriptRunner::requestPendingScript(PendingScript* pendingScript, Element* script) const |
{ |
- ASSERT(!pendingScript.element()); |
- pendingScript.setElement(script); |
+ ASSERT(!pendingScript->element()); |
+ pendingScript->setElement(script); |
// This should correctly return 0 for empty or invalid srcValues. |
ScriptResource* resource = toScriptLoaderIfPossible(script)->resource().get(); |
if (!resource) { |
notImplemented(); // Dispatch error event. |
return false; |
} |
- pendingScript.setScriptResource(resource); |
+ pendingScript->setScriptResource(resource); |
return true; |
} |
@@ -358,8 +354,8 @@ void HTMLScriptRunner::runScript(Element* script, const TextPosition& scriptStar |
requestDeferredScript(script); |
} else if (scriptLoader->readyToBeParserExecuted()) { |
if (m_scriptNestingLevel == 1) { |
- m_parserBlockingScript.setElement(script); |
- m_parserBlockingScript.setStartingPosition(scriptStartPosition); |
+ m_parserBlockingScript->setElement(script); |
+ m_parserBlockingScript->setStartingPosition(scriptStartPosition); |
} else { |
ScriptSourceCode sourceCode(script->textContent(), documentURLForScriptExecution(m_document), scriptStartPosition); |
scriptLoader->executeScript(sourceCode); |