[compiler-dispatcher] Delete Jobs as BG work
Deleting / deallocating Jobs, along with everything they own (e.g. PersistentHandles), can take a long time, especially if the allocator isn't too friendly to deallocating on a different thread than where the allocation happened. Instead, enqueue Jobs for deletion as part of background processing, with the hope that they end up being deallocated on the same thread as they were allocated, and at the very least taking the deallocation time off the main thread. The deletion queue is processed after the pending background jobs are all processed, and counts as a single "background job" as far as parallelism is concerned. Bug: chromium:1275157 Change-Id: Ie7c3f725f7e510b4325e7590e60477338c478388 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3314835 Reviewed-by: Igor Sheludko <ishell@chromium.org> Commit-Queue: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/main@{#78307}
This commit is contained in:
parent
67a59d803e
commit
85877e54b1
@ -357,6 +357,10 @@ void LazyCompileDispatcher::AbortAll() {
|
||||
DeleteJob(job, lock);
|
||||
}
|
||||
finalizable_jobs_.clear();
|
||||
for (Job* job : jobs_to_dispose_) {
|
||||
delete job;
|
||||
}
|
||||
jobs_to_dispose_.clear();
|
||||
|
||||
DCHECK_EQ(all_jobs_.size(), 0);
|
||||
num_jobs_for_background_ = 0;
|
||||
@ -411,7 +415,7 @@ void LazyCompileDispatcher::DoBackgroundWork(JobDelegate* delegate) {
|
||||
{
|
||||
base::MutexGuard lock(&mutex_);
|
||||
|
||||
if (pending_background_jobs_.empty()) return;
|
||||
if (pending_background_jobs_.empty()) break;
|
||||
job = pending_background_jobs_.back();
|
||||
pending_background_jobs_.pop_back();
|
||||
DCHECK_EQ(job->state, Job::State::kPending);
|
||||
@ -452,6 +456,20 @@ void LazyCompileDispatcher::DoBackgroundWork(JobDelegate* delegate) {
|
||||
}
|
||||
}
|
||||
|
||||
while (!delegate->ShouldYield()) {
|
||||
Job* job = nullptr;
|
||||
{
|
||||
base::MutexGuard lock(&job_dispose_mutex_);
|
||||
if (jobs_to_dispose_.empty()) break;
|
||||
job = jobs_to_dispose_.back();
|
||||
jobs_to_dispose_.pop_back();
|
||||
if (jobs_to_dispose_.empty()) {
|
||||
num_jobs_for_background_--;
|
||||
}
|
||||
}
|
||||
delete job;
|
||||
}
|
||||
|
||||
// Don't touch |this| anymore after this point, as it might have been
|
||||
// deleted.
|
||||
}
|
||||
@ -537,7 +555,11 @@ void LazyCompileDispatcher::DeleteJob(Job* job, const base::MutexGuard&) {
|
||||
#ifdef DEBUG
|
||||
all_jobs_.erase(job);
|
||||
#endif
|
||||
delete job;
|
||||
base::MutexGuard lock(&job_dispose_mutex_);
|
||||
jobs_to_dispose_.push_back(job);
|
||||
if (jobs_to_dispose_.size() == 1) {
|
||||
num_jobs_for_background_++;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -570,7 +592,8 @@ void LazyCompileDispatcher::VerifyBackgroundTaskCount(const base::MutexGuard&) {
|
||||
|
||||
CHECK_EQ(pending_background_jobs_.size(), pending_jobs);
|
||||
CHECK_EQ(finalizable_jobs_.size(), finalizable_jobs);
|
||||
CHECK_EQ(num_jobs_for_background_.load(), pending_jobs + running_jobs);
|
||||
CHECK_EQ(num_jobs_for_background_.load(),
|
||||
pending_jobs + running_jobs + (jobs_to_dispose_.empty() ? 0 : 1));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "src/common/globals.h"
|
||||
#include "src/handles/maybe-handles.h"
|
||||
#include "src/utils/identity-map.h"
|
||||
#include "src/utils/locked-queue.h"
|
||||
#include "testing/gtest/include/gtest/gtest_prod.h" // nogncheck
|
||||
|
||||
namespace v8 {
|
||||
@ -224,6 +225,9 @@ class V8_EXPORT_PRIVATE LazyCompileDispatcher {
|
||||
Job* main_thread_blocking_on_job_;
|
||||
base::ConditionVariable main_thread_blocking_signal_;
|
||||
|
||||
mutable base::Mutex job_dispose_mutex_;
|
||||
std::vector<Job*> jobs_to_dispose_;
|
||||
|
||||
// Test support.
|
||||
base::AtomicValue<bool> block_for_testing_;
|
||||
base::Semaphore semaphore_for_testing_;
|
||||
|
Loading…
Reference in New Issue
Block a user