45 std::memory_order_relaxed);
46 if (
v8_flags.lazy_compile_dispatcher_max_threads == 0)
return n;
48 n,
static_cast<size_t>(
v8_flags.lazy_compile_dispatcher_max_threads));
62 size_t max_stack_size)
65 isolate->counters()->worker_thread_runtime_call_stats()),
67 isolate->counters()->compile_function_on_background()),
69 reinterpret_cast<
v8::
Isolate*>(isolate))),
80 std::make_unique<JobTask>(
this));
98 shared_info->uncompiled_data(isolate);
99 switch (uncompiled_data->map(isolate)->instance_type()) {
102 case UNCOMPILED_DATA_WITH_PREPARSE_DATA_AND_JOB_TYPE:
104 ->set_job(job_address);
106 case UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_WITH_JOB_TYPE:
108 ->set_job(job_address);
114 case UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE: {
115 Handle<String> inferred_name(uncompiled_data->inferred_name(), isolate);
121 isolate->factory()->NewUncompiledDataWithPreparseDataAndJob(
122 inferred_name, uncompiled_data->start_position(),
123 uncompiled_data->end_position(), preparse_data);
125 new_uncompiled_data->set_job(job_address);
126 shared_info->set_uncompiled_data(*new_uncompiled_data);
129 case UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE: {
130 DCHECK(IsUncompiledDataWithoutPreparseData(uncompiled_data));
131 Handle<String> inferred_name(uncompiled_data->inferred_name(), isolate);
132 DirectHandle<UncompiledDataWithoutPreparseDataWithJob>
133 new_uncompiled_data =
134 isolate->factory()->NewUncompiledDataWithoutPreparseDataWithJob(
135 inferred_name, uncompiled_data->start_position(),
136 uncompiled_data->end_position());
138 new_uncompiled_data->set_job(job_address);
139 shared_info->set_uncompiled_data(*new_uncompiled_data);
152 std::unique_ptr<Utf16CharacterStream> character_stream) {
154 "V8.LazyCompilerDispatcherEnqueue");
155 RCS_SCOPE(isolate, RuntimeCallCounterId::kCompileEnqueueOnDispatcher);
157 Job* job =
new Job(std::make_unique<BackgroundCompileTask>(
158 isolate_, shared_info, std::move(character_stream),
162 SetUncompiledDataJobPointer(isolate, shared_info,
163 reinterpret_cast<Address>(job));
170 PrintF(
"LazyCompileDispatcher: enqueued job for ");
176 all_jobs_.insert(job);
187 if (!shared->HasUncompiledData())
return false;
190 if (IsUncompiledDataWithPreparseDataAndJob(data)) {
191 job =
reinterpret_cast<Job*
>(
193 }
else if (IsUncompiledDataWithoutPreparseDataWithJob(data)) {
194 job =
reinterpret_cast<Job*
>(
197 return job !=
nullptr;
203 "V8.LazyCompilerDispatcherWaitForBackgroundJob");
256 "V8.LazyCompilerDispatcherFinishNow");
259 PrintF(
"LazyCompileDispatcher: finishing ");
308 PrintF(
"LazyCompileDispatcher: aborting job for ");
343 job->
task->AbortFunction();
356 job->task->AbortFunction();
362 job->task->AbortFunction();
382 if (!shared->HasUncompiledData())
return nullptr;
384 if (IsUncompiledDataWithPreparseDataAndJob(data)) {
385 return reinterpret_cast<Job*
>(
387 }
else if (IsUncompiledDataWithoutPreparseDataWithJob(data)) {
388 return reinterpret_cast<Job*
>(
404 [
this](
double deadline_in_seconds) { DoIdleWork(deadline_in_seconds); }));
409 "V8.LazyCompileDispatcherDoBackgroundWork");
439 PrintF(
"LazyCompileDispatcher: doing background work\n");
442 job->
task->Run(&isolate, &reusable_state);
504 if (job ==
nullptr)
return false;
507 PrintF(
"LazyCompileDispatcher: idle finalizing job\n");
516 job->
task->AbortFunction();
525 "V8.LazyCompilerDispatcherDoIdleWork");
532 PrintF(
"LazyCompileDispatcher: received %0.1lfms of idle time\n",
539 if (!there_was_a_job)
return;
558 all_jobs_.erase(job);
568 size_t pending_jobs = 0;
569 size_t running_jobs = 0;
570 size_t finalizable_jobs = 0;
572 for (Job* job : all_jobs_) {
573 switch (job->state) {
virtual bool ShouldYield()=0
V8_INLINE void SetValue(T new_value)
V8_INLINE T Value() const
static constexpr int64_t kMillisecondsPerSecond
static bool FinalizeBackgroundCompileTask(BackgroundCompileTask *task, Isolate *isolate, ClearExceptionFlag flag)
JobTask(LazyCompileDispatcher *lazy_compile_dispatcher)
LazyCompileDispatcher * lazy_compile_dispatcher_
void Run(JobDelegate *delegate) final
size_t GetMaxConcurrency(size_t worker_count) const final
base::AtomicValue< bool > block_for_testing_
void Enqueue(LocalIsolate *isolate, Handle< SharedFunctionInfo > shared_info, std::unique_ptr< Utf16CharacterStream > character_stream)
void DoIdleWork(double deadline_in_seconds)
base::Semaphore semaphore_for_testing_
TimedHistogram * background_compile_timer_
bool idle_task_scheduled_
Job * PopSingleFinalizeJob()
void DoBackgroundWork(JobDelegate *delegate)
bool FinishNow(DirectHandle< SharedFunctionInfo > function)
void ScheduleIdleTaskFromAnyThread(const base::MutexGuard &)
bool IsEnqueued(DirectHandle< SharedFunctionInfo > function) const
std::vector< Job * > pending_background_jobs_
Job * main_thread_blocking_on_job_
void NotifyRemovedBackgroundJob(const base::MutexGuard &lock)
LazyCompileDispatcher(Isolate *isolate, Platform *platform, size_t max_stack_size)
std::vector< Job * > jobs_to_dispose_
bool trace_compiler_dispatcher_
void NotifyAddedBackgroundJob(const base::MutexGuard &lock)
WorkerThreadRuntimeCallStats * worker_thread_runtime_call_stats_
base::ConditionVariable main_thread_blocking_signal_
std::unique_ptr< CancelableTaskManager > idle_task_manager_
void AbortJob(DirectHandle< SharedFunctionInfo > function)
std::unique_ptr< JobHandle > job_handle_
std::atomic< size_t > num_jobs_for_background_
Job * GetJobFor(DirectHandle< SharedFunctionInfo > shared, const base::MutexGuard &) const
std::shared_ptr< TaskRunner > taskrunner_
std::vector< Job * > finalizable_jobs_
void WaitForJobIfRunningOnBackground(Job *job, const base::MutexGuard &)
void VerifyBackgroundTaskCount(const base::MutexGuard &)
void PrintF(const char *format,...)
void ShortPrint(Tagged< Object > obj, FILE *out)
std::unique_ptr< CancelableIdleTask > MakeCancelableIdleTask(Isolate *isolate, std::function< void(double)> func)
static constexpr int kMaxOpportunisticFinalizeTimeMs
V8_EXPORT_PRIVATE FlagValues v8_flags
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
#define DCHECK_NE(v1, v2)
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
bool is_running_on_background() const
@ kPendingToRunOnForeground
std::unique_ptr< BackgroundCompileTask > task
Job(std::unique_ptr< BackgroundCompileTask > task)
#define TRACE_EVENT0(category_group, name)
#define TRACE_DISABLED_BY_DEFAULT(name)
#define V8_UNLIKELY(condition)