[gin] Implement v8::TaskRunners

With this CL the gin platform implements the new v8::Platform API
functions {GetForegroundTaskRunner} and {GetBackgroundTaskRunner}.

The existing task posting function of the V8Platform now also use these
taskrunners to post tasks. Thereby we can move some of the
implementation from the V8Platform and the PerIsolateData to the new
taskrunners.

[email protected]

Change-Id: I27ea6dd5f6ef8409e394f23ad914f468c09ded4a
Reviewed-on: https://chromium-review.googlesource.com/758578
Commit-Queue: Andreas Haas <[email protected]>
Reviewed-by: François Doray <[email protected]>
Reviewed-by: Ross McIlroy <[email protected]>
Cr-Commit-Position: refs/heads/master@{#517067}
diff --git a/gin/BUILD.gn b/gin/BUILD.gn
index ff5d79ef..d71adf51 100644
--- a/gin/BUILD.gn
+++ b/gin/BUILD.gn
@@ -59,6 +59,14 @@
     "shell_runner.h",
     "try_catch.cc",
     "try_catch.h",
+    "v8_background_task_runner.cc",
+    "v8_background_task_runner.h",
+    "v8_foreground_task_runner.cc",
+    "v8_foreground_task_runner.h",
+    "v8_foreground_task_runner_base.cc",
+    "v8_foreground_task_runner_base.h",
+    "v8_foreground_task_runner_with_locker.cc",
+    "v8_foreground_task_runner_with_locker.h",
     "v8_initializer.cc",
     "v8_initializer.h",
     "v8_isolate_memory_dump_provider.cc",
diff --git a/gin/per_isolate_data.cc b/gin/per_isolate_data.cc
index 029b93d..0bc8bec 100644
--- a/gin/per_isolate_data.cc
+++ b/gin/per_isolate_data.cc
@@ -10,6 +10,8 @@
 #include "base/single_thread_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "gin/public/gin_embedders.h"
+#include "gin/v8_foreground_task_runner.h"
+#include "gin/v8_foreground_task_runner_with_locker.h"
 
 using v8::ArrayBuffer;
 using v8::Eternal;
@@ -26,12 +28,16 @@
     ArrayBuffer::Allocator* allocator,
     IsolateHolder::AccessMode access_mode,
     scoped_refptr<base::SingleThreadTaskRunner> task_runner)
-    : isolate_(isolate),
-      allocator_(allocator),
-      access_mode_(access_mode),
-      task_runner_(
-          task_runner ? task_runner : base::ThreadTaskRunnerHandle::Get()) {
+    : isolate_(isolate), allocator_(allocator) {
   isolate_->SetData(kEmbedderNativeGin, this);
+
+  task_runner = task_runner ? task_runner : base::ThreadTaskRunnerHandle::Get();
+  if (access_mode == IsolateHolder::kUseLocker) {
+    task_runner_ = std::make_shared<V8ForegroundTaskRunnerWithLocker>(
+        isolate, task_runner);
+  } else {
+    task_runner_ = std::make_shared<V8ForegroundTaskRunner>(task_runner);
+  }
 }
 
 PerIsolateData::~PerIsolateData() {
@@ -120,7 +126,7 @@
 
 void PerIsolateData::EnableIdleTasks(
     std::unique_ptr<V8IdleTaskRunner> idle_task_runner) {
-  idle_task_runner_ = std::move(idle_task_runner);
+  task_runner_->EnableIdleTasks(std::move(idle_task_runner));
 }
 
 }  // namespace gin
diff --git a/gin/per_isolate_data.h b/gin/per_isolate_data.h
index ac0cf95..31a5cb4 100644
--- a/gin/per_isolate_data.h
+++ b/gin/per_isolate_data.h
@@ -12,16 +12,13 @@
 #include "base/memory/ref_counted.h"
 #include "gin/gin_export.h"
 #include "gin/public/isolate_holder.h"
-#include "gin/public/v8_idle_task_runner.h"
 #include "gin/public/wrapper_info.h"
+#include "gin/v8_foreground_task_runner_base.h"
 #include "v8/include/v8.h"
 
-namespace base {
-class SingleThreadTaskRunner;
-}
-
 namespace gin {
 
+class V8IdleTaskRunner;
 class IndexedPropertyInterceptor;
 class NamedPropertyInterceptor;
 class WrappableBase;
@@ -73,12 +70,7 @@
 
   v8::Isolate* isolate() { return isolate_; }
   v8::ArrayBuffer::Allocator* allocator() { return allocator_; }
-  base::SingleThreadTaskRunner* task_runner() { return task_runner_.get(); }
-  V8IdleTaskRunner* idle_task_runner() {
-    return idle_task_runner_.get();
-  }
-
-  IsolateHolder::AccessMode access_mode() const { return access_mode_; }
+  std::shared_ptr<v8::TaskRunner> task_runner() { return task_runner_; }
 
  private:
   typedef std::map<
@@ -94,13 +86,11 @@
   // owned by the IsolateHolder, which also owns the PerIsolateData.
   v8::Isolate* isolate_;
   v8::ArrayBuffer::Allocator* allocator_;
-  IsolateHolder::AccessMode access_mode_;
   ObjectTemplateMap object_templates_;
   FunctionTemplateMap function_templates_;
   IndexedPropertyInterceptorMap indexed_interceptors_;
   NamedPropertyInterceptorMap named_interceptors_;
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-  std::unique_ptr<V8IdleTaskRunner> idle_task_runner_;
+  std::shared_ptr<V8ForegroundTaskRunnerBase> task_runner_;
 
   DISALLOW_COPY_AND_ASSIGN(PerIsolateData);
 };
diff --git a/gin/public/v8_platform.h b/gin/public/v8_platform.h
index b25582c..cbbebc0 100644
--- a/gin/public/v8_platform.h
+++ b/gin/public/v8_platform.h
@@ -20,6 +20,10 @@
 
   // v8::Platform implementation.
   void OnCriticalMemoryPressure() override;
+  std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner(
+      v8::Isolate*) override;
+  std::shared_ptr<v8::TaskRunner> GetBackgroundTaskRunner(
+      v8::Isolate*) override;
   size_t NumberOfAvailableBackgroundThreads() override;
   void CallOnBackgroundThread(
       v8::Task* task,
diff --git a/gin/v8_background_task_runner.cc b/gin/v8_background_task_runner.cc
new file mode 100644
index 0000000..177f3d390
--- /dev/null
+++ b/gin/v8_background_task_runner.cc
@@ -0,0 +1,53 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <algorithm>
+
+#include "gin/v8_background_task_runner.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/task_scheduler/task_scheduler.h"
+#include "base/task_scheduler/task_traits.h"
+
+namespace gin {
+
+namespace {
+
+constexpr base::TaskTraits kBackgroundThreadTaskTraits = {
+    base::TaskPriority::USER_VISIBLE};
+
+}  // namespace
+
+void V8BackgroundTaskRunner::PostTask(std::unique_ptr<v8::Task> task) {
+  base::PostTaskWithTraits(FROM_HERE, kBackgroundThreadTaskTraits,
+                           base::BindOnce(&v8::Task::Run, std::move(task)));
+}
+
+void V8BackgroundTaskRunner::PostDelayedTask(std::unique_ptr<v8::Task> task,
+                                             double delay_in_seconds) {
+  base::PostDelayedTaskWithTraits(
+      FROM_HERE, kBackgroundThreadTaskTraits,
+      base::BindOnce(&v8::Task::Run, std::move(task)),
+      base::TimeDelta::FromSecondsD(delay_in_seconds));
+}
+
+void V8BackgroundTaskRunner::PostIdleTask(std::unique_ptr<v8::IdleTask> task) {
+  NOTREACHED() << "Idle tasks are not supported on background threads.";
+}
+
+bool V8BackgroundTaskRunner::IdleTasksEnabled() {
+  // No idle tasks on background threads.
+  return false;
+}
+
+// static
+size_t V8BackgroundTaskRunner::NumberOfAvailableBackgroundThreads() {
+  return std::max(1, base::TaskScheduler::GetInstance()
+                         ->GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated(
+                             kBackgroundThreadTaskTraits));
+}
+
+}  // namespace gin
diff --git a/gin/v8_background_task_runner.h b/gin/v8_background_task_runner.h
new file mode 100644
index 0000000..0c9855c2
--- /dev/null
+++ b/gin/v8_background_task_runner.h
@@ -0,0 +1,30 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GIN_V8_BACKGROUND_TASK_RUNNER_H
+#define GIN_V8_BACKGROUND_TASK_RUNNER_H
+
+#include "v8/include/v8-platform.h"
+
+namespace gin {
+
+class V8BackgroundTaskRunner : public v8::TaskRunner {
+ public:
+  // Returns the number of available background threads, which is always >= 1.
+  static size_t NumberOfAvailableBackgroundThreads();
+
+  // v8::Platform implementation.
+  void PostTask(std::unique_ptr<v8::Task> task) override;
+
+  void PostDelayedTask(std::unique_ptr<v8::Task> task,
+                       double delay_in_seconds) override;
+
+  void PostIdleTask(std::unique_ptr<v8::IdleTask> task) override;
+
+  bool IdleTasksEnabled() override;
+};
+
+}  // namespace gin
+
+#endif  // GIN_V8_BACKGROUND_TASK_RUNNER_H
diff --git a/gin/v8_foreground_task_runner.cc b/gin/v8_foreground_task_runner.cc
new file mode 100644
index 0000000..afc2824
--- /dev/null
+++ b/gin/v8_foreground_task_runner.cc
@@ -0,0 +1,39 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gin/v8_foreground_task_runner.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
+
+namespace gin {
+
+V8ForegroundTaskRunner::V8ForegroundTaskRunner(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+    : task_runner_(std::move(task_runner)) {
+  DCHECK(task_runner_);
+}
+
+V8ForegroundTaskRunner::~V8ForegroundTaskRunner() {}
+
+void V8ForegroundTaskRunner::PostTask(std::unique_ptr<v8::Task> task) {
+  task_runner_->PostTask(FROM_HERE,
+                         base::BindOnce(&v8::Task::Run, std::move(task)));
+}
+
+void V8ForegroundTaskRunner::PostDelayedTask(std::unique_ptr<v8::Task> task,
+                                             double delay_in_seconds) {
+  task_runner_->PostDelayedTask(
+      FROM_HERE, base::BindOnce(&v8::Task::Run, std::move(task)),
+      base::TimeDelta::FromSecondsD(delay_in_seconds));
+}
+
+void V8ForegroundTaskRunner::PostIdleTask(std::unique_ptr<v8::IdleTask> task) {
+  DCHECK(IdleTasksEnabled());
+  idle_task_runner()->PostIdleTask(task.release());
+}
+
+}  // namespace gin
diff --git a/gin/v8_foreground_task_runner.h b/gin/v8_foreground_task_runner.h
new file mode 100644
index 0000000..b9da5f1
--- /dev/null
+++ b/gin/v8_foreground_task_runner.h
@@ -0,0 +1,38 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_FOREGROUND_TASK_RUNNER_H
+#define V8_FOREGROUND_TASK_RUNNER_H
+
+#include "base/memory/ref_counted.h"
+#include "gin/v8_foreground_task_runner_base.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+namespace gin {
+
+class V8ForegroundTaskRunner : public V8ForegroundTaskRunnerBase {
+ public:
+  V8ForegroundTaskRunner(
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+
+  ~V8ForegroundTaskRunner() override;
+
+  // v8::Platform implementation.
+  void PostTask(std::unique_ptr<v8::Task> task) override;
+
+  void PostDelayedTask(std::unique_ptr<v8::Task> task,
+                       double delay_in_seconds) override;
+
+  void PostIdleTask(std::unique_ptr<v8::IdleTask> task) override;
+
+ private:
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+};
+
+}  // namespace gin
+
+#endif  // V8_FOREGROUND_TASK_RUNNER_H
diff --git a/gin/v8_foreground_task_runner_base.cc b/gin/v8_foreground_task_runner_base.cc
new file mode 100644
index 0000000..53f6104
--- /dev/null
+++ b/gin/v8_foreground_task_runner_base.cc
@@ -0,0 +1,22 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "v8_foreground_task_runner_base.h"
+
+namespace gin {
+
+V8ForegroundTaskRunnerBase::V8ForegroundTaskRunnerBase() {}
+
+V8ForegroundTaskRunnerBase::~V8ForegroundTaskRunnerBase() {}
+
+void V8ForegroundTaskRunnerBase::EnableIdleTasks(
+    std::unique_ptr<V8IdleTaskRunner> idle_task_runner) {
+  idle_task_runner_ = std::move(idle_task_runner);
+}
+
+bool V8ForegroundTaskRunnerBase::IdleTasksEnabled() {
+  return idle_task_runner() != nullptr;
+}
+
+}  // namespace gin
diff --git a/gin/v8_foreground_task_runner_base.h b/gin/v8_foreground_task_runner_base.h
new file mode 100644
index 0000000..112727f0
--- /dev/null
+++ b/gin/v8_foreground_task_runner_base.h
@@ -0,0 +1,36 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_FOREGROUND_TASK_RUNNER_BASE_H
+#define V8_FOREGROUND_TASK_RUNNER_BASE_H
+
+#include "v8/include/v8-platform.h"
+
+#include "gin/gin_export.h"
+#include "gin/public/v8_idle_task_runner.h"
+
+namespace gin {
+
+// Base class for the V8ForegroundTaskRunners to share the capability of
+// enabling IdleTasks.
+class V8ForegroundTaskRunnerBase : public v8::TaskRunner {
+ public:
+  V8ForegroundTaskRunnerBase();
+
+  ~V8ForegroundTaskRunnerBase() override;
+
+  void EnableIdleTasks(std::unique_ptr<V8IdleTaskRunner> idle_task_runner);
+
+  bool IdleTasksEnabled() override;
+
+ protected:
+  V8IdleTaskRunner* idle_task_runner() { return idle_task_runner_.get(); }
+
+ private:
+  std::unique_ptr<V8IdleTaskRunner> idle_task_runner_;
+};
+
+}  // namespace gin
+
+#endif /* !V8_FOREGROUND_TASK_RUNNER_BASE_H */
diff --git a/gin/v8_foreground_task_runner_with_locker.cc b/gin/v8_foreground_task_runner_with_locker.cc
new file mode 100644
index 0000000..4a60141
--- /dev/null
+++ b/gin/v8_foreground_task_runner_with_locker.cc
@@ -0,0 +1,77 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gin/v8_foreground_task_runner_with_locker.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "v8/include/v8.h"
+
+namespace gin {
+
+V8ForegroundTaskRunnerWithLocker::V8ForegroundTaskRunnerWithLocker(
+    v8::Isolate* isolate,
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+    : isolate_(isolate), task_runner_(std::move(task_runner)) {
+  DCHECK(task_runner_);
+}
+
+V8ForegroundTaskRunnerWithLocker::~V8ForegroundTaskRunnerWithLocker() {}
+
+namespace {
+
+void RunWithLocker(v8::Isolate* isolate, std::unique_ptr<v8::Task> task) {
+  v8::Locker lock(isolate);
+  task->Run();
+}
+
+class IdleTaskWithLocker : public v8::IdleTask {
+ public:
+  IdleTaskWithLocker(v8::Isolate* isolate, std::unique_ptr<v8::IdleTask> task)
+      : isolate_(isolate), task_(std::move(task)) {}
+
+  ~IdleTaskWithLocker() override = default;
+
+  // v8::IdleTask implementation.
+  void Run(double deadline_in_seconds) override {
+    v8::Locker lock(isolate_);
+    task_->Run(deadline_in_seconds);
+  }
+
+ private:
+  v8::Isolate* isolate_;
+  std::unique_ptr<v8::IdleTask> task_;
+
+  DISALLOW_COPY_AND_ASSIGN(IdleTaskWithLocker);
+};
+
+}  // namespace
+
+void V8ForegroundTaskRunnerWithLocker::PostTask(
+    std::unique_ptr<v8::Task> task) {
+  task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(RunWithLocker, base::Unretained(isolate_),
+                                std::move(task)));
+}
+
+void V8ForegroundTaskRunnerWithLocker::PostDelayedTask(
+    std::unique_ptr<v8::Task> task,
+    double delay_in_seconds) {
+  task_runner_->PostDelayedTask(
+      FROM_HERE,
+      base::BindOnce(RunWithLocker, base::Unretained(isolate_),
+                     std::move(task)),
+      base::TimeDelta::FromSecondsD(delay_in_seconds));
+}
+
+void V8ForegroundTaskRunnerWithLocker::PostIdleTask(
+    std::unique_ptr<v8::IdleTask> task) {
+  DCHECK(IdleTasksEnabled());
+  idle_task_runner()->PostIdleTask(
+      new IdleTaskWithLocker(isolate_, std::move(task)));
+}
+
+}  // namespace gin
diff --git a/gin/v8_foreground_task_runner_with_locker.h b/gin/v8_foreground_task_runner_with_locker.h
new file mode 100644
index 0000000..68c716f
--- /dev/null
+++ b/gin/v8_foreground_task_runner_with_locker.h
@@ -0,0 +1,40 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_FOREGROUND_TASK_RUNNER_WITH_LOCKER_H
+#define V8_FOREGROUND_TASK_RUNNER_WITH_LOCKER_H
+
+#include "base/memory/ref_counted.h"
+#include "gin/v8_foreground_task_runner_base.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+namespace gin {
+
+class V8ForegroundTaskRunnerWithLocker : public V8ForegroundTaskRunnerBase {
+ public:
+  V8ForegroundTaskRunnerWithLocker(
+      v8::Isolate* isolate,
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+
+  ~V8ForegroundTaskRunnerWithLocker() override;
+
+  // v8::Platform implementation.
+  void PostTask(std::unique_ptr<v8::Task> task) override;
+
+  void PostDelayedTask(std::unique_ptr<v8::Task> task,
+                       double delay_in_seconds) override;
+
+  void PostIdleTask(std::unique_ptr<v8::IdleTask> task) override;
+
+ private:
+  v8::Isolate* isolate_;
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+};
+
+}  // namespace gin
+
+#endif  // V8_FOREGROUND_TASK_RUNNER_WITH_LOCKER_H
diff --git a/gin/v8_platform.cc b/gin/v8_platform.cc
index e9b7b02..8b071b8 100644
--- a/gin/v8_platform.cc
+++ b/gin/v8_platform.cc
@@ -16,41 +16,14 @@
 #include "base/trace_event/trace_event.h"
 #include "build/build_config.h"
 #include "gin/per_isolate_data.h"
+#include "gin/v8_background_task_runner.h"
 
 namespace gin {
 
 namespace {
 
-constexpr base::TaskTraits kBackgroundThreadTaskTraits = {
-    base::TaskPriority::USER_VISIBLE};
-
 base::LazyInstance<V8Platform>::Leaky g_v8_platform = LAZY_INSTANCE_INITIALIZER;
 
-void RunWithLocker(v8::Isolate* isolate, v8::Task* task) {
-  v8::Locker lock(isolate);
-  task->Run();
-}
-
-class IdleTaskWithLocker : public v8::IdleTask {
- public:
-  IdleTaskWithLocker(v8::Isolate* isolate, v8::IdleTask* task)
-      : isolate_(isolate), task_(task) {}
-
-  ~IdleTaskWithLocker() override = default;
-
-  // v8::IdleTask implementation.
-  void Run(double deadline_in_seconds) override {
-    v8::Locker lock(isolate_);
-    task_->Run(deadline_in_seconds);
-  }
-
- private:
-  v8::Isolate* isolate_;
-  std::unique_ptr<v8::IdleTask> task_;
-
-  DISALLOW_COPY_AND_ASSIGN(IdleTaskWithLocker);
-};
-
 void PrintStackTrace() {
   base::debug::StackTrace trace;
   trace.Print();
@@ -205,61 +178,48 @@
 #endif
 }
 
+std::shared_ptr<v8::TaskRunner> V8Platform::GetForegroundTaskRunner(
+    v8::Isolate* isolate) {
+  PerIsolateData* data = PerIsolateData::From(isolate);
+  return data->task_runner();
+}
+
+std::shared_ptr<v8::TaskRunner> V8Platform::GetBackgroundTaskRunner(
+    v8::Isolate* isolate) {
+  return std::make_shared<V8BackgroundTaskRunner>();
+}
+
 size_t V8Platform::NumberOfAvailableBackgroundThreads() {
-  return std::max(1, base::TaskScheduler::GetInstance()
-                         ->GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated(
-                             kBackgroundThreadTaskTraits));
+  return V8BackgroundTaskRunner::NumberOfAvailableBackgroundThreads();
 }
 
 void V8Platform::CallOnBackgroundThread(
     v8::Task* task,
     v8::Platform::ExpectedRuntime expected_runtime) {
-  base::PostTaskWithTraits(FROM_HERE, kBackgroundThreadTaskTraits,
-                           base::Bind(&v8::Task::Run, base::Owned(task)));
+  GetBackgroundTaskRunner(nullptr)->PostTask(std::unique_ptr<v8::Task>(task));
 }
 
 void V8Platform::CallOnForegroundThread(v8::Isolate* isolate, v8::Task* task) {
   PerIsolateData* data = PerIsolateData::From(isolate);
-  if (data->access_mode() == IsolateHolder::kUseLocker) {
-    data->task_runner()->PostTask(
-        FROM_HERE, base::Bind(RunWithLocker, base::Unretained(isolate),
-                              base::Owned(task)));
-  } else {
-    data->task_runner()->PostTask(
-        FROM_HERE, base::Bind(&v8::Task::Run, base::Owned(task)));
-  }
+  data->task_runner()->PostTask(std::unique_ptr<v8::Task>(task));
 }
 
 void V8Platform::CallDelayedOnForegroundThread(v8::Isolate* isolate,
                                                v8::Task* task,
                                                double delay_in_seconds) {
   PerIsolateData* data = PerIsolateData::From(isolate);
-  if (data->access_mode() == IsolateHolder::kUseLocker) {
-    data->task_runner()->PostDelayedTask(
-        FROM_HERE,
-        base::Bind(RunWithLocker, base::Unretained(isolate), base::Owned(task)),
-        base::TimeDelta::FromSecondsD(delay_in_seconds));
-  } else {
-    data->task_runner()->PostDelayedTask(
-        FROM_HERE, base::Bind(&v8::Task::Run, base::Owned(task)),
-        base::TimeDelta::FromSecondsD(delay_in_seconds));
-  }
+  data->task_runner()->PostDelayedTask(std::unique_ptr<v8::Task>(task),
+                                       delay_in_seconds);
 }
 
 void V8Platform::CallIdleOnForegroundThread(v8::Isolate* isolate,
                                             v8::IdleTask* task) {
   PerIsolateData* data = PerIsolateData::From(isolate);
-  DCHECK(data->idle_task_runner());
-  if (data->access_mode() == IsolateHolder::kUseLocker) {
-    data->idle_task_runner()->PostIdleTask(
-        new IdleTaskWithLocker(isolate, task));
-  } else {
-    data->idle_task_runner()->PostIdleTask(task);
-  }
+  data->task_runner()->PostIdleTask(std::unique_ptr<v8::IdleTask>(task));
 }
 
 bool V8Platform::IdleTasksEnabled(v8::Isolate* isolate) {
-  return PerIsolateData::From(isolate)->idle_task_runner() != nullptr;
+  return PerIsolateData::From(isolate)->task_runner()->IdleTasksEnabled();
 }
 
 double V8Platform::MonotonicallyIncreasingTime() {