v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
optimizing-compile-dispatcher.h
Go to the documentation of this file.
1// Copyright 2012 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_OPTIMIZING_COMPILE_DISPATCHER_H_
6#define V8_COMPILER_DISPATCHER_OPTIMIZING_COMPILE_DISPATCHER_H_
7
8#include <atomic>
9#include <queue>
10
13#include "src/base/vector.h"
14#include "src/common/globals.h"
15#include "src/flags/flags.h"
17
18namespace v8 {
19namespace internal {
20
21class LocalHeap;
22class TurbofanCompilationJob;
23class RuntimeCallStats;
24class SharedFunctionInfo;
25
26// Align the structure to the cache line size to prevent false sharing. While a
27// task state is owned by a single thread, all tasks states are kept in a vector
28// in OptimizingCompileDispatcher::task_states.
29struct alignas(PROCESSOR_CACHE_LINE_SIZE) OptimizingCompileTaskState {
32};
33
34// Circular queue of incoming recompilation tasks (including OSR).
36 public:
37 inline bool IsAvailable() {
38 base::MutexGuard access(&mutex_);
39 return queue_.size() < capacity_;
40 }
41
42 inline size_t Length() {
43 base::MutexGuard access_queue(&mutex_);
44 return queue_.size();
45 }
46
47 explicit OptimizingCompileInputQueue(int capacity) : capacity_(capacity) {}
48
50 TurbofanCompilationJob* DequeueIfIsolateMatches(
51 OptimizingCompileTaskState& task_state);
52
53 bool Enqueue(std::unique_ptr<TurbofanCompilationJob>& job);
54
55 void FlushJobsForIsolate(Isolate* isolate);
56 bool HasJobForIsolate(Isolate* isolate);
57
58 void Prioritize(Isolate* isolate, Tagged<SharedFunctionInfo> function);
59
60 private:
61 std::deque<TurbofanCompilationJob*> queue_;
62 size_t capacity_;
63
66
68};
69
70// This class runs compile tasks in a thread pool. Threads grab new work from
71// the input_queue_ defined in this class. Once a task is done, it will be
72// enqueued into an isolate-local output queue. This class is
73// not specific to a particular isolate and may be shared across multiple
74// isolates in the future.
76 public:
79
80 // Creates Job with PostJob.
81 void EnsureInitialized();
82
83 // Invokes and runs Turbofan for this particular job.
84 void RunCompilationJob(OptimizingCompileTaskState& task_state,
85 Isolate* isolate, LocalIsolate& local_isolate,
87
88 // Gets the next job from the input queue.
90
91 // Gets the next job from the input queue but only if the job is also for the
92 // same isolate as in the given `OptimizingCompileTaskState`.
93 TurbofanCompilationJob* NextInputIfIsolateMatches(
94 OptimizingCompileTaskState& task_state);
95
96 // Returns true when one of the currently running compilation tasks is
97 // operating on the given isolate. If the return value is false, the caller
98 // can also assume that no LocalHeap/LocalIsolate exists for the isolate
99 // anymore as well.
100 bool IsTaskRunningForIsolate(Isolate* isolate);
101
102 // Clears the state for a task/thread once it is done with a job. This mainly
103 // clears the current isolate for this task. Only invoke this after the
104 // LocalHeap/LocalIsolate for this thread was destroyed as well.
105 void ClearTaskState(OptimizingCompileTaskState& task_state);
106
107 void ResetJob(OptimizingCompileTaskState& task_state);
108
109 // Tries to append a new compilation job to the input queue. This may fail if
110 // the input queue was already full.
111 bool TryQueueForOptimization(std::unique_ptr<TurbofanCompilationJob>& job);
112
113 // Waits until all running and queued compilation jobs for this isolate are
114 // done.
115 void WaitUntilCompilationJobsDoneForIsolate(Isolate* isolate);
116
117 // Cancels all running compilation jobs for this isolate and then waits until
118 // they stop running.
119 void CancelCompilationJobsForIsolate(Isolate* isolate);
120
121 // Returns true if there exists a currently running or queued compilation job
122 // for this isolate..
123 bool HasCompilationJobsForIsolate(Isolate* isolate);
124
125 private:
126 class CompileTask;
127
128 static constexpr TaskPriority kTaskPriority = TaskPriority::kUserVisible;
129 static constexpr TaskPriority kEfficiencyTaskPriority =
130 TaskPriority::kBestEffort;
131
133
134 // Copy of v8_flags.concurrent_recompilation_delay that will be used from the
135 // background thread.
136 //
137 // Since flags might get modified while the background thread is running, it
138 // is not safe to access them directly.
140
141 std::unique_ptr<JobHandle> job_handle_;
142
144
145 // Used to avoid creating the JobHandle twice.
146 bool is_initialized_ = false;
147
149};
150
152 public:
153 void Enqueue(TurbofanCompilationJob* job);
154 std::unique_ptr<TurbofanCompilationJob> Dequeue();
155
156 int InstallGeneratedBuiltins(Isolate* isolate, int installed_count);
157
158 size_t size() const;
159 bool empty() const;
160
161 private:
162 // Queue of recompilation tasks ready to be installed (excluding OSR).
163 std::deque<TurbofanCompilationJob*> queue_;
164
165 // Used for job based recompilation which has multiple producers on
166 // different threads.
168};
169
170// OptimizingCompileDispatcher is an isolate-specific class to enqueue Turbofan
171// compilation jobs and retrieve results.
173 public:
175 Isolate* isolate, OptimizingCompileTaskExecutor* task_executor);
176
178
179 // Flushes input and output queue for compilation jobs. If blocking behavior
180 // is used, it will also wait until the running compilation jobs are done
181 // before flushing the output queue.
182 void Flush(BlockingBehavior blocking_behavior);
183
184 // Tries to append the compilation job to the input queue. Takes ownership of
185 // |job| if successful. Fails if the input queue is already full.
186 bool TryQueueForOptimization(std::unique_ptr<TurbofanCompilationJob>& job);
187
188 // Waits until all running and queued compilation jobs have finished.
189 void WaitUntilCompilationJobsDone();
190
191 void InstallOptimizedFunctions();
192
193 // Install generated builtins in the output queue in contiguous finalization
194 // order, starting with installed_count. Returns the finalization order of the
195 // last job that was finalized.
196 int InstallGeneratedBuiltins(int installed_count);
197
198 // Returns true if there is space available in the input queue.
199 inline bool IsQueueAvailable() { return input_queue().IsAvailable(); }
200
201 static bool Enabled() { return v8_flags.concurrent_recompilation; }
202
203 // This method must be called on the main thread.
204 bool HasJobs();
205
206 // Whether to finalize and thus install the optimized code. Defaults to true.
207 // Only set to false for testing (where finalization is then manually
208 // requested using %FinalizeOptimization) and when compiling embedded builtins
209 // concurrently. For the latter, builtins are installed manually using
210 // InstallGeneratedBuiltins().
211 bool finalize() const { return finalize_; }
212 void set_finalize(bool finalize) {
213 CHECK(!HasJobs());
214 finalize_ = finalize;
215 }
216
217 void Prioritize(Tagged<SharedFunctionInfo> function);
218
219 void StartTearDown();
220 void FinishTearDown();
221
222 void QueueFinishedJob(TurbofanCompilationJob* job);
223
224 private:
225 enum ModeFlag { COMPILE, FLUSH };
226
227 void FlushQueues(BlockingBehavior blocking_behavior);
228 void FlushInputQueue();
229 void FlushOutputQueue();
230
232 return task_executor_->input_queue_;
233 }
234
236 return task_executor_->recompilation_delay_;
237 }
238
240
242
244
245 bool finalize_ = true;
246};
247} // namespace internal
248} // namespace v8
249
250#endif // V8_COMPILER_DISPATCHER_OPTIMIZING_COMPILE_DISPATCHER_H_
std::deque< TurbofanCompilationJob * > queue_
base::OwnedVector< OptimizingCompileTaskState > task_states_
base::Mutex & mutex_
V8_EXPORT_PRIVATE FlagValues v8_flags
TaskPriority
Definition v8-platform.h:24
#define CHECK(condition)
Definition logging.h:124
#define V8_EXPORT_PRIVATE
Definition macros.h:460
#define V8_EXPORT
Definition v8config.h:800