Commit 3b4d46e3 authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[blink] Use scheduler for script streaming

Add a new feature flag, ScheduledScriptStreaming, which makes the script
streamer use the task scheduler for streaming tasks, rather than using a
dedicated ScriptStreamerThread.

Bug: chromium:865098
Bug: chromium:866868
Change-Id: I05ca411d8d5187c4b5180011ebce2a603e3944fe
Reviewed-on: https://chromium-review.googlesource.com/1145386
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarKouhei Ueno <kouhei@chromium.org>
Cr-Commit-Position: refs/heads/master@{#577543}
parent 1219b571
...@@ -406,6 +406,9 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs( ...@@ -406,6 +406,9 @@ void SetRuntimeFeaturesDefaultsAndUpdateFromArgs(
WebRuntimeFeatures::EnableWorkStealingInScriptRunner( WebRuntimeFeatures::EnableWorkStealingInScriptRunner(
base::FeatureList::IsEnabled(features::kWorkStealingInScriptRunner)); base::FeatureList::IsEnabled(features::kWorkStealingInScriptRunner));
WebRuntimeFeatures::EnableScheduledScriptStreaming(
base::FeatureList::IsEnabled(features::kScheduledScriptStreaming));
WebRuntimeFeatures::EnableFeatureFromString( WebRuntimeFeatures::EnableFeatureFromString(
"FeaturePolicyForPermissions", "FeaturePolicyForPermissions",
base::FeatureList::IsEnabled(features::kUseFeaturePolicyForPermissions)); base::FeatureList::IsEnabled(features::kUseFeaturePolicyForPermissions));
......
...@@ -590,6 +590,10 @@ const base::Feature kWipeCorruptV2IDBDatabases{ ...@@ -590,6 +590,10 @@ const base::Feature kWipeCorruptV2IDBDatabases{
const base::Feature kWorkStealingInScriptRunner{ const base::Feature kWorkStealingInScriptRunner{
"WorkStealingInScriptRunner", base::FEATURE_DISABLED_BY_DEFAULT}; "WorkStealingInScriptRunner", base::FEATURE_DISABLED_BY_DEFAULT};
// Enabled scheduler use for script streaming.
const base::Feature kScheduledScriptStreaming{
"ScheduledScriptStreaming", base::FEATURE_DISABLED_BY_DEFAULT};
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
// Autofill Accessibility in Android. // Autofill Accessibility in Android.
// crbug.com/627860 // crbug.com/627860
......
...@@ -135,6 +135,7 @@ CONTENT_EXPORT extern const base::Feature kWebXrHitTest; ...@@ -135,6 +135,7 @@ CONTENT_EXPORT extern const base::Feature kWebXrHitTest;
CONTENT_EXPORT extern const base::Feature kWebXrOrientationSensorDevice; CONTENT_EXPORT extern const base::Feature kWebXrOrientationSensorDevice;
CONTENT_EXPORT extern const base::Feature kWipeCorruptV2IDBDatabases; CONTENT_EXPORT extern const base::Feature kWipeCorruptV2IDBDatabases;
CONTENT_EXPORT extern const base::Feature kWorkStealingInScriptRunner; CONTENT_EXPORT extern const base::Feature kWorkStealingInScriptRunner;
CONTENT_EXPORT extern const base::Feature kScheduledScriptStreaming;
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
CONTENT_EXPORT extern const base::Feature kAndroidAutofillAccessibility; CONTENT_EXPORT extern const base::Feature kAndroidAutofillAccessibility;
......
...@@ -191,6 +191,7 @@ class WebRuntimeFeatures { ...@@ -191,6 +191,7 @@ class WebRuntimeFeatures {
BLINK_PLATFORM_EXPORT static void EnableV8ContextSnapshot(bool); BLINK_PLATFORM_EXPORT static void EnableV8ContextSnapshot(bool);
BLINK_PLATFORM_EXPORT static void EnableAutomationControlled(bool); BLINK_PLATFORM_EXPORT static void EnableAutomationControlled(bool);
BLINK_PLATFORM_EXPORT static void EnableWorkStealingInScriptRunner(bool); BLINK_PLATFORM_EXPORT static void EnableWorkStealingInScriptRunner(bool);
BLINK_PLATFORM_EXPORT static void EnableScheduledScriptStreaming(bool);
BLINK_PLATFORM_EXPORT static void EnableStopInBackground(bool); BLINK_PLATFORM_EXPORT static void EnableStopInBackground(bool);
BLINK_PLATFORM_EXPORT static void EnableStopNonTimersInBackground(bool); BLINK_PLATFORM_EXPORT static void EnableStopNonTimersInBackground(bool);
BLINK_PLATFORM_EXPORT static void EnablePWAFullCodeCache(bool); BLINK_PLATFORM_EXPORT static void EnablePWAFullCodeCache(bool);
......
...@@ -13,12 +13,15 @@ ...@@ -13,12 +13,15 @@
#include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h" #include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
#include "third_party/blink/renderer/core/script/classic_pending_script.h" #include "third_party/blink/renderer/core/script/classic_pending_script.h"
#include "third_party/blink/renderer/platform/cross_thread_functional.h" #include "third_party/blink/renderer/platform/cross_thread_functional.h"
#include "third_party/blink/renderer/platform/histogram.h" #include "third_party/blink/renderer/platform/histogram.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/loader/fetch/cached_metadata.h" #include "third_party/blink/renderer/platform/loader/fetch/cached_metadata.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource.h" #include "third_party/blink/renderer/platform/loader/fetch/resource.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/public/background_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/shared_buffer.h" #include "third_party/blink/renderer/platform/shared_buffer.h"
#include "third_party/blink/renderer/platform/wtf/deque.h" #include "third_party/blink/renderer/platform/wtf/deque.h"
...@@ -392,6 +395,19 @@ void ScriptStreamer::SuppressStreaming() { ...@@ -392,6 +395,19 @@ void ScriptStreamer::SuppressStreaming() {
streaming_suppressed_ = true; streaming_suppressed_ = true;
} }
static void RunScriptStreamingTask(
std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task,
ScriptStreamer* streamer) {
TRACE_EVENT1(
"v8,devtools.timeline", "v8.parseOnBackground", "data",
InspectorParseScriptEvent::Data(streamer->ScriptResourceIdentifier(),
streamer->ScriptURLString()));
// Running the task can and will block: SourceStream::GetSomeData will get
// called and it will block and wait for data from the network.
task->Run();
streamer->StreamingCompleteOnBackgroundThread();
}
void ScriptStreamer::NotifyAppendData(ScriptResource* resource) { void ScriptStreamer::NotifyAppendData(ScriptResource* resource) {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
if (streaming_suppressed_) if (streaming_suppressed_)
...@@ -436,11 +452,12 @@ void ScriptStreamer::NotifyAppendData(ScriptResource* resource) { ...@@ -436,11 +452,12 @@ void ScriptStreamer::NotifyAppendData(ScriptResource* resource) {
} }
} }
if (ScriptStreamerThread::Shared()->IsRunningTask()) { if (!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled() &&
// At the moment we only have one thread for running the tasks. A ScriptStreamerThread::Shared()->IsRunningTask()) {
// new task shouldn't be queued before the running task completes, // If scheduled script streaming is disabled, we only have one thread for
// because the running task can block and wait for data from the // running the tasks. A new task shouldn't be queued before the running
// network. // task completes, because the running task can block and wait for data
// from the network.
SuppressStreaming(); SuppressStreaming();
RecordNotStreamingReasonHistogram(script_type_, kThreadBusy); RecordNotStreamingReasonHistogram(script_type_, kThreadBusy);
RecordStartedStreamingHistogram(script_type_, 0); RecordStartedStreamingHistogram(script_type_, 0);
...@@ -476,10 +493,24 @@ void ScriptStreamer::NotifyAppendData(ScriptResource* resource) { ...@@ -476,10 +493,24 @@ void ScriptStreamer::NotifyAppendData(ScriptResource* resource) {
return; return;
} }
ScriptStreamerThread::Shared()->PostTask( if (RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()) {
CrossThreadBind(&ScriptStreamerThread::RunScriptStreamingTask, // Script streaming tasks are high priority, as they can block the
WTF::Passed(std::move(script_streaming_task)), // parser, and they can (and probably will) block during their own
WrapCrossThreadPersistent(this))); // execution as they wait for more input.
//
// TODO(leszeks): Decrease the priority of these tasks where possible.
BackgroundScheduler::PostOnBackgroundThreadWithTraits(
FROM_HERE, {base::TaskPriority::USER_BLOCKING, base::MayBlock()},
CrossThreadBind(RunScriptStreamingTask,
WTF::Passed(std::move(script_streaming_task)),
WrapCrossThreadPersistent(this)));
} else {
ScriptStreamerThread::Shared()->PostTask(
CrossThreadBind(&ScriptStreamerThread::RunScriptStreamingTask,
WTF::Passed(std::move(script_streaming_task)),
WrapCrossThreadPersistent(this)));
}
RecordStartedStreamingHistogram(script_type_, 1); RecordStartedStreamingHistogram(script_type_, 1);
} }
if (stream_) if (stream_)
......
...@@ -108,8 +108,10 @@ class ScriptStreamingTest : public testing::Test { ...@@ -108,8 +108,10 @@ class ScriptStreamingTest : public testing::Test {
} }
void ProcessTasksUntilStreamingComplete() { void ProcessTasksUntilStreamingComplete() {
while (ScriptStreamerThread::Shared()->IsRunningTask()) { if (!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()) {
test::RunPendingTasks(); while (ScriptStreamerThread::Shared()->IsRunningTask()) {
test::RunPendingTasks();
}
} }
// Once more, because the "streaming complete" notification might only // Once more, because the "streaming complete" notification might only
// now be in the task queue. // now be in the task queue.
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/bindings/core/v8/script_streamer.h" #include "third_party/blink/renderer/bindings/core/v8/script_streamer.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h" #include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/web_task_runner.h" #include "third_party/blink/renderer/platform/web_task_runner.h"
namespace blink { namespace blink {
...@@ -22,19 +23,24 @@ static ScriptStreamerThread* g_shared_thread = nullptr; ...@@ -22,19 +23,24 @@ static ScriptStreamerThread* g_shared_thread = nullptr;
static Mutex* g_mutex = nullptr; static Mutex* g_mutex = nullptr;
void ScriptStreamerThread::Init() { void ScriptStreamerThread::Init() {
DCHECK(!g_shared_thread); // Only enabled when ScheduledScriptStreaming is disabled.
DCHECK(IsMainThread()); if (!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()) {
// This is called in the main thread before any tasks are created, so no DCHECK(!g_shared_thread);
// locking is needed. DCHECK(IsMainThread());
g_mutex = new Mutex(); // This is called in the main thread before any tasks are created, so no
g_shared_thread = new ScriptStreamerThread(); // locking is needed.
g_mutex = new Mutex();
g_shared_thread = new ScriptStreamerThread();
}
} }
ScriptStreamerThread* ScriptStreamerThread::Shared() { ScriptStreamerThread* ScriptStreamerThread::Shared() {
DCHECK(!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled());
return g_shared_thread; return g_shared_thread;
} }
void ScriptStreamerThread::PostTask(CrossThreadClosure task) { void ScriptStreamerThread::PostTask(CrossThreadClosure task) {
DCHECK(!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled());
DCHECK(IsMainThread()); DCHECK(IsMainThread());
MutexLocker locker(mutex_); MutexLocker locker(mutex_);
DCHECK(!running_task_); DCHECK(!running_task_);
...@@ -60,6 +66,7 @@ WebThread& ScriptStreamerThread::PlatformThread() { ...@@ -60,6 +66,7 @@ WebThread& ScriptStreamerThread::PlatformThread() {
void ScriptStreamerThread::RunScriptStreamingTask( void ScriptStreamerThread::RunScriptStreamingTask(
std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task, std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task,
ScriptStreamer* streamer) { ScriptStreamer* streamer) {
DCHECK(!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled());
TRACE_EVENT1( TRACE_EVENT1(
"v8,devtools.timeline", "v8.parseOnBackground", "data", "v8,devtools.timeline", "v8.parseOnBackground", "data",
InspectorParseScriptEvent::Data(streamer->ScriptResourceIdentifier(), InspectorParseScriptEvent::Data(streamer->ScriptResourceIdentifier(),
......
...@@ -524,6 +524,10 @@ void WebRuntimeFeatures::EnableWorkStealingInScriptRunner(bool enable) { ...@@ -524,6 +524,10 @@ void WebRuntimeFeatures::EnableWorkStealingInScriptRunner(bool enable) {
RuntimeEnabledFeatures::SetWorkStealingInScriptRunnerEnabled(enable); RuntimeEnabledFeatures::SetWorkStealingInScriptRunnerEnabled(enable);
} }
void WebRuntimeFeatures::EnableScheduledScriptStreaming(bool enable) {
RuntimeEnabledFeatures::SetScheduledScriptStreamingEnabled(enable);
}
void WebRuntimeFeatures::EnableStopInBackground(bool enable) { void WebRuntimeFeatures::EnableStopInBackground(bool enable) {
RuntimeEnabledFeatures::SetStopInBackgroundEnabled(enable); RuntimeEnabledFeatures::SetStopInBackgroundEnabled(enable);
} }
......
...@@ -1117,6 +1117,9 @@ ...@@ -1117,6 +1117,9 @@
{ {
name: "RTCUnifiedPlanByDefault", name: "RTCUnifiedPlanByDefault",
}, },
{
name: "ScheduledScriptStreaming",
},
{ {
name: "ScriptedSpeech", name: "ScriptedSpeech",
status: "stable", status: "stable",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment