diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-08-24 12:15:48 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-08-28 13:30:04 +0000 |
commit | b014812705fc80bff0a5c120dfcef88f349816dc (patch) | |
tree | 25a2e2d9fa285f1add86aa333389a839f81a39ae /chromium/third_party/blink/renderer/core/script/script_runner.cc | |
parent | 9f4560b1027ae06fdb497023cdcaf91b8511fa74 (diff) | |
download | qtwebengine-chromium-b014812705fc80bff0a5c120dfcef88f349816dc.tar.gz |
BASELINE: Update Chromium to 68.0.3440.125
Change-Id: I23f19369e01f688e496f5bf179abb521ad73874f
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/core/script/script_runner.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/core/script/script_runner.cc | 154 |
1 files changed, 87 insertions, 67 deletions
diff --git a/chromium/third_party/blink/renderer/core/script/script_runner.cc b/chromium/third_party/blink/renderer/core/script/script_runner.cc index 7c8216ab36f..8d524497be6 100644 --- a/chromium/third_party/blink/renderer/core/script/script_runner.cc +++ b/chromium/third_party/blink/renderer/core/script/script_runner.cc @@ -34,36 +34,31 @@ #include "third_party/blink/renderer/core/script/script_loader.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" namespace blink { ScriptRunner::ScriptRunner(Document* document) : document_(document), - task_runner_(document->GetTaskRunner(TaskType::kNetworking)), - number_of_in_order_scripts_with_pending_notification_(0), - is_suspended_(false) { + task_runner_(document->GetTaskRunner(TaskType::kNetworking)) { DCHECK(document); -#ifndef NDEBUG - number_of_extra_tasks_ = 0; -#endif } -void ScriptRunner::QueueScriptForExecution(ScriptLoader* script_loader, - AsyncExecutionType execution_type) { - DCHECK(script_loader); +void ScriptRunner::QueueScriptForExecution(PendingScript* pending_script) { + DCHECK(pending_script); document_->IncrementLoadEventDelayCount(); - switch (execution_type) { - case kAsync: - pending_async_scripts_.insert(script_loader); - TryStream(script_loader); + switch (pending_script->GetSchedulingType()) { + case ScriptSchedulingType::kAsync: + pending_async_scripts_.insert(pending_script); + TryStream(pending_script); break; - case kInOrder: - pending_in_order_scripts_.push_back(script_loader); + case ScriptSchedulingType::kInOrder: + pending_in_order_scripts_.push_back(pending_script); number_of_in_order_scripts_with_pending_notification_++; break; - case kNone: + + default: NOTREACHED(); break; } @@ -100,47 +95,48 @@ void ScriptRunner::Resume() { void ScriptRunner::ScheduleReadyInOrderScripts() { while (!pending_in_order_scripts_.IsEmpty() && - pending_in_order_scripts_.front()->IsReady()) { + pending_in_order_scripts_.front() + ->IsReady()) { in_order_scripts_to_execute_soon_.push_back( pending_in_order_scripts_.TakeFirst()); PostTask(FROM_HERE); } } -void ScriptRunner::NotifyScriptReady(ScriptLoader* script_loader, - AsyncExecutionType execution_type) { - SECURITY_CHECK(script_loader); - switch (execution_type) { - case kAsync: +void ScriptRunner::NotifyScriptReady(PendingScript* pending_script) { + SECURITY_CHECK(pending_script); + switch (pending_script->GetSchedulingType()) { + case ScriptSchedulingType::kAsync: // SECURITY_CHECK() makes us crash in a controlled way in error cases - // where the ScriptLoader is associated with the wrong ScriptRunner + // where the PendingScript is associated with the wrong ScriptRunner // (otherwise we'd cause a use-after-free in ~ScriptRunner when it tries // to detach). - SECURITY_CHECK(pending_async_scripts_.Contains(script_loader)); + SECURITY_CHECK(pending_async_scripts_.Contains(pending_script)); - pending_async_scripts_.erase(script_loader); - async_scripts_to_execute_soon_.push_back(script_loader); + pending_async_scripts_.erase(pending_script); + async_scripts_to_execute_soon_.push_back(pending_script); PostTask(FROM_HERE); TryStreamAny(); break; - case kInOrder: + case ScriptSchedulingType::kInOrder: SECURITY_CHECK(number_of_in_order_scripts_with_pending_notification_ > 0); number_of_in_order_scripts_with_pending_notification_--; ScheduleReadyInOrderScripts(); break; - case kNone: + + default: NOTREACHED(); break; } } -bool ScriptRunner::RemovePendingInOrderScript(ScriptLoader* script_loader) { +bool ScriptRunner::RemovePendingInOrderScript(PendingScript* pending_script) { auto it = std::find(pending_in_order_scripts_.begin(), - pending_in_order_scripts_.end(), script_loader); + pending_in_order_scripts_.end(), pending_script); if (it == pending_in_order_scripts_.end()) return false; pending_in_order_scripts_.erase(it); @@ -177,23 +173,35 @@ void ScriptRunner::MovePendingScript(Document& old_document, DCHECK(!old_document.GetFrame()); old_context_document = &old_document; } - if (old_context_document != new_context_document) { - old_context_document->GetScriptRunner()->MovePendingScript( - new_context_document->GetScriptRunner(), script_loader); + + if (old_context_document == new_context_document) + return; + + PendingScript* pending_script = + script_loader + ->GetPendingScriptIfControlledByScriptRunnerForCrossDocMove(); + if (!pending_script) { + // The ScriptLoader is not controlled by ScriptRunner. This can happen + // because MovePendingScript() is called for all <script> elements + // moved between Documents, not only for those controlled by ScriptRunner. + return; } + + old_context_document->GetScriptRunner()->MovePendingScript( + new_context_document->GetScriptRunner(), pending_script); } void ScriptRunner::MovePendingScript(ScriptRunner* new_runner, - ScriptLoader* script_loader) { - auto it = pending_async_scripts_.find(script_loader); + PendingScript* pending_script) { + auto it = pending_async_scripts_.find(pending_script); if (it != pending_async_scripts_.end()) { - new_runner->QueueScriptForExecution(script_loader, kAsync); + new_runner->QueueScriptForExecution(pending_script); pending_async_scripts_.erase(it); document_->DecrementLoadEventDelayCount(); return; } - if (RemovePendingInOrderScript(script_loader)) { - new_runner->QueueScriptForExecution(script_loader, kInOrder); + if (RemovePendingInOrderScript(pending_script)) { + new_runner->QueueScriptForExecution(pending_script); document_->DecrementLoadEventDelayCount(); } } @@ -202,30 +210,40 @@ bool ScriptRunner::ExecuteInOrderTask() { if (in_order_scripts_to_execute_soon_.IsEmpty()) return false; - PendingScript* pending_script = in_order_scripts_to_execute_soon_.front() - ->GetPendingScriptIfScriptIsAsync(); - if (pending_script && pending_script->IsCurrentlyStreaming()) - return false; + PendingScript* pending_script = in_order_scripts_to_execute_soon_.TakeFirst(); + DCHECK(pending_script); + DCHECK_EQ(pending_script->GetSchedulingType(), ScriptSchedulingType::kInOrder) + << "In-order scripts queue should not contain any async script."; - in_order_scripts_to_execute_soon_.TakeFirst()->Execute(); + pending_script->ExecuteScriptBlock(NullURL()); document_->DecrementLoadEventDelayCount(); return true; } bool ScriptRunner::ExecuteAsyncTask() { - for (auto iter = async_scripts_to_execute_soon_.begin(); - iter != async_scripts_to_execute_soon_.end(); ++iter) { - PendingScript* pending_script = (*iter)->GetPendingScriptIfScriptIsAsync(); - if (!pending_script || !pending_script->IsCurrentlyStreaming()) { - ScriptLoader* loader = *iter; - async_scripts_to_execute_soon_.erase(iter); - loader->Execute(); - document_->DecrementLoadEventDelayCount(); - return true; - } + // Find an async script loader which is not currently streaming. + auto it = std::find_if(async_scripts_to_execute_soon_.begin(), + async_scripts_to_execute_soon_.end(), + [](PendingScript* pending_script) { + DCHECK(pending_script); + return !pending_script->IsCurrentlyStreaming(); + }); + if (it == async_scripts_to_execute_soon_.end()) { + return false; } - return false; + + // Remove the async script loader from the ready-to-exec set and execute. + PendingScript* pending_script = *it; + async_scripts_to_execute_soon_.erase(it); + + DCHECK_EQ(pending_script->GetSchedulingType(), ScriptSchedulingType::kAsync) + << "Async scripts queue should not contain any in-order script."; + + pending_script->ExecuteScriptBlock(NullURL()); + + document_->DecrementLoadEventDelayCount(); + return true; } void ScriptRunner::ExecuteTask() { @@ -254,34 +272,36 @@ void ScriptRunner::TryStreamAny() { return; // Look through async_scripts_to_execute_soon_, and stream any one of them. - for (auto script_loader : async_scripts_to_execute_soon_) { - if (DoTryStream(script_loader)) + for (auto pending_script : async_scripts_to_execute_soon_) { + if (DoTryStream(pending_script)) return; } } -void ScriptRunner::TryStream(ScriptLoader* script_loader) { +void ScriptRunner::TryStream(PendingScript* pending_script) { if (!is_suspended_) - DoTryStream(script_loader); + DoTryStream(pending_script); } -bool ScriptRunner::DoTryStream(ScriptLoader* script_loader) { +bool ScriptRunner::DoTryStream(PendingScript* pending_script) { // Checks that all callers should have already done. DCHECK(!is_suspended_); - DCHECK(script_loader); + DCHECK(pending_script); - // Currently, we support streaming only for async scripts. - DCHECK(pending_async_scripts_.find(script_loader) != + // Currently, we stream only async scripts in this function. + // Note: HTMLParserScriptRunner kicks streaming for deferred or blocking + // scripts. + DCHECK(pending_async_scripts_.find(pending_script) != pending_async_scripts_.end() || std::find(async_scripts_to_execute_soon_.begin(), async_scripts_to_execute_soon_.end(), - script_loader) != async_scripts_to_execute_soon_.end()); + pending_script) != async_scripts_to_execute_soon_.end()); - PendingScript* pending_script = - script_loader->GetPendingScriptIfScriptIsAsync(); if (!pending_script) return false; + DCHECK_EQ(pending_script->GetSchedulingType(), ScriptSchedulingType::kAsync); + #ifndef NDEBUG bool was_already_streaming = pending_script->IsCurrentlyStreaming(); #endif @@ -310,7 +330,7 @@ void ScriptRunner::Trace(blink::Visitor* visitor) { visitor->Trace(in_order_scripts_to_execute_soon_); } -void ScriptRunner::TraceWrappers(const ScriptWrappableVisitor* visitor) const { +void ScriptRunner::TraceWrappers(ScriptWrappableVisitor* visitor) const { for (const auto& loader : pending_in_order_scripts_) visitor->TraceWrappers(loader); for (const auto& loader : pending_async_scripts_) |