OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. | 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 } | 126 } |
127 | 127 |
128 // Use the URL of the currently active document for this frame. | 128 // Use the URL of the currently active document for this frame. |
129 return document->frame()->document()->url(); | 129 return document->frame()->document()->url(); |
130 } | 130 } |
131 | 131 |
132 } // namespace | 132 } // namespace |
133 | 133 |
134 using namespace HTMLNames; | 134 using namespace HTMLNames; |
135 | 135 |
136 HTMLScriptRunner::HTMLScriptRunner(Document* document, HTMLScriptRunnerHost* hos
t) | 136 HTMLScriptRunner::HTMLScriptRunner(HTMLParserReentryPermit* reentryPermit, Docum
ent* document, HTMLScriptRunnerHost* host) |
137 : m_document(document) | 137 : m_reentryPermit(reentryPermit) |
| 138 , m_document(document) |
138 , m_host(host) | 139 , m_host(host) |
139 , m_parserBlockingScript(PendingScript::create(nullptr, nullptr)) | 140 , m_parserBlockingScript(PendingScript::create(nullptr, nullptr)) |
140 , m_scriptNestingLevel(0) | |
141 , m_hasScriptsWaitingForResources(false) | 141 , m_hasScriptsWaitingForResources(false) |
142 { | 142 { |
143 ASSERT(m_host); | 143 ASSERT(m_host); |
144 ThreadState::current()->registerPreFinalizer(this); | 144 ThreadState::current()->registerPreFinalizer(this); |
145 } | 145 } |
146 | 146 |
147 HTMLScriptRunner::~HTMLScriptRunner() | 147 HTMLScriptRunner::~HTMLScriptRunner() |
148 { | 148 { |
149 // Verify that detach() has been called. | 149 // Verify that detach() has been called. |
150 ASSERT(!m_document); | 150 ASSERT(!m_document); |
151 } | 151 } |
152 | 152 |
153 void HTMLScriptRunner::detach() | 153 void HTMLScriptRunner::detach() |
154 { | 154 { |
155 if (!m_document) | 155 if (!m_document) |
156 return; | 156 return; |
157 | 157 |
158 m_parserBlockingScript->stopWatchingForLoad(); | 158 m_parserBlockingScript->stopWatchingForLoad(); |
159 m_parserBlockingScript->releaseElementAndClear(); | 159 m_parserBlockingScript->releaseElementAndClear(); |
160 | 160 |
161 while (!m_scriptsToExecuteAfterParsing.isEmpty()) { | 161 while (!m_scriptsToExecuteAfterParsing.isEmpty()) { |
162 PendingScript* pendingScript = m_scriptsToExecuteAfterParsing.takeFirst(
); | 162 PendingScript* pendingScript = m_scriptsToExecuteAfterParsing.takeFirst(
); |
163 pendingScript->stopWatchingForLoad(); | 163 pendingScript->stopWatchingForLoad(); |
164 pendingScript->releaseElementAndClear(); | 164 pendingScript->releaseElementAndClear(); |
165 } | 165 } |
166 m_document = nullptr; | 166 m_document = nullptr; |
| 167 // m_reentryPermit is not cleared here, because the script runner |
| 168 // may continue to run pending scripts after the parser has |
| 169 // detached. |
167 } | 170 } |
168 | 171 |
169 bool HTMLScriptRunner::isPendingScriptReady(const PendingScript* script) | 172 bool HTMLScriptRunner::isPendingScriptReady(const PendingScript* script) |
170 { | 173 { |
171 m_hasScriptsWaitingForResources = !m_document->isScriptExecutionReady(); | 174 m_hasScriptsWaitingForResources = !m_document->isScriptExecutionReady(); |
172 if (m_hasScriptsWaitingForResources) | 175 if (m_hasScriptsWaitingForResources) |
173 return false; | 176 return false; |
174 return script->isReady(); | 177 return script->isReady(); |
175 } | 178 } |
176 | 179 |
(...skipping 24 matching lines...) Expand all Loading... |
201 if (m_hasScriptsWaitingForResources) | 204 if (m_hasScriptsWaitingForResources) |
202 return; | 205 return; |
203 } | 206 } |
204 } | 207 } |
205 | 208 |
206 TextPosition scriptStartPosition = pendingScript->startingPosition(); | 209 TextPosition scriptStartPosition = pendingScript->startingPosition(); |
207 double scriptParserBlockingTime = pendingScript->parserBlockingLoadStartTime
(); | 210 double scriptParserBlockingTime = pendingScript->parserBlockingLoadStartTime
(); |
208 // Clear the pending script before possible re-entrancy from executeScript() | 211 // Clear the pending script before possible re-entrancy from executeScript() |
209 Element* element = pendingScript->releaseElementAndClear(); | 212 Element* element = pendingScript->releaseElementAndClear(); |
210 if (ScriptLoader* scriptLoader = toScriptLoaderIfPossible(element)) { | 213 if (ScriptLoader* scriptLoader = toScriptLoaderIfPossible(element)) { |
211 NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel); | 214 HTMLParserReentryPermit::ScriptNestingLevelIncrementer nestingLevelIncre
menter = m_reentryPermit->incrementScriptNestingLevel(); |
212 IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncrem
enter(m_document); | 215 IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncrem
enter(m_document); |
213 if (errorOccurred) { | 216 if (errorOccurred) { |
214 TRACE_EVENT_WITH_FLOW1("blink", "HTMLScriptRunner ExecuteScriptFaile
d", element, TRACE_EVENT_FLAG_FLOW_IN, | 217 TRACE_EVENT_WITH_FLOW1("blink", "HTMLScriptRunner ExecuteScriptFaile
d", element, TRACE_EVENT_FLAG_FLOW_IN, |
215 "data", getTraceArgsForScriptElement(element, scriptStartPositio
n)); | 218 "data", getTraceArgsForScriptElement(element, scriptStartPositio
n)); |
216 scriptLoader->dispatchErrorEvent(); | 219 scriptLoader->dispatchErrorEvent(); |
217 } else { | 220 } else { |
218 ASSERT(isExecutingScript()); | 221 ASSERT(isExecutingScript()); |
219 if (scriptParserBlockingTime > 0.0) { | 222 if (scriptParserBlockingTime > 0.0) { |
220 DocumentParserTiming::from(*m_document).recordParserBlockedOnScr
iptLoadDuration(monotonicallyIncreasingTime() - scriptParserBlockingTime, script
Loader->wasCreatedDuringDocumentWrite()); | 223 DocumentParserTiming::from(*m_document).recordParserBlockedOnScr
iptLoadDuration(monotonicallyIncreasingTime() - scriptParserBlockingTime, script
Loader->wasCreatedDuringDocumentWrite()); |
221 } | 224 } |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 ASSERT(scriptLoader); | 415 ASSERT(scriptLoader); |
413 if (!scriptLoader) | 416 if (!scriptLoader) |
414 return; | 417 return; |
415 | 418 |
416 ASSERT(scriptLoader->isParserInserted()); | 419 ASSERT(scriptLoader->isParserInserted()); |
417 | 420 |
418 if (!isExecutingScript()) | 421 if (!isExecutingScript()) |
419 Microtask::performCheckpoint(V8PerIsolateData::mainThreadIsolate()); | 422 Microtask::performCheckpoint(V8PerIsolateData::mainThreadIsolate()); |
420 | 423 |
421 InsertionPointRecord insertionPointRecord(m_host->inputStream()); | 424 InsertionPointRecord insertionPointRecord(m_host->inputStream()); |
422 NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel); | 425 HTMLParserReentryPermit::ScriptNestingLevelIncrementer nestingLevelIncre
menter = m_reentryPermit->incrementScriptNestingLevel(); |
423 | 426 |
424 scriptLoader->prepareScript(scriptStartPosition); | 427 scriptLoader->prepareScript(scriptStartPosition); |
425 | 428 |
426 if (!scriptLoader->willBeParserExecuted()) | 429 if (!scriptLoader->willBeParserExecuted()) |
427 return; | 430 return; |
428 | 431 |
429 if (scriptLoader->willExecuteWhenDocumentFinishedParsing()) { | 432 if (scriptLoader->willExecuteWhenDocumentFinishedParsing()) { |
430 requestDeferredScript(script); | 433 requestDeferredScript(script); |
431 } else if (scriptLoader->readyToBeParserExecuted()) { | 434 } else if (scriptLoader->readyToBeParserExecuted()) { |
432 if (m_scriptNestingLevel == 1) { | 435 if (m_reentryPermit->scriptNestingLevel() == 1u) { |
433 m_parserBlockingScript->setElement(script); | 436 m_parserBlockingScript->setElement(script); |
434 m_parserBlockingScript->setStartingPosition(scriptStartPosition)
; | 437 m_parserBlockingScript->setStartingPosition(scriptStartPosition)
; |
435 } else { | 438 } else { |
436 ASSERT(m_scriptNestingLevel > 1); | 439 DCHECK_GT(m_reentryPermit->scriptNestingLevel(), 1u); |
437 m_parserBlockingScript->releaseElementAndClear(); | 440 m_parserBlockingScript->releaseElementAndClear(); |
438 ScriptSourceCode sourceCode(script->textContent(), documentURLFo
rScriptExecution(m_document), scriptStartPosition); | 441 ScriptSourceCode sourceCode(script->textContent(), documentURLFo
rScriptExecution(m_document), scriptStartPosition); |
439 doExecuteScript(script, sourceCode, scriptStartPosition); | 442 doExecuteScript(script, sourceCode, scriptStartPosition); |
440 } | 443 } |
441 } else { | 444 } else { |
442 requestParsingBlockingScript(script); | 445 requestParsingBlockingScript(script); |
443 } | 446 } |
444 } | 447 } |
445 } | 448 } |
446 | 449 |
447 DEFINE_TRACE(HTMLScriptRunner) | 450 DEFINE_TRACE(HTMLScriptRunner) |
448 { | 451 { |
449 visitor->trace(m_document); | 452 visitor->trace(m_document); |
450 visitor->trace(m_host); | 453 visitor->trace(m_host); |
451 visitor->trace(m_parserBlockingScript); | 454 visitor->trace(m_parserBlockingScript); |
452 visitor->trace(m_scriptsToExecuteAfterParsing); | 455 visitor->trace(m_scriptsToExecuteAfterParsing); |
453 ScriptResourceClient::trace(visitor); | 456 ScriptResourceClient::trace(visitor); |
454 } | 457 } |
455 | 458 |
456 } // namespace blink | 459 } // namespace blink |
OLD | NEW |