[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:
parent
7e78e45b90
commit
1983f3055d
4
BUILD.gn
4
BUILD.gn
@ -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",
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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_;
|
||||||
|
@ -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_--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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();
|
||||||
|
@ -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_);
|
||||||
|
@ -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++) {
|
||||||
|
@ -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);
|
||||||
|
@ -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>();
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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_;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
@ -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_
|
@ -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 {
|
||||||
|
@ -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_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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; }
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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());
|
||||||
|
@ -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());
|
||||||
|
Loading…
Reference in New Issue
Block a user