| 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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 } // namespace | 147 } // namespace |
| 148 | 148 |
| 149 using namespace HTMLNames; | 149 using namespace HTMLNames; |
| 150 | 150 |
| 151 HTMLScriptRunner::HTMLScriptRunner(HTMLParserReentryPermit* reentryPermit, | 151 HTMLScriptRunner::HTMLScriptRunner(HTMLParserReentryPermit* reentryPermit, |
| 152 Document* document, | 152 Document* document, |
| 153 HTMLScriptRunnerHost* host) | 153 HTMLScriptRunnerHost* host) |
| 154 : m_reentryPermit(reentryPermit), | 154 : m_reentryPermit(reentryPermit), |
| 155 m_document(document), | 155 m_document(document), |
| 156 m_host(host), | 156 m_host(host), |
| 157 m_parserBlockingScript(PendingScript::create(nullptr, nullptr)) { | 157 m_parserBlockingScript(PendingScript::create(nullptr, nullptr)), |
| 158 m_hasScriptsWaitingForResources(false) { |
| 158 ASSERT(m_host); | 159 ASSERT(m_host); |
| 159 ThreadState::current()->registerPreFinalizer(this); | 160 ThreadState::current()->registerPreFinalizer(this); |
| 160 } | 161 } |
| 161 | 162 |
| 162 HTMLScriptRunner::~HTMLScriptRunner() { | 163 HTMLScriptRunner::~HTMLScriptRunner() { |
| 163 // Verify that detach() has been called. | 164 // Verify that detach() has been called. |
| 164 ASSERT(!m_document); | 165 ASSERT(!m_document); |
| 165 } | 166 } |
| 166 | 167 |
| 167 void HTMLScriptRunner::detach() { | 168 void HTMLScriptRunner::detach() { |
| 168 if (!m_document) | 169 if (!m_document) |
| 169 return; | 170 return; |
| 170 | 171 |
| 171 m_parserBlockingScript->stopWatchingForLoad(); | 172 m_parserBlockingScript->stopWatchingForLoad(); |
| 172 m_parserBlockingScript->releaseElementAndClear(); | 173 m_parserBlockingScript->releaseElementAndClear(); |
| 173 | 174 |
| 174 while (!m_scriptsToExecuteAfterParsing.isEmpty()) { | 175 while (!m_scriptsToExecuteAfterParsing.isEmpty()) { |
| 175 PendingScript* pendingScript = m_scriptsToExecuteAfterParsing.takeFirst(); | 176 PendingScript* pendingScript = m_scriptsToExecuteAfterParsing.takeFirst(); |
| 176 pendingScript->stopWatchingForLoad(); | 177 pendingScript->stopWatchingForLoad(); |
| 177 pendingScript->releaseElementAndClear(); | 178 pendingScript->releaseElementAndClear(); |
| 178 } | 179 } |
| 179 m_document = nullptr; | 180 m_document = nullptr; |
| 180 // m_reentryPermit is not cleared here, because the script runner | 181 // m_reentryPermit is not cleared here, because the script runner |
| 181 // may continue to run pending scripts after the parser has | 182 // may continue to run pending scripts after the parser has |
| 182 // detached. | 183 // detached. |
| 183 } | 184 } |
| 184 | 185 |
| 185 bool HTMLScriptRunner::isPendingScriptReady() { | 186 bool HTMLScriptRunner::isPendingScriptReady(const PendingScript* script) { |
| 186 if (!m_document->isScriptExecutionReady()) | 187 m_hasScriptsWaitingForResources = !m_document->isScriptExecutionReady(); |
| 188 if (m_hasScriptsWaitingForResources) |
| 187 return false; | 189 return false; |
| 188 return m_parserBlockingScript->isReady(); | 190 return script->isReady(); |
| 189 } | 191 } |
| 190 | 192 |
| 191 void HTMLScriptRunner::executeParsingBlockingScript() { | 193 void HTMLScriptRunner::executeParsingBlockingScript() { |
| 192 DCHECK(m_document); | 194 ASSERT(m_document); |
| 193 DCHECK(!isExecutingScript()); | 195 ASSERT(!isExecutingScript()); |
| 194 DCHECK(m_document->isScriptExecutionReady()); | 196 ASSERT(m_document->isScriptExecutionReady()); |
| 195 DCHECK(isPendingScriptReady()); | 197 ASSERT(isPendingScriptReady(m_parserBlockingScript.get())); |
| 196 | 198 |
| 197 InsertionPointRecord insertionPointRecord(m_host->inputStream()); | 199 InsertionPointRecord insertionPointRecord(m_host->inputStream()); |
| 198 executePendingScriptAndDispatchEvent(m_parserBlockingScript.get(), | 200 executePendingScriptAndDispatchEvent(m_parserBlockingScript.get(), |
| 199 ScriptStreamer::ParsingBlocking); | 201 ScriptStreamer::ParsingBlocking); |
| 200 } | 202 } |
| 201 | 203 |
| 202 void HTMLScriptRunner::executePendingScriptAndDispatchEvent( | 204 void HTMLScriptRunner::executePendingScriptAndDispatchEvent( |
| 203 PendingScript* pendingScript, | 205 PendingScript* pendingScript, |
| 204 ScriptStreamer::Type pendingScriptType) { | 206 ScriptStreamer::Type pendingScriptType) { |
| 205 bool errorOccurred = false; | 207 bool errorOccurred = false; |
| 206 ScriptSourceCode sourceCode = pendingScript->getSource( | 208 ScriptSourceCode sourceCode = pendingScript->getSource( |
| 207 documentURLForScriptExecution(m_document), errorOccurred); | 209 documentURLForScriptExecution(m_document), errorOccurred); |
| 208 | 210 |
| 209 // Stop watching loads before executeScript to prevent recursion if the script | 211 // Stop watching loads before executeScript to prevent recursion if the script |
| 210 // reloads itself. | 212 // reloads itself. |
| 211 pendingScript->stopWatchingForLoad(); | 213 pendingScript->stopWatchingForLoad(); |
| 212 | 214 |
| 213 if (!isExecutingScript()) { | 215 if (!isExecutingScript()) { |
| 214 Microtask::performCheckpoint(V8PerIsolateData::mainThreadIsolate()); | 216 Microtask::performCheckpoint(V8PerIsolateData::mainThreadIsolate()); |
| 215 if (pendingScriptType == ScriptStreamer::ParsingBlocking) { | 217 if (pendingScriptType == ScriptStreamer::ParsingBlocking) { |
| 218 m_hasScriptsWaitingForResources = !m_document->isScriptExecutionReady(); |
| 216 // The parser cannot be unblocked as a microtask requested another | 219 // The parser cannot be unblocked as a microtask requested another |
| 217 // resource | 220 // resource |
| 218 if (!m_document->isScriptExecutionReady()) | 221 if (m_hasScriptsWaitingForResources) |
| 219 return; | 222 return; |
| 220 } | 223 } |
| 221 } | 224 } |
| 222 | 225 |
| 223 TextPosition scriptStartPosition = pendingScript->startingPosition(); | 226 TextPosition scriptStartPosition = pendingScript->startingPosition(); |
| 224 double scriptParserBlockingTime = | 227 double scriptParserBlockingTime = |
| 225 pendingScript->parserBlockingLoadStartTime(); | 228 pendingScript->parserBlockingLoadStartTime(); |
| 226 // Clear the pending script before possible re-entrancy from executeScript() | 229 // Clear the pending script before possible re-entrancy from executeScript() |
| 227 Element* element = pendingScript->releaseElementAndClear(); | 230 Element* element = pendingScript->releaseElementAndClear(); |
| 228 if (ScriptLoader* scriptLoader = toScriptLoaderIfPossible(element)) { | 231 if (ScriptLoader* scriptLoader = toScriptLoaderIfPossible(element)) { |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 m_host->appendCurrentInputStreamToPreloadScannerAndScan(); | 366 m_host->appendCurrentInputStreamToPreloadScannerAndScan(); |
| 364 executeParsingBlockingScripts(); | 367 executeParsingBlockingScripts(); |
| 365 } | 368 } |
| 366 } | 369 } |
| 367 | 370 |
| 368 bool HTMLScriptRunner::hasParserBlockingScript() const { | 371 bool HTMLScriptRunner::hasParserBlockingScript() const { |
| 369 return !!m_parserBlockingScript->element(); | 372 return !!m_parserBlockingScript->element(); |
| 370 } | 373 } |
| 371 | 374 |
| 372 void HTMLScriptRunner::executeParsingBlockingScripts() { | 375 void HTMLScriptRunner::executeParsingBlockingScripts() { |
| 373 while (hasParserBlockingScript() && isPendingScriptReady()) | 376 while (hasParserBlockingScript() && |
| 377 isPendingScriptReady(m_parserBlockingScript.get())) |
| 374 executeParsingBlockingScript(); | 378 executeParsingBlockingScript(); |
| 375 } | 379 } |
| 376 | 380 |
| 377 void HTMLScriptRunner::executeScriptsWaitingForLoad(Resource* resource) { | 381 void HTMLScriptRunner::executeScriptsWaitingForLoad(Resource* resource) { |
| 378 TRACE_EVENT0("blink", "HTMLScriptRunner::executeScriptsWaitingForLoad"); | 382 TRACE_EVENT0("blink", "HTMLScriptRunner::executeScriptsWaitingForLoad"); |
| 379 ASSERT(!isExecutingScript()); | 383 ASSERT(!isExecutingScript()); |
| 380 ASSERT(hasParserBlockingScript()); | 384 ASSERT(hasParserBlockingScript()); |
| 381 DCHECK_EQ(resource, m_parserBlockingScript->resource()); | 385 DCHECK_EQ(resource, m_parserBlockingScript->resource()); |
| 382 ASSERT(m_parserBlockingScript->isReady()); | 386 ASSERT(m_parserBlockingScript->isReady()); |
| 383 executeParsingBlockingScripts(); | 387 executeParsingBlockingScripts(); |
| 384 } | 388 } |
| 385 | 389 |
| 386 void HTMLScriptRunner::executeScriptsWaitingForResources() { | 390 void HTMLScriptRunner::executeScriptsWaitingForResources() { |
| 387 TRACE_EVENT0("blink", "HTMLScriptRunner::executeScriptsWaitingForResources"); | 391 TRACE_EVENT0("blink", "HTMLScriptRunner::executeScriptsWaitingForResources"); |
| 388 ASSERT(m_document); | 392 ASSERT(m_document); |
| 393 // Callers should check hasScriptsWaitingForResources() before calling |
| 394 // to prevent parser or script re-entry during </style> parsing. |
| 395 ASSERT(hasScriptsWaitingForResources()); |
| 389 ASSERT(!isExecutingScript()); | 396 ASSERT(!isExecutingScript()); |
| 390 ASSERT(m_document->isScriptExecutionReady()); | 397 ASSERT(m_document->isScriptExecutionReady()); |
| 391 executeParsingBlockingScripts(); | 398 executeParsingBlockingScripts(); |
| 392 } | 399 } |
| 393 | 400 |
| 394 bool HTMLScriptRunner::executeScriptsWaitingForParsing() { | 401 bool HTMLScriptRunner::executeScriptsWaitingForParsing() { |
| 395 TRACE_EVENT0("blink", "HTMLScriptRunner::executeScriptsWaitingForParsing"); | 402 TRACE_EVENT0("blink", "HTMLScriptRunner::executeScriptsWaitingForParsing"); |
| 396 while (!m_scriptsToExecuteAfterParsing.isEmpty()) { | 403 while (!m_scriptsToExecuteAfterParsing.isEmpty()) { |
| 397 ASSERT(!isExecutingScript()); | 404 ASSERT(!isExecutingScript()); |
| 398 ASSERT(!hasParserBlockingScript()); | 405 ASSERT(!hasParserBlockingScript()); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 | 529 |
| 523 DEFINE_TRACE(HTMLScriptRunner) { | 530 DEFINE_TRACE(HTMLScriptRunner) { |
| 524 visitor->trace(m_document); | 531 visitor->trace(m_document); |
| 525 visitor->trace(m_host); | 532 visitor->trace(m_host); |
| 526 visitor->trace(m_parserBlockingScript); | 533 visitor->trace(m_parserBlockingScript); |
| 527 visitor->trace(m_scriptsToExecuteAfterParsing); | 534 visitor->trace(m_scriptsToExecuteAfterParsing); |
| 528 ScriptResourceClient::trace(visitor); | 535 ScriptResourceClient::trace(visitor); |
| 529 } | 536 } |
| 530 | 537 |
| 531 } // namespace blink | 538 } // namespace blink |
| OLD | NEW |