| Index: src/compiler-dispatcher/compiler-dispatcher.cc
|
| diff --git a/src/compiler-dispatcher/compiler-dispatcher.cc b/src/compiler-dispatcher/compiler-dispatcher.cc
|
| index 47c04b8b44a39792173dd26443179bf137f9745e..5cf10aa3eb8ac012143c4f4b486d0e69c3bcfc1c 100644
|
| --- a/src/compiler-dispatcher/compiler-dispatcher.cc
|
| +++ b/src/compiler-dispatcher/compiler-dispatcher.cc
|
| @@ -66,80 +66,29 @@
|
| job->status() == CompileJobStatus::kFailed;
|
| }
|
|
|
| -bool CanRunOnAnyThread(CompilerDispatcherJob* job) {
|
| - return (job->status() == CompileJobStatus::kReadyToParse &&
|
| - job->can_parse_on_background_thread()) ||
|
| - (job->status() == CompileJobStatus::kReadyToCompile &&
|
| - job->can_compile_on_background_thread());
|
| -}
|
| -
|
| -void DoNextStepOnBackgroundThread(CompilerDispatcherJob* job) {
|
| - DCHECK(CanRunOnAnyThread(job));
|
| - switch (job->status()) {
|
| - case CompileJobStatus::kReadyToParse:
|
| - job->Parse();
|
| - break;
|
| -
|
| - case CompileJobStatus::kReadyToCompile:
|
| - job->Compile();
|
| - break;
|
| -
|
| - default:
|
| - UNREACHABLE();
|
| - }
|
| -}
|
| -
|
| // Theoretically we get 50ms of idle time max, however it's unlikely that
|
| // we'll get all of it so try to be a conservative.
|
| const double kMaxIdleTimeToExpectInMs = 40;
|
|
|
| } // namespace
|
|
|
| -class CompilerDispatcher::BackgroundTask : public CancelableTask {
|
| +class CompilerDispatcher::IdleTask : public CancelableIdleTask {
|
| public:
|
| - BackgroundTask(Isolate* isolate, CancelableTaskManager* task_manager,
|
| - CompilerDispatcher* dispatcher);
|
| - ~BackgroundTask() override;
|
| -
|
| - // CancelableTask implementation.
|
| - void RunInternal() override;
|
| + IdleTask(Isolate* isolate, CompilerDispatcher* dispatcher);
|
| + ~IdleTask() override;
|
| +
|
| + // CancelableIdleTask implementation.
|
| + void RunInternal(double deadline_in_seconds) override;
|
|
|
| private:
|
| CompilerDispatcher* dispatcher_;
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(BackgroundTask);
|
| -};
|
| -
|
| -CompilerDispatcher::BackgroundTask::BackgroundTask(
|
| - Isolate* isolate, CancelableTaskManager* task_manager,
|
| - CompilerDispatcher* dispatcher)
|
| - : CancelableTask(isolate, task_manager), dispatcher_(dispatcher) {}
|
| -
|
| -CompilerDispatcher::BackgroundTask::~BackgroundTask() {}
|
| -
|
| -void CompilerDispatcher::BackgroundTask::RunInternal() {
|
| - dispatcher_->DoBackgroundWork();
|
| -}
|
| -
|
| -class CompilerDispatcher::IdleTask : public CancelableIdleTask {
|
| - public:
|
| - IdleTask(Isolate* isolate, CancelableTaskManager* task_manager,
|
| - CompilerDispatcher* dispatcher);
|
| - ~IdleTask() override;
|
| -
|
| - // CancelableIdleTask implementation.
|
| - void RunInternal(double deadline_in_seconds) override;
|
| -
|
| - private:
|
| - CompilerDispatcher* dispatcher_;
|
| -
|
| DISALLOW_COPY_AND_ASSIGN(IdleTask);
|
| };
|
|
|
| CompilerDispatcher::IdleTask::IdleTask(Isolate* isolate,
|
| - CancelableTaskManager* task_manager,
|
| CompilerDispatcher* dispatcher)
|
| - : CancelableIdleTask(isolate, task_manager), dispatcher_(dispatcher) {}
|
| + : CancelableIdleTask(isolate), dispatcher_(dispatcher) {}
|
|
|
| CompilerDispatcher::IdleTask::~IdleTask() {}
|
|
|
| @@ -153,15 +102,11 @@
|
| platform_(platform),
|
| max_stack_size_(max_stack_size),
|
| tracer_(new CompilerDispatcherTracer(isolate_)),
|
| - task_manager_(new CancelableTaskManager()),
|
| - idle_task_scheduled_(false),
|
| - num_scheduled_background_tasks_(0),
|
| - main_thread_blocking_on_job_(nullptr) {}
|
| + idle_task_scheduled_(false) {}
|
|
|
| CompilerDispatcher::~CompilerDispatcher() {
|
| // To avoid crashing in unit tests due to unfished jobs.
|
| AbortAll(BlockingBehavior::kBlock);
|
| - task_manager_->CancelAndWait();
|
| }
|
|
|
| bool CompilerDispatcher::Enqueue(Handle<SharedFunctionInfo> function) {
|
| @@ -193,27 +138,12 @@
|
| return GetJobFor(function) != jobs_.end();
|
| }
|
|
|
| -void CompilerDispatcher::WaitForJobIfRunningOnBackground(
|
| - CompilerDispatcherJob* job) {
|
| - base::LockGuard<base::Mutex> lock(&mutex_);
|
| - if (running_background_jobs_.find(job) == running_background_jobs_.end()) {
|
| - pending_background_jobs_.erase(job);
|
| - return;
|
| - }
|
| - DCHECK_NULL(main_thread_blocking_on_job_);
|
| - main_thread_blocking_on_job_ = job;
|
| - while (main_thread_blocking_on_job_ != nullptr) {
|
| - main_thread_blocking_signal_.Wait(&mutex_);
|
| - }
|
| - DCHECK(pending_background_jobs_.find(job) == pending_background_jobs_.end());
|
| - DCHECK(running_background_jobs_.find(job) == running_background_jobs_.end());
|
| -}
|
| -
|
| bool CompilerDispatcher::FinishNow(Handle<SharedFunctionInfo> function) {
|
| JobMap::const_iterator job = GetJobFor(function);
|
| CHECK(job != jobs_.end());
|
|
|
| - WaitForJobIfRunningOnBackground(job->second.get());
|
| + // TODO(jochen): Check if there's an in-flight background task working on this
|
| + // job.
|
| while (!IsFinished(job->second.get())) {
|
| DoNextStepOnMainThread(isolate_, job->second.get(),
|
| ExceptionHandling::kThrow);
|
| @@ -224,11 +154,23 @@
|
| return result;
|
| }
|
|
|
| +void CompilerDispatcher::Abort(Handle<SharedFunctionInfo> function,
|
| + BlockingBehavior blocking) {
|
| + USE(blocking);
|
| + JobMap::const_iterator job = GetJobFor(function);
|
| + CHECK(job != jobs_.end());
|
| +
|
| + // TODO(jochen): Check if there's an in-flight background task working on this
|
| + // job.
|
| + job->second->ResetOnMainThread();
|
| + jobs_.erase(job);
|
| +}
|
| +
|
| void CompilerDispatcher::AbortAll(BlockingBehavior blocking) {
|
| - // TODO(jochen): Implement support for non-blocking abort.
|
| - DCHECK(blocking == BlockingBehavior::kBlock);
|
| + USE(blocking);
|
| + // TODO(jochen): Check if there's an in-flight background task working on this
|
| + // job.
|
| for (auto& kv : jobs_) {
|
| - WaitForJobIfRunningOnBackground(kv.second.get());
|
| kv.second->ResetOnMainThread();
|
| }
|
| jobs_.clear();
|
| @@ -246,87 +188,18 @@
|
| return jobs_.end();
|
| }
|
|
|
| -void CompilerDispatcher::ScheduleIdleTaskFromAnyThread() {
|
| +void CompilerDispatcher::ScheduleIdleTaskIfNeeded() {
|
| v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate_);
|
| DCHECK(platform_->IdleTasksEnabled(v8_isolate));
|
| - {
|
| - base::LockGuard<base::Mutex> lock(&mutex_);
|
| - if (idle_task_scheduled_) return;
|
| - idle_task_scheduled_ = true;
|
| - }
|
| - platform_->CallIdleOnForegroundThread(
|
| - v8_isolate, new IdleTask(isolate_, task_manager_.get(), this));
|
| -}
|
| -
|
| -void CompilerDispatcher::ScheduleIdleTaskIfNeeded() {
|
| + if (idle_task_scheduled_) return;
|
| if (jobs_.empty()) return;
|
| - ScheduleIdleTaskFromAnyThread();
|
| -}
|
| -
|
| -void CompilerDispatcher::ConsiderJobForBackgroundProcessing(
|
| - CompilerDispatcherJob* job) {
|
| - if (!CanRunOnAnyThread(job)) return;
|
| - {
|
| - base::LockGuard<base::Mutex> lock(&mutex_);
|
| - pending_background_jobs_.insert(job);
|
| - }
|
| - ScheduleMoreBackgroundTasksIfNeeded();
|
| -}
|
| -
|
| -void CompilerDispatcher::ScheduleMoreBackgroundTasksIfNeeded() {
|
| - if (FLAG_single_threaded) return;
|
| - {
|
| - base::LockGuard<base::Mutex> lock(&mutex_);
|
| - if (pending_background_jobs_.empty()) return;
|
| - if (platform_->NumberOfAvailableBackgroundThreads() <=
|
| - num_scheduled_background_tasks_) {
|
| - return;
|
| - }
|
| - ++num_scheduled_background_tasks_;
|
| - }
|
| - platform_->CallOnBackgroundThread(
|
| - new BackgroundTask(isolate_, task_manager_.get(), this),
|
| - v8::Platform::kShortRunningTask);
|
| -}
|
| -
|
| -void CompilerDispatcher::DoBackgroundWork() {
|
| - CompilerDispatcherJob* job = nullptr;
|
| - {
|
| - base::LockGuard<base::Mutex> lock(&mutex_);
|
| - --num_scheduled_background_tasks_;
|
| - if (!pending_background_jobs_.empty()) {
|
| - auto it = pending_background_jobs_.begin();
|
| - job = *it;
|
| - pending_background_jobs_.erase(it);
|
| - running_background_jobs_.insert(job);
|
| - }
|
| - }
|
| - if (job == nullptr) return;
|
| - DoNextStepOnBackgroundThread(job);
|
| -
|
| - ScheduleMoreBackgroundTasksIfNeeded();
|
| - // Unconditionally schedule an idle task, as all background steps have to be
|
| - // followed by a main thread step.
|
| - ScheduleIdleTaskFromAnyThread();
|
| -
|
| - {
|
| - base::LockGuard<base::Mutex> lock(&mutex_);
|
| - running_background_jobs_.erase(job);
|
| -
|
| - if (main_thread_blocking_on_job_ == job) {
|
| - main_thread_blocking_on_job_ = nullptr;
|
| - main_thread_blocking_signal_.NotifyOne();
|
| - }
|
| - }
|
| - // Don't touch |this| anymore after this point, as it might have been
|
| - // deleted.
|
| + idle_task_scheduled_ = true;
|
| + platform_->CallIdleOnForegroundThread(v8_isolate,
|
| + new IdleTask(isolate_, this));
|
| }
|
|
|
| void CompilerDispatcher::DoIdleWork(double deadline_in_seconds) {
|
| - {
|
| - base::LockGuard<base::Mutex> lock(&mutex_);
|
| - idle_task_scheduled_ = false;
|
| - }
|
| + idle_task_scheduled_ = false;
|
|
|
| // Number of jobs that are unlikely to make progress during any idle callback
|
| // due to their estimated duration.
|
| @@ -341,17 +214,6 @@
|
| job != jobs_.end() && idle_time_in_seconds > 0.0;
|
| idle_time_in_seconds =
|
| deadline_in_seconds - platform_->MonotonicallyIncreasingTime()) {
|
| - // Don't work on jobs that are being worked on by background tasks.
|
| - // Similarly, remove jobs we work on from the set of available background
|
| - // jobs.
|
| - std::unique_ptr<base::LockGuard<base::Mutex>> lock(
|
| - new base::LockGuard<base::Mutex>(&mutex_));
|
| - if (running_background_jobs_.find(job->second.get()) !=
|
| - running_background_jobs_.end()) {
|
| - ++job;
|
| - continue;
|
| - }
|
| - auto it = pending_background_jobs_.find(job->second.get());
|
| double estimate_in_ms = job->second->EstimateRuntimeOfNextStepInMs();
|
| if (idle_time_in_seconds <
|
| (estimate_in_ms /
|
| @@ -360,23 +222,14 @@
|
| // have managed to finish the job in a large idle task to assess
|
| // whether we should ask for another idle callback.
|
| if (estimate_in_ms > kMaxIdleTimeToExpectInMs) ++too_long_jobs;
|
| - if (it == pending_background_jobs_.end()) {
|
| - lock.reset();
|
| - ConsiderJobForBackgroundProcessing(job->second.get());
|
| - }
|
| ++job;
|
| } else if (IsFinished(job->second.get())) {
|
| - DCHECK(it == pending_background_jobs_.end());
|
| job->second->ResetOnMainThread();
|
| job = jobs_.erase(job);
|
| - continue;
|
| + break;
|
| } else {
|
| // Do one step, and keep processing the job (as we don't advance the
|
| // iterator).
|
| - if (it != pending_background_jobs_.end()) {
|
| - pending_background_jobs_.erase(it);
|
| - }
|
| - lock.reset();
|
| DoNextStepOnMainThread(isolate_, job->second.get(),
|
| ExceptionHandling::kSwallow);
|
| }
|
|
|