[V8 Platform] Make CallOnWorkerThread use std::unique_ptr

This is done now while embedders have yet to adapt to the new API before
it becomes hard to migrate.

Also renamed variable/methods to use "worker threads" rather than
"background" nomenclature.

Extracted from https://chromium-review.googlesource.com/c/v8/v8/+/978443/7
while resolving the more contentious bits around using task runners.

TBR=rmcilroy@chromium.org

Bug: chromium:817421
Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
Change-Id: Ie3ddf15a708e829c0f718d89bebf3e96d1990c16
Reviewed-on: https://chromium-review.googlesource.com/980953
Commit-Queue: Gabriel Charette <gab@chromium.org>
Reviewed-by: Gabriel Charette <gab@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52231}
This commit is contained in:
Gabriel Charette 2018-03-26 12:44:23 -04:00 committed by Commit Bot
parent 7e78e45b90
commit 1983f3055d
23 changed files with 179 additions and 168 deletions

View File

@ -2861,12 +2861,12 @@ v8_component("v8_libplatform") {
"include/libplatform/libplatform-export.h", "include/libplatform/libplatform-export.h",
"include/libplatform/libplatform.h", "include/libplatform/libplatform.h",
"include/libplatform/v8-tracing.h", "include/libplatform/v8-tracing.h",
"src/libplatform/default-background-task-runner.cc",
"src/libplatform/default-background-task-runner.h",
"src/libplatform/default-foreground-task-runner.cc", "src/libplatform/default-foreground-task-runner.cc",
"src/libplatform/default-foreground-task-runner.h", "src/libplatform/default-foreground-task-runner.h",
"src/libplatform/default-platform.cc", "src/libplatform/default-platform.cc",
"src/libplatform/default-platform.h", "src/libplatform/default-platform.h",
"src/libplatform/default-worker-threads-task-runner.cc",
"src/libplatform/default-worker-threads-task-runner.h",
"src/libplatform/task-queue.cc", "src/libplatform/task-queue.cc",
"src/libplatform/task-queue.h", "src/libplatform/task-queue.h",
"src/libplatform/tracing/trace-buffer.cc", "src/libplatform/tracing/trace-buffer.cc",

View File

@ -363,8 +363,7 @@ class Platform {
* thread the task will be run on. * thread the task will be run on.
*/ */
V8_DEPRECATE_SOON( V8_DEPRECATE_SOON(
"ExpectedRuntime is deprecated, use CallOnWorkerThread(Task*) " "ExpectedRuntime is deprecated, use CallOnWorkerThread() instead.",
"instead.",
virtual void CallOnBackgroundThread(Task* task, virtual void CallOnBackgroundThread(Task* task,
ExpectedRuntime expected_runtime)) { ExpectedRuntime expected_runtime)) {
// An implementation needs to be provided here because this is called by the // An implementation needs to be provided here because this is called by the
@ -381,17 +380,18 @@ class Platform {
* TODO(gab): Make pure virtual when all embedders override this instead of * TODO(gab): Make pure virtual when all embedders override this instead of
* CallOnBackgroundThread(). * CallOnBackgroundThread().
*/ */
virtual void CallOnWorkerThread(Task* task) { virtual void CallOnWorkerThread(std::unique_ptr<Task> task) {
CallOnBackgroundThread(task, kShortRunningTask); CallOnBackgroundThread(task.release(), kShortRunningTask);
} }
/** /**
* Schedules a task that blocks the main thread to be invoked with * Schedules a task that blocks the main thread to be invoked with
* high-priority on a worker thread. * high-priority on a worker thread.
*/ */
virtual void CallBlockingTaskOnWorkerThread(Task* task) { virtual void CallBlockingTaskOnWorkerThread(std::unique_ptr<Task> task) {
// TODO(gab): Make pure-virtual when all embedders override this. // Embedders may optionally override this to process these tasks in a high
CallOnWorkerThread(task); // priority pool.
CallOnWorkerThread(std::move(task));
} }
/** /**

View File

@ -7,6 +7,7 @@
#include "include/v8-platform.h" #include "include/v8-platform.h"
#include "include/v8.h" #include "include/v8.h"
#include "src/base/platform/time.h" #include "src/base/platform/time.h"
#include "src/base/template-utils.h"
#include "src/cancelable-task.h" #include "src/cancelable-task.h"
#include "src/compilation-info.h" #include "src/compilation-info.h"
#include "src/compiler-dispatcher/compiler-dispatcher-job.h" #include "src/compiler-dispatcher/compiler-dispatcher-job.h"
@ -123,11 +124,11 @@ void CompilerDispatcher::AbortTask::RunInternal() {
dispatcher_->AbortInactiveJobs(); dispatcher_->AbortInactiveJobs();
} }
class CompilerDispatcher::BackgroundTask : public CancelableTask { class CompilerDispatcher::WorkerTask : public CancelableTask {
public: public:
BackgroundTask(Isolate* isolate, CancelableTaskManager* task_manager, WorkerTask(Isolate* isolate, CancelableTaskManager* task_manager,
CompilerDispatcher* dispatcher); CompilerDispatcher* dispatcher);
~BackgroundTask() override; ~WorkerTask() override;
// CancelableTask implementation. // CancelableTask implementation.
void RunInternal() override; void RunInternal() override;
@ -135,17 +136,17 @@ class CompilerDispatcher::BackgroundTask : public CancelableTask {
private: private:
CompilerDispatcher* dispatcher_; CompilerDispatcher* dispatcher_;
DISALLOW_COPY_AND_ASSIGN(BackgroundTask); DISALLOW_COPY_AND_ASSIGN(WorkerTask);
}; };
CompilerDispatcher::BackgroundTask::BackgroundTask( CompilerDispatcher::WorkerTask::WorkerTask(Isolate* isolate,
Isolate* isolate, CancelableTaskManager* task_manager, CancelableTaskManager* task_manager,
CompilerDispatcher* dispatcher) CompilerDispatcher* dispatcher)
: CancelableTask(task_manager), dispatcher_(dispatcher) {} : CancelableTask(task_manager), dispatcher_(dispatcher) {}
CompilerDispatcher::BackgroundTask::~BackgroundTask() {} CompilerDispatcher::WorkerTask::~WorkerTask() {}
void CompilerDispatcher::BackgroundTask::RunInternal() { void CompilerDispatcher::WorkerTask::RunInternal() {
dispatcher_->DoBackgroundWork(); dispatcher_->DoBackgroundWork();
} }
@ -188,7 +189,7 @@ CompilerDispatcher::CompilerDispatcher(Isolate* isolate, Platform* platform,
memory_pressure_level_(MemoryPressureLevel::kNone), memory_pressure_level_(MemoryPressureLevel::kNone),
abort_(false), abort_(false),
idle_task_scheduled_(false), idle_task_scheduled_(false),
num_background_tasks_(0), num_worker_tasks_(0),
main_thread_blocking_on_job_(nullptr), main_thread_blocking_on_job_(nullptr),
block_for_testing_(false), block_for_testing_(false),
semaphore_for_testing_(0) { semaphore_for_testing_(0) {
@ -434,7 +435,7 @@ void CompilerDispatcher::AbortInactiveJobs() {
} }
if (jobs_.empty()) { if (jobs_.empty()) {
base::LockGuard<base::Mutex> lock(&mutex_); base::LockGuard<base::Mutex> lock(&mutex_);
if (num_background_tasks_ == 0) abort_ = false; if (num_worker_tasks_ == 0) abort_ = false;
} }
} }
@ -511,22 +512,22 @@ void CompilerDispatcher::ConsiderJobForBackgroundProcessing(
base::LockGuard<base::Mutex> lock(&mutex_); base::LockGuard<base::Mutex> lock(&mutex_);
pending_background_jobs_.insert(job); pending_background_jobs_.insert(job);
} }
ScheduleMoreBackgroundTasksIfNeeded(); ScheduleMoreWorkerTasksIfNeeded();
} }
void CompilerDispatcher::ScheduleMoreBackgroundTasksIfNeeded() { void CompilerDispatcher::ScheduleMoreWorkerTasksIfNeeded() {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.CompilerDispatcherScheduleMoreBackgroundTasksIfNeeded"); "V8.CompilerDispatcherScheduleMoreWorkerTasksIfNeeded");
{ {
base::LockGuard<base::Mutex> lock(&mutex_); base::LockGuard<base::Mutex> lock(&mutex_);
if (pending_background_jobs_.empty()) return; if (pending_background_jobs_.empty()) return;
if (platform_->NumberOfWorkerThreads() <= num_background_tasks_) { if (platform_->NumberOfWorkerThreads() <= num_worker_tasks_) {
return; return;
} }
++num_background_tasks_; ++num_worker_tasks_;
} }
platform_->CallOnWorkerThread( platform_->CallOnWorkerThread(
new BackgroundTask(isolate_, task_manager_.get(), this)); base::make_unique<WorkerTask>(isolate_, task_manager_.get(), this));
} }
void CompilerDispatcher::DoBackgroundWork() { void CompilerDispatcher::DoBackgroundWork() {
@ -570,7 +571,7 @@ void CompilerDispatcher::DoBackgroundWork() {
{ {
base::LockGuard<base::Mutex> lock(&mutex_); base::LockGuard<base::Mutex> lock(&mutex_);
--num_background_tasks_; --num_worker_tasks_;
if (running_background_jobs_.empty() && abort_) { if (running_background_jobs_.empty() && abort_) {
// This is the last background job that finished. The abort task // This is the last background job that finished. The abort task
@ -718,7 +719,7 @@ CompilerDispatcher::JobMap::const_iterator CompilerDispatcher::RemoveJob(
it = jobs_.erase(it); it = jobs_.erase(it);
if (jobs_.empty()) { if (jobs_.empty()) {
base::LockGuard<base::Mutex> lock(&mutex_); base::LockGuard<base::Mutex> lock(&mutex_);
if (num_background_tasks_ == 0) abort_ = false; if (num_worker_tasks_ == 0) abort_ = false;
} }
return it; return it;
} }

View File

@ -117,16 +117,16 @@ class V8_EXPORT_PRIVATE CompilerDispatcher {
FRIEND_TEST(CompilerDispatcherTest, EnqueueAndStepParsed); FRIEND_TEST(CompilerDispatcherTest, EnqueueAndStepParsed);
FRIEND_TEST(CompilerDispatcherTest, IdleTaskSmallIdleTime); FRIEND_TEST(CompilerDispatcherTest, IdleTaskSmallIdleTime);
FRIEND_TEST(CompilerDispatcherTest, CompileOnBackgroundThread); FRIEND_TEST(CompilerDispatcherTest, CompileOnBackgroundThread);
FRIEND_TEST(CompilerDispatcherTest, FinishNowWithBackgroundTask); FRIEND_TEST(CompilerDispatcherTest, FinishNowWithWorkerTask);
FRIEND_TEST(CompilerDispatcherTest, AsyncAbortAllPendingBackgroundTask); FRIEND_TEST(CompilerDispatcherTest, AsyncAbortAllPendingWorkerTask);
FRIEND_TEST(CompilerDispatcherTest, AsyncAbortAllRunningBackgroundTask); FRIEND_TEST(CompilerDispatcherTest, AsyncAbortAllRunningWorkerTask);
FRIEND_TEST(CompilerDispatcherTest, FinishNowDuringAbortAll); FRIEND_TEST(CompilerDispatcherTest, FinishNowDuringAbortAll);
FRIEND_TEST(CompilerDispatcherTest, CompileMultipleOnBackgroundThread); FRIEND_TEST(CompilerDispatcherTest, CompileMultipleOnBackgroundThread);
typedef std::map<JobId, std::unique_ptr<CompilerDispatcherJob>> JobMap; typedef std::map<JobId, std::unique_ptr<CompilerDispatcherJob>> JobMap;
typedef IdentityMap<JobId, FreeStoreAllocationPolicy> SharedToJobIdMap; typedef IdentityMap<JobId, FreeStoreAllocationPolicy> SharedToJobIdMap;
class AbortTask; class AbortTask;
class BackgroundTask; class WorkerTask;
class IdleTask; class IdleTask;
void WaitForJobIfRunningOnBackground(CompilerDispatcherJob* job); void WaitForJobIfRunningOnBackground(CompilerDispatcherJob* job);
@ -135,7 +135,7 @@ class V8_EXPORT_PRIVATE CompilerDispatcher {
bool CanEnqueue(Handle<SharedFunctionInfo> function); bool CanEnqueue(Handle<SharedFunctionInfo> function);
JobMap::const_iterator GetJobFor(Handle<SharedFunctionInfo> shared) const; JobMap::const_iterator GetJobFor(Handle<SharedFunctionInfo> shared) const;
void ConsiderJobForBackgroundProcessing(CompilerDispatcherJob* job); void ConsiderJobForBackgroundProcessing(CompilerDispatcherJob* job);
void ScheduleMoreBackgroundTasksIfNeeded(); void ScheduleMoreWorkerTasksIfNeeded();
void ScheduleIdleTaskFromAnyThread(); void ScheduleIdleTaskFromAnyThread();
void ScheduleIdleTaskIfNeeded(); void ScheduleIdleTaskIfNeeded();
void ScheduleAbortTask(); void ScheduleAbortTask();
@ -183,8 +183,8 @@ class V8_EXPORT_PRIVATE CompilerDispatcher {
bool idle_task_scheduled_; bool idle_task_scheduled_;
// Number of scheduled or running BackgroundTask objects. // Number of scheduled or running WorkerTask objects.
int num_background_tasks_; int num_worker_tasks_;
// The set of CompilerDispatcherJobs that can be advanced on any thread. // The set of CompilerDispatcherJobs that can be advanced on any thread.
std::unordered_set<CompilerDispatcherJob*> pending_background_jobs_; std::unordered_set<CompilerDispatcherJob*> pending_background_jobs_;

View File

@ -5,6 +5,7 @@
#include "src/compiler-dispatcher/optimizing-compile-dispatcher.h" #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
#include "src/base/atomicops.h" #include "src/base/atomicops.h"
#include "src/base/template-utils.h"
#include "src/cancelable-task.h" #include "src/cancelable-task.h"
#include "src/compilation-info.h" #include "src/compilation-info.h"
#include "src/compiler.h" #include "src/compiler.h"
@ -225,14 +226,14 @@ void OptimizingCompileDispatcher::QueueForOptimization(CompilationJob* job) {
blocked_jobs_++; blocked_jobs_++;
} else { } else {
V8::GetCurrentPlatform()->CallOnWorkerThread( V8::GetCurrentPlatform()->CallOnWorkerThread(
new CompileTask(isolate_, this)); base::make_unique<CompileTask>(isolate_, this));
} }
} }
void OptimizingCompileDispatcher::Unblock() { void OptimizingCompileDispatcher::Unblock() {
while (blocked_jobs_ > 0) { while (blocked_jobs_ > 0) {
V8::GetCurrentPlatform()->CallOnWorkerThread( V8::GetCurrentPlatform()->CallOnWorkerThread(
new CompileTask(isolate_, this)); base::make_unique<CompileTask>(isolate_, this));
blocked_jobs_--; blocked_jobs_--;
} }
} }

View File

@ -191,11 +191,10 @@ class PredictablePlatform : public Platform {
return platform_->GetForegroundTaskRunner(isolate); return platform_->GetForegroundTaskRunner(isolate);
} }
void CallOnWorkerThread(Task* task) override { void CallOnWorkerThread(std::unique_ptr<Task> task) override {
// It's not defined when background tasks are being executed, so we can just // It's not defined when background tasks are being executed, so we can just
// execute them right away. // execute them right away.
task->Run(); task->Run();
delete task;
} }
void CallOnForegroundThread(v8::Isolate* isolate, Task* task) override { void CallOnForegroundThread(v8::Isolate* isolate, Task* task) override {

View File

@ -4,6 +4,7 @@
#include "src/heap/array-buffer-collector.h" #include "src/heap/array-buffer-collector.h"
#include "src/base/template-utils.h"
#include "src/heap/array-buffer-tracker.h" #include "src/heap/array-buffer-tracker.h"
#include "src/heap/heap-inl.h" #include "src/heap/heap-inl.h"
@ -48,8 +49,8 @@ class ArrayBufferCollector::FreeingTask final : public CancelableTask {
void ArrayBufferCollector::FreeAllocationsOnBackgroundThread() { void ArrayBufferCollector::FreeAllocationsOnBackgroundThread() {
heap_->account_external_memory_concurrently_freed(); heap_->account_external_memory_concurrently_freed();
if (!heap_->IsTearingDown() && FLAG_concurrent_array_buffer_freeing) { if (!heap_->IsTearingDown() && FLAG_concurrent_array_buffer_freeing) {
FreeingTask* task = new FreeingTask(heap_); V8::GetCurrentPlatform()->CallOnWorkerThread(
V8::GetCurrentPlatform()->CallOnWorkerThread(task); base::make_unique<FreeingTask>(heap_));
} else { } else {
// Fallback for when concurrency is disabled/restricted. // Fallback for when concurrency is disabled/restricted.
FreeAllocations(); FreeAllocations();

View File

@ -8,6 +8,7 @@
#include <unordered_map> #include <unordered_map>
#include "include/v8config.h" #include "include/v8config.h"
#include "src/base/template-utils.h"
#include "src/heap/gc-tracer.h" #include "src/heap/gc-tracer.h"
#include "src/heap/heap-inl.h" #include "src/heap/heap-inl.h"
#include "src/heap/heap.h" #include "src/heap/heap.h"
@ -612,9 +613,10 @@ void ConcurrentMarking::ScheduleTasks() {
task_state_[i].preemption_request.SetValue(false); task_state_[i].preemption_request.SetValue(false);
is_pending_[i] = true; is_pending_[i] = true;
++pending_task_count_; ++pending_task_count_;
Task* task = new Task(heap_->isolate(), this, &task_state_[i], i); auto task =
base::make_unique<Task>(heap_->isolate(), this, &task_state_[i], i);
cancelable_id_[i] = task->id(); cancelable_id_[i] = task->id();
V8::GetCurrentPlatform()->CallOnWorkerThread(task); V8::GetCurrentPlatform()->CallOnWorkerThread(std::move(task));
} }
} }
DCHECK_EQ(task_count_, pending_task_count_); DCHECK_EQ(task_count_, pending_task_count_);

View File

@ -90,10 +90,11 @@ void ItemParallelJob::Run(std::shared_ptr<Counters> async_counters) {
: 0; : 0;
CancelableTaskManager::Id* task_ids = CancelableTaskManager::Id* task_ids =
new CancelableTaskManager::Id[num_tasks]; new CancelableTaskManager::Id[num_tasks];
Task* main_task = nullptr; std::unique_ptr<Task> main_task;
for (size_t i = 0, start_index = 0; i < num_tasks; for (size_t i = 0, start_index = 0; i < num_tasks;
i++, start_index += items_per_task + (i < items_remainder ? 1 : 0)) { i++, start_index += items_per_task + (i < items_remainder ? 1 : 0)) {
Task* task = tasks_[i]; auto task = std::move(tasks_[i]);
DCHECK(task);
// By definition there are less |items_remainder| to distribute then // By definition there are less |items_remainder| to distribute then
// there are tasks processing items so this cannot overflow while we are // there are tasks processing items so this cannot overflow while we are
@ -105,15 +106,15 @@ void ItemParallelJob::Run(std::shared_ptr<Counters> async_counters) {
: base::Optional<AsyncTimedHistogram>()); : base::Optional<AsyncTimedHistogram>());
task_ids[i] = task->id(); task_ids[i] = task->id();
if (i > 0) { if (i > 0) {
V8::GetCurrentPlatform()->CallBlockingTaskOnWorkerThread(task); V8::GetCurrentPlatform()->CallBlockingTaskOnWorkerThread(std::move(task));
} else { } else {
main_task = task; main_task = std::move(task);
} }
} }
// Contribute on main thread. // Contribute on main thread.
DCHECK(main_task);
main_task->Run(); main_task->Run();
delete main_task;
// Wait for background tasks. // Wait for background tasks.
for (size_t i = 0; i < num_tasks; i++) { for (size_t i = 0; i < num_tasks; i++) {

View File

@ -126,7 +126,7 @@ class V8_EXPORT_PRIVATE ItemParallelJob {
~ItemParallelJob(); ~ItemParallelJob();
// Adds a task to the job. Transfers ownership to the job. // Adds a task to the job. Transfers ownership to the job.
void AddTask(Task* task) { tasks_.push_back(task); } void AddTask(Task* task) { tasks_.push_back(std::unique_ptr<Task>(task)); }
// Adds an item to the job. Transfers ownership to the job. // Adds an item to the job. Transfers ownership to the job.
void AddItem(Item* item) { items_.push_back(item); } void AddItem(Item* item) { items_.push_back(item); }
@ -140,7 +140,7 @@ class V8_EXPORT_PRIVATE ItemParallelJob {
private: private:
std::vector<Item*> items_; std::vector<Item*> items_;
std::vector<Task*> tasks_; std::vector<std::unique_ptr<Task>> tasks_;
CancelableTaskManager* cancelable_task_manager_; CancelableTaskManager* cancelable_task_manager_;
base::Semaphore* pending_tasks_; base::Semaphore* pending_tasks_;
DISALLOW_COPY_AND_ASSIGN(ItemParallelJob); DISALLOW_COPY_AND_ASSIGN(ItemParallelJob);

View File

@ -9,6 +9,7 @@
#include "src/base/bits.h" #include "src/base/bits.h"
#include "src/base/macros.h" #include "src/base/macros.h"
#include "src/base/platform/semaphore.h" #include "src/base/platform/semaphore.h"
#include "src/base/template-utils.h"
#include "src/counters.h" #include "src/counters.h"
#include "src/heap/array-buffer-tracker.h" #include "src/heap/array-buffer-tracker.h"
#include "src/heap/concurrent-marking.h" #include "src/heap/concurrent-marking.h"
@ -349,7 +350,7 @@ void MemoryAllocator::Unmapper::FreeQueuedChunks() {
} }
return; return;
} }
UnmapFreeMemoryTask* task = new UnmapFreeMemoryTask(heap_->isolate(), this); auto task = base::make_unique<UnmapFreeMemoryTask>(heap_->isolate(), this);
if (FLAG_trace_unmapper) { if (FLAG_trace_unmapper) {
PrintIsolate(heap_->isolate(), PrintIsolate(heap_->isolate(),
"Unmapper::FreeQueuedChunks: new task id=%" PRIu64 "\n", "Unmapper::FreeQueuedChunks: new task id=%" PRIu64 "\n",
@ -360,7 +361,7 @@ void MemoryAllocator::Unmapper::FreeQueuedChunks() {
DCHECK_GE(active_unmapping_tasks_.Value(), 0); DCHECK_GE(active_unmapping_tasks_.Value(), 0);
active_unmapping_tasks_.Increment(1); active_unmapping_tasks_.Increment(1);
task_ids_[pending_unmapping_tasks_++] = task->id(); task_ids_[pending_unmapping_tasks_++] = task->id();
V8::GetCurrentPlatform()->CallOnWorkerThread(task); V8::GetCurrentPlatform()->CallOnWorkerThread(std::move(task));
} else { } else {
PerformFreeMemoryOnQueuedChunks<FreeMode::kUncommitPooled>(); PerformFreeMemoryOnQueuedChunks<FreeMode::kUncommitPooled>();
} }

View File

@ -7,6 +7,7 @@
#include <algorithm> #include <algorithm>
#include "src/base/macros.h" #include "src/base/macros.h"
#include "src/base/template-utils.h"
#include "src/counters.h" #include "src/counters.h"
#include "src/heap/incremental-marking.h" #include "src/heap/incremental-marking.h"
#include "src/isolate.h" #include "src/isolate.h"
@ -94,8 +95,8 @@ void StoreBuffer::FlipStoreBuffers() {
if (!task_running_ && FLAG_concurrent_store_buffer) { if (!task_running_ && FLAG_concurrent_store_buffer) {
task_running_ = true; task_running_ = true;
Task* task = new Task(heap_->isolate(), this); V8::GetCurrentPlatform()->CallOnWorkerThread(
V8::GetCurrentPlatform()->CallOnWorkerThread(task); base::make_unique<Task>(heap_->isolate(), this));
} }
} }

View File

@ -4,6 +4,7 @@
#include "src/heap/sweeper.h" #include "src/heap/sweeper.h"
#include "src/base/template-utils.h"
#include "src/heap/array-buffer-tracker-inl.h" #include "src/heap/array-buffer-tracker-inl.h"
#include "src/heap/gc-tracer.h" #include "src/heap/gc-tracer.h"
#include "src/heap/mark-compact-inl.h" #include "src/heap/mark-compact-inl.h"
@ -154,12 +155,12 @@ void Sweeper::StartSweeperTasks() {
ForAllSweepingSpaces([this](AllocationSpace space) { ForAllSweepingSpaces([this](AllocationSpace space) {
DCHECK(IsValidSweepingSpace(space)); DCHECK(IsValidSweepingSpace(space));
num_sweeping_tasks_.Increment(1); num_sweeping_tasks_.Increment(1);
SweeperTask* task = new SweeperTask(heap_->isolate(), this, auto task = base::make_unique<SweeperTask>(
&pending_sweeper_tasks_semaphore_, heap_->isolate(), this, &pending_sweeper_tasks_semaphore_,
&num_sweeping_tasks_, space); &num_sweeping_tasks_, space);
DCHECK_LT(num_tasks_, kMaxSweeperTasks); DCHECK_LT(num_tasks_, kMaxSweeperTasks);
task_ids_[num_tasks_++] = task->id(); task_ids_[num_tasks_++] = task->id();
V8::GetCurrentPlatform()->CallOnWorkerThread(task); V8::GetCurrentPlatform()->CallOnWorkerThread(std::move(task));
}); });
ScheduleIncrementalSweepingTask(); ScheduleIncrementalSweepingTask();
} }
@ -551,11 +552,11 @@ void Sweeper::StartIterabilityTasks() {
DCHECK(!iterability_task_started_); DCHECK(!iterability_task_started_);
if (FLAG_concurrent_sweeping && !iterability_list_.empty()) { if (FLAG_concurrent_sweeping && !iterability_list_.empty()) {
IterabilityTask* task = new IterabilityTask(heap_->isolate(), this, auto task = base::make_unique<IterabilityTask>(
&iterability_task_semaphore_); heap_->isolate(), this, &iterability_task_semaphore_);
iterability_task_id_ = task->id(); iterability_task_id_ = task->id();
iterability_task_started_ = true; iterability_task_started_ = true;
V8::GetCurrentPlatform()->CallOnWorkerThread(task); V8::GetCurrentPlatform()->CallOnWorkerThread(std::move(task));
} }
} }

View File

@ -14,8 +14,8 @@
#include "src/base/platform/platform.h" #include "src/base/platform/platform.h"
#include "src/base/platform/time.h" #include "src/base/platform/time.h"
#include "src/base/sys-info.h" #include "src/base/sys-info.h"
#include "src/libplatform/default-background-task-runner.h"
#include "src/libplatform/default-foreground-task-runner.h" #include "src/libplatform/default-foreground-task-runner.h"
#include "src/libplatform/default-worker-threads-task-runner.h"
namespace v8 { namespace v8 {
namespace platform { namespace platform {
@ -96,7 +96,7 @@ DefaultPlatform::DefaultPlatform(
DefaultPlatform::~DefaultPlatform() { DefaultPlatform::~DefaultPlatform() {
base::LockGuard<base::Mutex> guard(&lock_); base::LockGuard<base::Mutex> guard(&lock_);
if (background_task_runner_) background_task_runner_->Terminate(); if (worker_threads_task_runner_) worker_threads_task_runner_->Terminate();
for (auto it : foreground_task_runner_map_) { for (auto it : foreground_task_runner_map_) {
it.second->Terminate(); it.second->Terminate();
} }
@ -114,9 +114,9 @@ void DefaultPlatform::SetThreadPoolSize(int thread_pool_size) {
void DefaultPlatform::EnsureBackgroundTaskRunnerInitialized() { void DefaultPlatform::EnsureBackgroundTaskRunnerInitialized() {
base::LockGuard<base::Mutex> guard(&lock_); base::LockGuard<base::Mutex> guard(&lock_);
if (!background_task_runner_) { if (!worker_threads_task_runner_) {
background_task_runner_ = worker_threads_task_runner_ =
std::make_shared<DefaultBackgroundTaskRunner>(thread_pool_size_); std::make_shared<DefaultWorkerThreadsTaskRunner>(thread_pool_size_);
} }
} }
@ -196,11 +196,11 @@ std::shared_ptr<TaskRunner> DefaultPlatform::GetForegroundTaskRunner(
std::shared_ptr<TaskRunner> DefaultPlatform::GetWorkerThreadsTaskRunner( std::shared_ptr<TaskRunner> DefaultPlatform::GetWorkerThreadsTaskRunner(
v8::Isolate*) { v8::Isolate*) {
EnsureBackgroundTaskRunnerInitialized(); EnsureBackgroundTaskRunnerInitialized();
return background_task_runner_; return worker_threads_task_runner_;
} }
void DefaultPlatform::CallOnWorkerThread(Task* task) { void DefaultPlatform::CallOnWorkerThread(std::unique_ptr<Task> task) {
GetWorkerThreadsTaskRunner(nullptr)->PostTask(std::unique_ptr<Task>(task)); GetWorkerThreadsTaskRunner(nullptr)->PostTask(std::move(task));
} }
void DefaultPlatform::CallOnForegroundThread(v8::Isolate* isolate, Task* task) { void DefaultPlatform::CallOnForegroundThread(v8::Isolate* isolate, Task* task) {

View File

@ -26,7 +26,7 @@ namespace platform {
class Thread; class Thread;
class WorkerThread; class WorkerThread;
class DefaultForegroundTaskRunner; class DefaultForegroundTaskRunner;
class DefaultBackgroundTaskRunner; class DefaultWorkerThreadsTaskRunner;
class DefaultPageAllocator; class DefaultPageAllocator;
class V8_PLATFORM_EXPORT DefaultPlatform : public NON_EXPORTED_BASE(Platform) { class V8_PLATFORM_EXPORT DefaultPlatform : public NON_EXPORTED_BASE(Platform) {
@ -60,7 +60,7 @@ class V8_PLATFORM_EXPORT DefaultPlatform : public NON_EXPORTED_BASE(Platform) {
v8::Isolate* isolate) override; v8::Isolate* isolate) override;
std::shared_ptr<TaskRunner> GetWorkerThreadsTaskRunner( std::shared_ptr<TaskRunner> GetWorkerThreadsTaskRunner(
v8::Isolate* isolate) override; v8::Isolate* isolate) override;
void CallOnWorkerThread(Task* task) override; void CallOnWorkerThread(std::unique_ptr<Task> task) override;
void CallOnForegroundThread(v8::Isolate* isolate, Task* task) override; void CallOnForegroundThread(v8::Isolate* isolate, Task* task) override;
void CallDelayedOnForegroundThread(Isolate* isolate, Task* task, void CallDelayedOnForegroundThread(Isolate* isolate, Task* task,
double delay_in_seconds) override; double delay_in_seconds) override;
@ -78,7 +78,7 @@ class V8_PLATFORM_EXPORT DefaultPlatform : public NON_EXPORTED_BASE(Platform) {
base::Mutex lock_; base::Mutex lock_;
int thread_pool_size_; int thread_pool_size_;
IdleTaskSupport idle_task_support_; IdleTaskSupport idle_task_support_;
std::shared_ptr<DefaultBackgroundTaskRunner> background_task_runner_; std::shared_ptr<DefaultWorkerThreadsTaskRunner> worker_threads_task_runner_;
std::map<v8::Isolate*, std::shared_ptr<DefaultForegroundTaskRunner>> std::map<v8::Isolate*, std::shared_ptr<DefaultForegroundTaskRunner>>
foreground_task_runner_map_; foreground_task_runner_map_;

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "src/libplatform/default-background-task-runner.h" #include "src/libplatform/default-worker-threads-task-runner.h"
#include "src/base/platform/mutex.h" #include "src/base/platform/mutex.h"
#include "src/libplatform/worker-thread.h" #include "src/libplatform/worker-thread.h"
@ -10,19 +10,19 @@
namespace v8 { namespace v8 {
namespace platform { namespace platform {
DefaultBackgroundTaskRunner::DefaultBackgroundTaskRunner( DefaultWorkerThreadsTaskRunner::DefaultWorkerThreadsTaskRunner(
uint32_t thread_pool_size) { uint32_t thread_pool_size) {
for (uint32_t i = 0; i < thread_pool_size; ++i) { for (uint32_t i = 0; i < thread_pool_size; ++i) {
thread_pool_.push_back(base::make_unique<WorkerThread>(&queue_)); thread_pool_.push_back(base::make_unique<WorkerThread>(&queue_));
} }
} }
DefaultBackgroundTaskRunner::~DefaultBackgroundTaskRunner() { DefaultWorkerThreadsTaskRunner::~DefaultWorkerThreadsTaskRunner() {
// This destructor is needed because we have unique_ptr to the WorkerThreads, // This destructor is needed because we have unique_ptr to the WorkerThreads,
// und the {WorkerThread} class is forward declared in the header file. // und the {WorkerThread} class is forward declared in the header file.
} }
void DefaultBackgroundTaskRunner::Terminate() { void DefaultWorkerThreadsTaskRunner::Terminate() {
base::LockGuard<base::Mutex> guard(&lock_); base::LockGuard<base::Mutex> guard(&lock_);
terminated_ = true; terminated_ = true;
queue_.Terminate(); queue_.Terminate();
@ -30,28 +30,29 @@ void DefaultBackgroundTaskRunner::Terminate() {
thread_pool_.clear(); thread_pool_.clear();
} }
void DefaultBackgroundTaskRunner::PostTask(std::unique_ptr<Task> task) { void DefaultWorkerThreadsTaskRunner::PostTask(std::unique_ptr<Task> task) {
base::LockGuard<base::Mutex> guard(&lock_); base::LockGuard<base::Mutex> guard(&lock_);
if (terminated_) return; if (terminated_) return;
queue_.Append(std::move(task)); queue_.Append(std::move(task));
} }
void DefaultBackgroundTaskRunner::PostDelayedTask(std::unique_ptr<Task> task, void DefaultWorkerThreadsTaskRunner::PostDelayedTask(std::unique_ptr<Task> task,
double delay_in_seconds) { double delay_in_seconds) {
base::LockGuard<base::Mutex> guard(&lock_); base::LockGuard<base::Mutex> guard(&lock_);
if (terminated_) return; if (terminated_) return;
// There is no use case for this function on a background thread at the // There is no use case for this function on a worker thread at the
// moment, but it is still part of the interface. // moment, but it is still part of the interface.
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
void DefaultBackgroundTaskRunner::PostIdleTask(std::unique_ptr<IdleTask> task) { void DefaultWorkerThreadsTaskRunner::PostIdleTask(
// There are no idle background tasks. std::unique_ptr<IdleTask> task) {
// There are no idle worker tasks.
UNREACHABLE(); UNREACHABLE();
} }
bool DefaultBackgroundTaskRunner::IdleTasksEnabled() { bool DefaultWorkerThreadsTaskRunner::IdleTasksEnabled() {
// There are no idle background tasks. // There are no idle worker tasks.
return false; return false;
} }

View File

@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef V8_LIBPLATFORM_DEFAULT_BACKGROUND_TASK_RUNNER_H_ #ifndef V8_LIBPLATFORM_DEFAULT_WORKER_THREADS_TASK_RUNNER_H_
#define V8_LIBPLATFORM_DEFAULT_BACKGROUND_TASK_RUNNER_H_ #define V8_LIBPLATFORM_DEFAULT_WORKER_THREADS_TASK_RUNNER_H_
#include "include/v8-platform.h" #include "include/v8-platform.h"
#include "src/libplatform/task-queue.h" #include "src/libplatform/task-queue.h"
@ -14,12 +14,12 @@ namespace platform {
class Thread; class Thread;
class WorkerThread; class WorkerThread;
class V8_PLATFORM_EXPORT DefaultBackgroundTaskRunner class V8_PLATFORM_EXPORT DefaultWorkerThreadsTaskRunner
: public NON_EXPORTED_BASE(TaskRunner) { : public NON_EXPORTED_BASE(TaskRunner) {
public: public:
DefaultBackgroundTaskRunner(uint32_t thread_pool_size); DefaultWorkerThreadsTaskRunner(uint32_t thread_pool_size);
~DefaultBackgroundTaskRunner(); ~DefaultWorkerThreadsTaskRunner();
void Terminate(); void Terminate();
@ -42,4 +42,4 @@ class V8_PLATFORM_EXPORT DefaultBackgroundTaskRunner
} // namespace platform } // namespace platform
} // namespace v8 } // namespace v8
#endif // V8_LIBPLATFORM_DEFAULT_BACKGROUND_TASK_RUNNER_H_ #endif // V8_LIBPLATFORM_DEFAULT_WORKER_THREADS_TASK_RUNNER_H_

View File

@ -690,8 +690,8 @@ class TestPlatform : public v8::Platform {
return old_platform_->GetWorkerThreadsTaskRunner(isolate); return old_platform_->GetWorkerThreadsTaskRunner(isolate);
} }
void CallOnWorkerThread(v8::Task* task) override { void CallOnWorkerThread(std::unique_ptr<v8::Task> task) override {
old_platform_->CallOnWorkerThread(task); old_platform_->CallOnWorkerThread(std::move(task));
} }
void CallOnForegroundThread(v8::Isolate* isolate, v8::Task* task) override { void CallOnForegroundThread(v8::Isolate* isolate, v8::Task* task) override {

View File

@ -40,8 +40,8 @@ class MockPlatform : public TestPlatform {
virtual ~MockPlatform() { virtual ~MockPlatform() {
delete task_; delete task_;
i::V8::SetPlatformForTesting(old_platform_); i::V8::SetPlatformForTesting(old_platform_);
for (Task* task : worker_tasks_) { for (auto& task : worker_tasks_) {
old_platform_->CallOnWorkerThread(task); old_platform_->CallOnWorkerThread(std::move(task));
} }
worker_tasks_.clear(); worker_tasks_.clear();
} }
@ -50,8 +50,8 @@ class MockPlatform : public TestPlatform {
task_ = task; task_ = task;
} }
void CallOnWorkerThread(Task* task) override { void CallOnWorkerThread(std::unique_ptr<Task> task) override {
worker_tasks_.push_back(task); worker_tasks_.push_back(std::move(task));
} }
bool IdleTasksEnabled(v8::Isolate* isolate) override { return false; } bool IdleTasksEnabled(v8::Isolate* isolate) override { return false; }
@ -67,7 +67,7 @@ class MockPlatform : public TestPlatform {
private: private:
Task* task_; Task* task_;
std::vector<Task*> worker_tasks_; std::vector<std::unique_ptr<Task>> worker_tasks_;
v8::Platform* old_platform_; v8::Platform* old_platform_;
}; };

View File

@ -44,8 +44,8 @@ class MockPlatform final : public TestPlatform {
task_runner_->PostTask(std::unique_ptr<Task>(task)); task_runner_->PostTask(std::unique_ptr<Task>(task));
} }
void CallOnWorkerThread(v8::Task* task) override { void CallOnWorkerThread(std::unique_ptr<v8::Task> task) override {
task_runner_->PostTask(std::unique_ptr<Task>(task)); task_runner_->PostTask(std::move(task));
} }
bool IdleTasksEnabled(v8::Isolate* isolate) override { return false; } bool IdleTasksEnabled(v8::Isolate* isolate) override { return false; }

View File

@ -9,6 +9,7 @@
#include "include/v8.h" #include "include/v8.h"
#include "src/base/macros.h" #include "src/base/macros.h"
#include "src/base/platform/semaphore.h" #include "src/base/platform/semaphore.h"
#include "src/base/template-utils.h"
#include "src/execution.h" #include "src/execution.h"
#include "src/isolate.h" #include "src/isolate.h"
#include "src/v8.h" #include "src/v8.h"
@ -61,7 +62,7 @@ TEST_F(IsolateTest, MemoryPressureNotificationBackground) {
base::Semaphore semaphore(0); base::Semaphore semaphore(0);
internal::V8::GetCurrentPlatform()->CallOnWorkerThread( internal::V8::GetCurrentPlatform()->CallOnWorkerThread(
new MemoryPressureTask(isolate(), &semaphore)); base::make_unique<MemoryPressureTask>(isolate(), &semaphore));
semaphore.Wait(); semaphore.Wait();

View File

@ -10,6 +10,7 @@
#include "src/api.h" #include "src/api.h"
#include "src/ast/ast-value-factory.h" #include "src/ast/ast-value-factory.h"
#include "src/base/platform/semaphore.h" #include "src/base/platform/semaphore.h"
#include "src/base/template-utils.h"
#include "src/compiler-dispatcher/compiler-dispatcher-job.h" #include "src/compiler-dispatcher/compiler-dispatcher-job.h"
#include "src/compiler-dispatcher/compiler-dispatcher-tracer.h" #include "src/compiler-dispatcher/compiler-dispatcher-tracer.h"
#include "src/compiler-dispatcher/unoptimized-compile-job.h" #include "src/compiler-dispatcher/unoptimized-compile-job.h"
@ -93,7 +94,7 @@ class MockPlatform : public v8::Platform {
~MockPlatform() override { ~MockPlatform() override {
base::LockGuard<base::Mutex> lock(&mutex_); base::LockGuard<base::Mutex> lock(&mutex_);
EXPECT_TRUE(foreground_tasks_.empty()); EXPECT_TRUE(foreground_tasks_.empty());
EXPECT_TRUE(background_tasks_.empty()); EXPECT_TRUE(worker_tasks_.empty());
EXPECT_TRUE(idle_task_ == nullptr); EXPECT_TRUE(idle_task_ == nullptr);
} }
@ -111,14 +112,14 @@ class MockPlatform : public v8::Platform {
return std::make_shared<MockTaskRunner>(this, is_foreground_task_runner); return std::make_shared<MockTaskRunner>(this, is_foreground_task_runner);
} }
void CallOnWorkerThread(Task* task) override { void CallOnWorkerThread(std::unique_ptr<Task> task) override {
base::LockGuard<base::Mutex> lock(&mutex_); base::LockGuard<base::Mutex> lock(&mutex_);
background_tasks_.push_back(task); worker_tasks_.push_back(std::move(task));
} }
void CallOnForegroundThread(v8::Isolate* isolate, Task* task) override { void CallOnForegroundThread(v8::Isolate* isolate, Task* task) override {
base::LockGuard<base::Mutex> lock(&mutex_); base::LockGuard<base::Mutex> lock(&mutex_);
foreground_tasks_.push_back(task); foreground_tasks_.push_back(std::unique_ptr<Task>(task));
} }
void CallDelayedOnForegroundThread(v8::Isolate* isolate, Task* task, void CallDelayedOnForegroundThread(v8::Isolate* isolate, Task* task,
@ -166,9 +167,9 @@ class MockPlatform : public v8::Platform {
return idle_task_; return idle_task_;
} }
bool BackgroundTasksPending() { bool WorkerTasksPending() {
base::LockGuard<base::Mutex> lock(&mutex_); base::LockGuard<base::Mutex> lock(&mutex_);
return !background_tasks_.empty(); return !worker_tasks_.empty();
} }
bool ForegroundTasksPending() { bool ForegroundTasksPending() {
@ -176,57 +177,54 @@ class MockPlatform : public v8::Platform {
return !foreground_tasks_.empty(); return !foreground_tasks_.empty();
} }
void RunBackgroundTasksAndBlock(Platform* platform) { void RunWorkerTasksAndBlock(Platform* platform) {
std::vector<Task*> tasks; std::vector<std::unique_ptr<Task>> tasks;
{ {
base::LockGuard<base::Mutex> lock(&mutex_); base::LockGuard<base::Mutex> lock(&mutex_);
tasks.swap(background_tasks_); tasks.swap(worker_tasks_);
} }
platform->CallOnWorkerThread(new TaskWrapper(this, tasks, true)); platform->CallOnWorkerThread(
base::make_unique<TaskWrapper>(this, std::move(tasks), true));
sem_.Wait(); sem_.Wait();
} }
void RunBackgroundTasks(Platform* platform) { void RunWorkerTasks(Platform* platform) {
std::vector<Task*> tasks; std::vector<std::unique_ptr<Task>> tasks;
{ {
base::LockGuard<base::Mutex> lock(&mutex_); base::LockGuard<base::Mutex> lock(&mutex_);
tasks.swap(background_tasks_); tasks.swap(worker_tasks_);
} }
platform->CallOnWorkerThread(new TaskWrapper(this, tasks, false)); platform->CallOnWorkerThread(
base::make_unique<TaskWrapper>(this, std::move(tasks), false));
} }
void RunForegroundTasks() { void RunForegroundTasks() {
std::vector<Task*> tasks; std::vector<std::unique_ptr<Task>> tasks;
{ {
base::LockGuard<base::Mutex> lock(&mutex_); base::LockGuard<base::Mutex> lock(&mutex_);
tasks.swap(foreground_tasks_); tasks.swap(foreground_tasks_);
} }
for (auto& task : tasks) { for (auto& task : tasks) {
task->Run(); task->Run();
delete task; // Reset |task| before running the next one.
task.reset();
} }
} }
void ClearBackgroundTasks() { void ClearWorkerTasks() {
std::vector<Task*> tasks; std::vector<std::unique_ptr<Task>> tasks;
{ {
base::LockGuard<base::Mutex> lock(&mutex_); base::LockGuard<base::Mutex> lock(&mutex_);
tasks.swap(background_tasks_); tasks.swap(worker_tasks_);
}
for (auto& task : tasks) {
delete task;
} }
} }
void ClearForegroundTasks() { void ClearForegroundTasks() {
std::vector<Task*> tasks; std::vector<std::unique_ptr<Task>> tasks;
{ {
base::LockGuard<base::Mutex> lock(&mutex_); base::LockGuard<base::Mutex> lock(&mutex_);
tasks.swap(foreground_tasks_); tasks.swap(foreground_tasks_);
} }
for (auto& task : tasks) {
delete task;
}
} }
void ClearIdleTask() { void ClearIdleTask() {
@ -239,22 +237,23 @@ class MockPlatform : public v8::Platform {
private: private:
class TaskWrapper : public Task { class TaskWrapper : public Task {
public: public:
TaskWrapper(MockPlatform* platform, const std::vector<Task*>& tasks, TaskWrapper(MockPlatform* platform,
bool signal) std::vector<std::unique_ptr<Task>> tasks, bool signal)
: platform_(platform), tasks_(tasks), signal_(signal) {} : platform_(platform), tasks_(std::move(tasks)), signal_(signal) {}
~TaskWrapper() = default; ~TaskWrapper() = default;
void Run() override { void Run() override {
for (auto& task : tasks_) { for (auto& task : tasks_) {
task->Run(); task->Run();
delete task; // Reset |task| before running the next one.
task.reset();
} }
if (signal_) platform_->sem_.Signal(); if (signal_) platform_->sem_.Signal();
} }
private: private:
MockPlatform* platform_; MockPlatform* platform_;
std::vector<Task*> tasks_; std::vector<std::unique_ptr<Task>> tasks_;
bool signal_; bool signal_;
DISALLOW_COPY_AND_ASSIGN(TaskWrapper); DISALLOW_COPY_AND_ASSIGN(TaskWrapper);
@ -269,9 +268,9 @@ class MockPlatform : public v8::Platform {
void PostTask(std::unique_ptr<v8::Task> task) override { void PostTask(std::unique_ptr<v8::Task> task) override {
base::LockGuard<base::Mutex> lock(&platform_->mutex_); base::LockGuard<base::Mutex> lock(&platform_->mutex_);
if (is_foreground_task_runner_) { if (is_foreground_task_runner_) {
platform_->foreground_tasks_.push_back(task.release()); platform_->foreground_tasks_.push_back(std::move(task));
} else { } else {
platform_->background_tasks_.push_back(task.release()); platform_->worker_tasks_.push_back(std::move(task));
} }
} }
@ -304,8 +303,8 @@ class MockPlatform : public v8::Platform {
base::Mutex mutex_; base::Mutex mutex_;
IdleTask* idle_task_; IdleTask* idle_task_;
std::vector<Task*> background_tasks_; std::vector<std::unique_ptr<Task>> worker_tasks_;
std::vector<Task*> foreground_tasks_; std::vector<std::unique_ptr<Task>> foreground_tasks_;
base::Semaphore sem_; base::Semaphore sem_;
@ -383,7 +382,7 @@ TEST_F(CompilerDispatcherTest, FinishAllNow) {
ASSERT_TRUE(shared[i]->is_compiled()); ASSERT_TRUE(shared[i]->is_compiled());
} }
platform.ClearIdleTask(); platform.ClearIdleTask();
platform.ClearBackgroundTasks(); platform.ClearWorkerTasks();
} }
TEST_F(CompilerDispatcherTest, IdleTask) { TEST_F(CompilerDispatcherTest, IdleTask) {
@ -497,12 +496,12 @@ TEST_F(CompilerDispatcherTest, CompileOnBackgroundThread) {
ASSERT_TRUE(dispatcher.IsEnqueued(shared)); ASSERT_TRUE(dispatcher.IsEnqueued(shared));
ASSERT_FALSE(shared->is_compiled()); ASSERT_FALSE(shared->is_compiled());
ASSERT_FALSE(platform.IdleTaskPending()); ASSERT_FALSE(platform.IdleTaskPending());
ASSERT_TRUE(platform.BackgroundTasksPending()); ASSERT_TRUE(platform.WorkerTasksPending());
platform.RunBackgroundTasksAndBlock(V8::GetCurrentPlatform()); platform.RunWorkerTasksAndBlock(V8::GetCurrentPlatform());
ASSERT_TRUE(platform.IdleTaskPending()); ASSERT_TRUE(platform.IdleTaskPending());
ASSERT_FALSE(platform.BackgroundTasksPending()); ASSERT_FALSE(platform.WorkerTasksPending());
ASSERT_EQ(UnoptimizedCompileJob::Status::kCompiled, ASSERT_EQ(UnoptimizedCompileJob::Status::kCompiled,
dispatcher.jobs_.begin()->second->status()); dispatcher.jobs_.begin()->second->status());
@ -514,7 +513,7 @@ TEST_F(CompilerDispatcherTest, CompileOnBackgroundThread) {
ASSERT_FALSE(platform.IdleTaskPending()); ASSERT_FALSE(platform.IdleTaskPending());
} }
TEST_F(CompilerDispatcherTest, FinishNowWithBackgroundTask) { TEST_F(CompilerDispatcherTest, FinishNowWithWorkerTask) {
MockPlatform platform; MockPlatform platform;
CompilerDispatcher dispatcher(i_isolate(), &platform, FLAG_stack_size); CompilerDispatcher dispatcher(i_isolate(), &platform, FLAG_stack_size);
@ -540,17 +539,17 @@ TEST_F(CompilerDispatcherTest, FinishNowWithBackgroundTask) {
ASSERT_TRUE(dispatcher.IsEnqueued(shared)); ASSERT_TRUE(dispatcher.IsEnqueued(shared));
ASSERT_FALSE(shared->is_compiled()); ASSERT_FALSE(shared->is_compiled());
ASSERT_FALSE(platform.IdleTaskPending()); ASSERT_FALSE(platform.IdleTaskPending());
ASSERT_TRUE(platform.BackgroundTasksPending()); ASSERT_TRUE(platform.WorkerTasksPending());
// This does not block, but races with the FinishNow() call below. // This does not block, but races with the FinishNow() call below.
platform.RunBackgroundTasks(V8::GetCurrentPlatform()); platform.RunWorkerTasks(V8::GetCurrentPlatform());
ASSERT_TRUE(dispatcher.FinishNow(shared)); ASSERT_TRUE(dispatcher.FinishNow(shared));
// Finishing removes the SFI from the queue. // Finishing removes the SFI from the queue.
ASSERT_FALSE(dispatcher.IsEnqueued(shared)); ASSERT_FALSE(dispatcher.IsEnqueued(shared));
ASSERT_TRUE(shared->is_compiled()); ASSERT_TRUE(shared->is_compiled());
if (platform.IdleTaskPending()) platform.ClearIdleTask(); if (platform.IdleTaskPending()) platform.ClearIdleTask();
ASSERT_FALSE(platform.BackgroundTasksPending()); ASSERT_FALSE(platform.WorkerTasksPending());
} }
TEST_F(CompilerDispatcherTest, IdleTaskMultipleJobs) { TEST_F(CompilerDispatcherTest, IdleTaskMultipleJobs) {
@ -608,7 +607,7 @@ TEST_F(CompilerDispatcherTest, FinishNowException) {
platform.ClearIdleTask(); platform.ClearIdleTask();
} }
TEST_F(CompilerDispatcherTest, AsyncAbortAllPendingBackgroundTask) { TEST_F(CompilerDispatcherTest, AsyncAbortAllPendingWorkerTask) {
MockPlatform platform; MockPlatform platform;
CompilerDispatcher dispatcher(i_isolate(), &platform, FLAG_stack_size); CompilerDispatcher dispatcher(i_isolate(), &platform, FLAG_stack_size);
@ -634,7 +633,7 @@ TEST_F(CompilerDispatcherTest, AsyncAbortAllPendingBackgroundTask) {
ASSERT_TRUE(dispatcher.IsEnqueued(shared)); ASSERT_TRUE(dispatcher.IsEnqueued(shared));
ASSERT_FALSE(shared->is_compiled()); ASSERT_FALSE(shared->is_compiled());
ASSERT_FALSE(platform.IdleTaskPending()); ASSERT_FALSE(platform.IdleTaskPending());
ASSERT_TRUE(platform.BackgroundTasksPending()); ASSERT_TRUE(platform.WorkerTasksPending());
// The background task hasn't yet started, so we can just cancel it. // The background task hasn't yet started, so we can just cancel it.
dispatcher.AbortAll(BlockingBehavior::kDontBlock); dispatcher.AbortAll(BlockingBehavior::kDontBlock);
@ -643,14 +642,14 @@ TEST_F(CompilerDispatcherTest, AsyncAbortAllPendingBackgroundTask) {
ASSERT_FALSE(dispatcher.IsEnqueued(shared)); ASSERT_FALSE(dispatcher.IsEnqueued(shared));
ASSERT_FALSE(shared->is_compiled()); ASSERT_FALSE(shared->is_compiled());
platform.RunBackgroundTasksAndBlock(V8::GetCurrentPlatform()); platform.RunWorkerTasksAndBlock(V8::GetCurrentPlatform());
if (platform.IdleTaskPending()) platform.ClearIdleTask(); if (platform.IdleTaskPending()) platform.ClearIdleTask();
ASSERT_FALSE(platform.BackgroundTasksPending()); ASSERT_FALSE(platform.WorkerTasksPending());
ASSERT_FALSE(platform.ForegroundTasksPending()); ASSERT_FALSE(platform.ForegroundTasksPending());
} }
TEST_F(CompilerDispatcherTest, AsyncAbortAllRunningBackgroundTask) { TEST_F(CompilerDispatcherTest, AsyncAbortAllRunningWorkerTask) {
MockPlatform platform; MockPlatform platform;
CompilerDispatcher dispatcher(i_isolate(), &platform, FLAG_stack_size); CompilerDispatcher dispatcher(i_isolate(), &platform, FLAG_stack_size);
@ -680,11 +679,11 @@ TEST_F(CompilerDispatcherTest, AsyncAbortAllRunningBackgroundTask) {
ASSERT_TRUE(dispatcher.IsEnqueued(shared1)); ASSERT_TRUE(dispatcher.IsEnqueued(shared1));
ASSERT_FALSE(shared1->is_compiled()); ASSERT_FALSE(shared1->is_compiled());
ASSERT_FALSE(platform.IdleTaskPending()); ASSERT_FALSE(platform.IdleTaskPending());
ASSERT_TRUE(platform.BackgroundTasksPending()); ASSERT_TRUE(platform.WorkerTasksPending());
// Kick off background tasks and freeze them. // Kick off background tasks and freeze them.
dispatcher.block_for_testing_.SetValue(true); dispatcher.block_for_testing_.SetValue(true);
platform.RunBackgroundTasks(V8::GetCurrentPlatform()); platform.RunWorkerTasks(V8::GetCurrentPlatform());
// Busy loop until the background task started running. // Busy loop until the background task started running.
while (dispatcher.block_for_testing_.Value()) { while (dispatcher.block_for_testing_.Value()) {
@ -719,13 +718,13 @@ TEST_F(CompilerDispatcherTest, AsyncAbortAllRunningBackgroundTask) {
ASSERT_TRUE(platform.IdleTaskPending()); ASSERT_TRUE(platform.IdleTaskPending());
platform.RunIdleTask(5.0, 1.0); platform.RunIdleTask(5.0, 1.0);
ASSERT_FALSE(platform.BackgroundTasksPending()); ASSERT_FALSE(platform.WorkerTasksPending());
ASSERT_FALSE(platform.ForegroundTasksPending()); ASSERT_FALSE(platform.ForegroundTasksPending());
// Now it's possible to enqueue new functions again. // Now it's possible to enqueue new functions again.
ASSERT_TRUE(dispatcher.Enqueue(shared2)); ASSERT_TRUE(dispatcher.Enqueue(shared2));
ASSERT_TRUE(platform.IdleTaskPending()); ASSERT_TRUE(platform.IdleTaskPending());
ASSERT_FALSE(platform.BackgroundTasksPending()); ASSERT_FALSE(platform.WorkerTasksPending());
ASSERT_FALSE(platform.ForegroundTasksPending()); ASSERT_FALSE(platform.ForegroundTasksPending());
platform.ClearIdleTask(); platform.ClearIdleTask();
} }
@ -756,11 +755,11 @@ TEST_F(CompilerDispatcherTest, FinishNowDuringAbortAll) {
ASSERT_TRUE(dispatcher.IsEnqueued(shared)); ASSERT_TRUE(dispatcher.IsEnqueued(shared));
ASSERT_FALSE(shared->is_compiled()); ASSERT_FALSE(shared->is_compiled());
ASSERT_FALSE(platform.IdleTaskPending()); ASSERT_FALSE(platform.IdleTaskPending());
ASSERT_TRUE(platform.BackgroundTasksPending()); ASSERT_TRUE(platform.WorkerTasksPending());
// Kick off background tasks and freeze them. // Kick off background tasks and freeze them.
dispatcher.block_for_testing_.SetValue(true); dispatcher.block_for_testing_.SetValue(true);
platform.RunBackgroundTasks(V8::GetCurrentPlatform()); platform.RunWorkerTasks(V8::GetCurrentPlatform());
// Busy loop until the background task started running. // Busy loop until the background task started running.
while (dispatcher.block_for_testing_.Value()) { while (dispatcher.block_for_testing_.Value()) {
@ -789,14 +788,14 @@ TEST_F(CompilerDispatcherTest, FinishNowDuringAbortAll) {
// Busy wait for the background task to finish. // Busy wait for the background task to finish.
for (;;) { for (;;) {
base::LockGuard<base::Mutex> lock(&dispatcher.mutex_); base::LockGuard<base::Mutex> lock(&dispatcher.mutex_);
if (dispatcher.num_background_tasks_ == 0) { if (dispatcher.num_worker_tasks_ == 0) {
break; break;
} }
} }
ASSERT_TRUE(platform.ForegroundTasksPending()); ASSERT_TRUE(platform.ForegroundTasksPending());
ASSERT_TRUE(platform.IdleTaskPending()); ASSERT_TRUE(platform.IdleTaskPending());
ASSERT_FALSE(platform.BackgroundTasksPending()); ASSERT_FALSE(platform.WorkerTasksPending());
platform.RunForegroundTasks(); platform.RunForegroundTasks();
{ {
@ -866,7 +865,8 @@ TEST_F(CompilerDispatcherTest, MemoryPressureFromBackground) {
ASSERT_TRUE(dispatcher.Enqueue(shared)); ASSERT_TRUE(dispatcher.Enqueue(shared));
base::Semaphore sem(0); base::Semaphore sem(0);
V8::GetCurrentPlatform()->CallOnWorkerThread( V8::GetCurrentPlatform()->CallOnWorkerThread(
new PressureNotificationTask(i_isolate(), &dispatcher, &sem)); base::make_unique<PressureNotificationTask>(i_isolate(), &dispatcher,
&sem));
sem.Wait(); sem.Wait();
@ -901,7 +901,7 @@ TEST_F(CompilerDispatcherTest, EnqueueJob) {
ASSERT_TRUE(platform.IdleTaskPending()); ASSERT_TRUE(platform.IdleTaskPending());
platform.ClearIdleTask(); platform.ClearIdleTask();
ASSERT_FALSE(platform.BackgroundTasksPending()); ASSERT_FALSE(platform.WorkerTasksPending());
} }
TEST_F(CompilerDispatcherTest, EnqueueAndStep) { TEST_F(CompilerDispatcherTest, EnqueueAndStep) {
@ -921,8 +921,8 @@ TEST_F(CompilerDispatcherTest, EnqueueAndStep) {
ASSERT_TRUE(platform.IdleTaskPending()); ASSERT_TRUE(platform.IdleTaskPending());
platform.ClearIdleTask(); platform.ClearIdleTask();
ASSERT_TRUE(platform.BackgroundTasksPending()); ASSERT_TRUE(platform.WorkerTasksPending());
platform.ClearBackgroundTasks(); platform.ClearWorkerTasks();
} }
TEST_F(CompilerDispatcherTest, CompileLazyFinishesDispatcherJob) { TEST_F(CompilerDispatcherTest, CompileLazyFinishesDispatcherJob) {
@ -991,9 +991,9 @@ TEST_F(CompilerDispatcherTest, EnqueueAndStepTwice) {
dispatcher.jobs_.begin()->second->status()); dispatcher.jobs_.begin()->second->status());
ASSERT_TRUE(platform.IdleTaskPending()); ASSERT_TRUE(platform.IdleTaskPending());
ASSERT_TRUE(platform.BackgroundTasksPending()); ASSERT_TRUE(platform.WorkerTasksPending());
platform.ClearIdleTask(); platform.ClearIdleTask();
platform.ClearBackgroundTasks(); platform.ClearWorkerTasks();
} }
TEST_F(CompilerDispatcherTest, CompileMultipleOnBackgroundThread) { TEST_F(CompilerDispatcherTest, CompileMultipleOnBackgroundThread) {
@ -1033,12 +1033,12 @@ TEST_F(CompilerDispatcherTest, CompileMultipleOnBackgroundThread) {
ASSERT_FALSE(shared1->is_compiled()); ASSERT_FALSE(shared1->is_compiled());
ASSERT_FALSE(shared2->is_compiled()); ASSERT_FALSE(shared2->is_compiled());
ASSERT_FALSE(platform.IdleTaskPending()); ASSERT_FALSE(platform.IdleTaskPending());
ASSERT_TRUE(platform.BackgroundTasksPending()); ASSERT_TRUE(platform.WorkerTasksPending());
platform.RunBackgroundTasksAndBlock(V8::GetCurrentPlatform()); platform.RunWorkerTasksAndBlock(V8::GetCurrentPlatform());
ASSERT_TRUE(platform.IdleTaskPending()); ASSERT_TRUE(platform.IdleTaskPending());
ASSERT_FALSE(platform.BackgroundTasksPending()); ASSERT_FALSE(platform.WorkerTasksPending());
ASSERT_EQ(dispatcher.jobs_.size(), 2u); ASSERT_EQ(dispatcher.jobs_.size(), 2u);
ASSERT_EQ(UnoptimizedCompileJob::Status::kCompiled, ASSERT_EQ(UnoptimizedCompileJob::Status::kCompiled,
dispatcher.jobs_.begin()->second->status()); dispatcher.jobs_.begin()->second->status());

View File

@ -9,6 +9,7 @@
#include "src/ast/ast.h" #include "src/ast/ast.h"
#include "src/ast/scopes.h" #include "src/ast/scopes.h"
#include "src/base/platform/semaphore.h" #include "src/base/platform/semaphore.h"
#include "src/base/template-utils.h"
#include "src/compiler-dispatcher/compiler-dispatcher-job.h" #include "src/compiler-dispatcher/compiler-dispatcher-job.h"
#include "src/compiler-dispatcher/compiler-dispatcher-tracer.h" #include "src/compiler-dispatcher/compiler-dispatcher-tracer.h"
#include "src/compiler-dispatcher/unoptimized-compile-job.h" #include "src/compiler-dispatcher/unoptimized-compile-job.h"
@ -226,9 +227,9 @@ TEST_F(UnoptimizedCompileJobTest, CompileOnBackgroundThread) {
ASSERT_FALSE(job->IsFailed()); ASSERT_FALSE(job->IsFailed());
base::Semaphore semaphore(0); base::Semaphore semaphore(0);
CompileTask* background_task = new CompileTask(job.get(), &semaphore); auto background_task = base::make_unique<CompileTask>(job.get(), &semaphore);
ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kPrepared, job); ASSERT_JOB_STATUS(CompilerDispatcherJob::Status::kPrepared, job);
V8::GetCurrentPlatform()->CallOnWorkerThread(background_task); V8::GetCurrentPlatform()->CallOnWorkerThread(std::move(background_task));
semaphore.Wait(); semaphore.Wait();
job->FinalizeOnMainThread(isolate()); job->FinalizeOnMainThread(isolate());
ASSERT_FALSE(job->IsFailed()); ASSERT_FALSE(job->IsFailed());