v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
lazy-compile-dispatcher.h
Go to the documentation of this file.
1// Copyright 2016 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_COMPILER_DISPATCHER_LAZY_COMPILE_DISPATCHER_H_
6#define V8_COMPILER_DISPATCHER_LAZY_COMPILE_DISPATCHER_H_
7
8#include <cstdint>
9#include <memory>
10#include <unordered_set>
11#include <utility>
12#include <vector>
13
15#include "src/base/macros.h"
19#include "src/common/globals.h"
21#include "testing/gtest/include/gtest/gtest_prod.h" // nogncheck
22
23namespace v8 {
24
25class JobDelegate;
26class JobHandle;
27class Platform;
28class TaskRunner;
29enum class MemoryPressureLevel;
30
31namespace internal {
32
33class AstRawString;
34class AstValueFactory;
35class BackgroundCompileTask;
36class CancelableTaskManager;
37class UnoptimizedCompileJob;
38class UnoptimizedCompileState;
39class FunctionLiteral;
40class ParseInfo;
41class ProducedPreparseData;
42class SharedFunctionInfo;
43class TimedHistogram;
44class Utf16CharacterStream;
45class WorkerThreadRuntimeCallStats;
46class Zone;
47
48
49// The LazyCompileDispatcher uses a combination of idle tasks and background
50// tasks to parse and compile lazily parsed functions.
51//
52// As both parsing and compilation currently requires a preparation and
53// finalization step that happens on the main thread, every task has to be
54// advanced during idle time first. Depending on the properties of the task, it
55// can then be parsed or compiled on either background threads, or during idle
56// time. Last, it has to be finalized during idle time again.
57//
58// LazyCompileDispatcher::jobs_ maintains the list of all
59// LazyCompilerDispatcherJobs the LazyCompileDispatcher knows about.
60//
61// LazyCompileDispatcher::pending_background_jobs_ contains the set of
62// LazyCompilerDispatcherJobs that can be processed on a background thread.
63//
64// LazyCompileDispatcher::running_background_jobs_ contains the set of
65// LazyCompilerDispatcherJobs that are currently being processed on a background
66// thread.
67//
68// LazyCompileDispatcher::DoIdleWork tries to advance as many jobs out of jobs_
69// as possible during idle time. If a job can't be advanced, but is suitable for
70// background processing, it fires off background threads.
71//
72// LazyCompileDispatcher::DoBackgroundWork advances one of the pending jobs,
73// and then spins of another idle task to potentially do the final step on the
74// main thread.
76 public:
77 using JobId = uintptr_t;
78
79 LazyCompileDispatcher(Isolate* isolate, Platform* platform,
80 size_t max_stack_size);
84
85 void Enqueue(LocalIsolate* isolate, Handle<SharedFunctionInfo> shared_info,
86 std::unique_ptr<Utf16CharacterStream> character_stream);
87
88 // Returns true if there is a pending job registered for the given function.
89 bool IsEnqueued(DirectHandle<SharedFunctionInfo> function) const;
90
91 // Blocks until the given function is compiled (and does so as fast as
92 // possible). Returns true if the compile job was successful.
93 bool FinishNow(DirectHandle<SharedFunctionInfo> function);
94
95 // Aborts compilation job for the given function.
96 void AbortJob(DirectHandle<SharedFunctionInfo> function);
97
98 // Aborts all jobs, blocking until all jobs are aborted.
99 void AbortAll();
100
101 private:
102 FRIEND_TEST(LazyCompileDispatcherTest, IdleTaskNoIdleTime);
103 FRIEND_TEST(LazyCompileDispatcherTest, IdleTaskSmallIdleTime);
104 FRIEND_TEST(LazyCompileDispatcherTest, FinishNowWithWorkerTask);
105 FRIEND_TEST(LazyCompileDispatcherTest, AbortJobNotStarted);
106 FRIEND_TEST(LazyCompileDispatcherTest, AbortJobAlreadyStarted);
107 FRIEND_TEST(LazyCompileDispatcherTest, AsyncAbortAllPendingWorkerTask);
108 FRIEND_TEST(LazyCompileDispatcherTest, AsyncAbortAllRunningWorkerTask);
109 FRIEND_TEST(LazyCompileDispatcherTest, CompileMultipleOnBackgroundThread);
110
111 // JobTask for PostJob API.
112 class JobTask;
113
114 struct Job {
115 enum class State {
116 // Background thread states (Enqueue + DoBackgroundWork)
117 // ---
118
119 // In the pending task queue.
120 kPending,
121 // Currently running on a background thread.
122 kRunning,
123 kAbortRequested, // ... but we want to drop the result.
124 // In the finalizable task queue.
125 kReadyToFinalize,
126 kAborted,
127
128 // Main thread states (FinishNow and FinalizeSingleJob)
129 // ---
130
131 // Popped off the pending task queue.
132 kPendingToRunOnForeground,
133 // Popped off the finalizable task queue.
134 kFinalizingNow,
135 kAbortingNow, // ... and we want to abort
136
137 // Finished finalizing, ready for deletion.
138 kFinalized,
139 };
140
141 explicit Job(std::unique_ptr<BackgroundCompileTask> task);
143
145 return state == State::kRunning || state == State::kAbortRequested;
146 }
147
148 std::unique_ptr<BackgroundCompileTask> task;
149 State state = State::kPending;
150 };
151
153
154 void WaitForJobIfRunningOnBackground(Job* job, const base::MutexGuard&);
155 Job* GetJobFor(DirectHandle<SharedFunctionInfo> shared,
156 const base::MutexGuard&) const;
157 Job* PopSingleFinalizeJob();
158 void ScheduleIdleTaskFromAnyThread(const base::MutexGuard&);
159 bool FinalizeSingleJob();
160 void DoBackgroundWork(JobDelegate* delegate);
161 void DoIdleWork(double deadline_in_seconds);
162
163 // DeleteJob without the mutex held.
164 void DeleteJob(Job* job);
165 // DeleteJob with the mutex already held.
166 void DeleteJob(Job* job, const base::MutexGuard&);
167
169 ++num_jobs_for_background_;
170 VerifyBackgroundTaskCount(lock);
171 }
173 --num_jobs_for_background_;
174 VerifyBackgroundTaskCount(lock);
175 }
176
177#ifdef DEBUG
178 void VerifyBackgroundTaskCount(const base::MutexGuard&);
179#else
181#endif
182
186 std::shared_ptr<TaskRunner> taskrunner_;
189
190 std::unique_ptr<JobHandle> job_handle_;
191
192 // Copy of v8_flags.trace_compiler_dispatcher to allow for access from any
193 // thread.
195
196 std::unique_ptr<CancelableTaskManager> idle_task_manager_;
197
198 // The following members can be accessed from any thread. Methods need to hold
199 // the mutex |mutex_| while accessing them.
201
202 // True if an idle task is scheduled to be run.
204
205 // The set of jobs that can be run on a background thread.
206 std::vector<Job*> pending_background_jobs_;
207
208 // The set of jobs that can be finalized on the main thread.
209 std::vector<Job*> finalizable_jobs_;
210
211 // The total number of jobs ready to execute on background, both those pending
212 // and those currently running.
213 std::atomic<size_t> num_jobs_for_background_;
214
215#ifdef DEBUG
216 // The set of all allocated jobs, used for verification of the various queues
217 // and counts.
218 std::unordered_set<Job*> all_jobs_;
219#endif
220
221 // A queue of jobs to delete on the background thread(s). Jobs in this queue
222 // are considered dead as far as the rest of the system is concerned, so they
223 // won't be pointed to by any SharedFunctionInfo and won't be in the all_jobs
224 // set above.
225 std::vector<Job*> jobs_to_dispose_;
226
227 // If not nullptr, then the main thread waits for the task processing
228 // this job, and blocks on the ConditionVariable main_thread_blocking_signal_.
231
232 // Test support.
235};
236
237} // namespace internal
238} // namespace v8
239
240#endif // V8_COMPILER_DISPATCHER_LAZY_COMPILE_DISPATCHER_H_
friend Zone
Definition asm-types.cc:195
FRIEND_TEST(LazyCompileDispatcherTest, AsyncAbortAllRunningWorkerTask)
FRIEND_TEST(LazyCompileDispatcherTest, AbortJobNotStarted)
void NotifyRemovedBackgroundJob(const base::MutexGuard &lock)
LazyCompileDispatcher(const LazyCompileDispatcher &)=delete
void NotifyAddedBackgroundJob(const base::MutexGuard &lock)
FRIEND_TEST(LazyCompileDispatcherTest, CompileMultipleOnBackgroundThread)
FRIEND_TEST(LazyCompileDispatcherTest, IdleTaskSmallIdleTime)
WorkerThreadRuntimeCallStats * worker_thread_runtime_call_stats_
FRIEND_TEST(LazyCompileDispatcherTest, AbortJobAlreadyStarted)
base::ConditionVariable main_thread_blocking_signal_
std::unique_ptr< CancelableTaskManager > idle_task_manager_
FRIEND_TEST(LazyCompileDispatcherTest, FinishNowWithWorkerTask)
FRIEND_TEST(LazyCompileDispatcherTest, IdleTaskNoIdleTime)
std::shared_ptr< TaskRunner > taskrunner_
FRIEND_TEST(LazyCompileDispatcherTest, AsyncAbortAllPendingWorkerTask)
void VerifyBackgroundTaskCount(const base::MutexGuard &)
LazyCompileDispatcher & operator=(const LazyCompileDispatcher &)=delete
v8::JobDelegate JobDelegate
Definition platform.h:20
v8::TaskRunner TaskRunner
Definition platform.h:25
v8::JobHandle JobHandle
Definition platform.h:19
MemoryPressureLevel
Definition v8-isolate.h:175
#define V8_EXPORT_PRIVATE
Definition macros.h:460
std::unique_ptr< BackgroundCompileTask > task