Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: src/optimizing-compiler-thread.cc

Issue 816363003: Implement missing functionality for job based recompilation (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: updates Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/optimizing-compiler-thread.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/optimizing-compiler-thread.h" 5 #include "src/optimizing-compiler-thread.h"
6 6
7 #include "src/v8.h" 7 #include "src/v8.h"
8 8
9 #include "src/base/atomicops.h" 9 #include "src/base/atomicops.h"
10 #include "src/full-codegen.h" 10 #include "src/full-codegen.h"
11 #include "src/hydrogen.h" 11 #include "src/hydrogen.h"
12 #include "src/isolate.h" 12 #include "src/isolate.h"
13 #include "src/v8threads.h" 13 #include "src/v8threads.h"
14 14
15 namespace v8 { 15 namespace v8 {
16 namespace internal { 16 namespace internal {
17 17
18 namespace {
19
20 void DisposeOptimizedCompileJob(OptimizedCompileJob* job,
21 bool restore_function_code) {
22 // The recompile job is allocated in the CompilationInfo's zone.
23 CompilationInfo* info = job->info();
24 if (restore_function_code) {
25 if (info->is_osr()) {
26 if (!job->IsWaitingForInstall()) {
27 // Remove stack check that guards OSR entry on original code.
28 Handle<Code> code = info->unoptimized_code();
29 uint32_t offset = code->TranslateAstIdToPcOffset(info->osr_ast_id());
30 BackEdgeTable::RemoveStackCheck(code, offset);
31 }
32 } else {
33 Handle<JSFunction> function = info->closure();
34 function->ReplaceCode(function->shared()->code());
35 }
36 }
37 delete info;
38 }
39
40 } // namespace
41
42
18 class OptimizingCompilerThread::CompileTask : public v8::Task { 43 class OptimizingCompilerThread::CompileTask : public v8::Task {
19 public: 44 public:
20 CompileTask(Isolate* isolate, OptimizedCompileJob* job) 45 explicit CompileTask(Isolate* isolate) : isolate_(isolate) {}
21 : isolate_(isolate), job_(job) {}
22 46
23 virtual ~CompileTask() {} 47 virtual ~CompileTask() {}
24 48
25 private: 49 private:
26 // v8::Task overrides. 50 // v8::Task overrides.
27 void Run() OVERRIDE { 51 void Run() OVERRIDE {
28 DisallowHeapAllocation no_allocation; 52 DisallowHeapAllocation no_allocation;
29 DisallowHandleAllocation no_handles; 53 DisallowHandleAllocation no_handles;
30 DisallowHandleDereference no_deref; 54 DisallowHandleDereference no_deref;
31 55
32 // The function may have already been optimized by OSR. Simply continue. 56 TimerEventScope<TimerEventRecompileConcurrent> timer(isolate_);
33 OptimizedCompileJob::Status status = job_->OptimizeGraph();
34 USE(status); // Prevent an unused-variable error in release mode.
35 DCHECK(status != OptimizedCompileJob::FAILED);
36 57
37 // The function may have already been optimized by OSR. Simply continue. 58 OptimizingCompilerThread* thread = isolate_->optimizing_compiler_thread();
38 // Use a mutex to make sure that functions marked for install 59
39 // are always also queued. 60 if (thread->recompilation_delay_ != 0) {
61 base::OS::Sleep(thread->recompilation_delay_);
62 }
63
64 StopFlag flag;
65 OptimizedCompileJob* job = thread->NextInput(&flag);
66
67 if (flag == CONTINUE) {
68 thread->CompileNext(job);
69 } else {
70 AllowHandleDereference allow_handle_dereference;
71 if (!job->info()->is_osr()) {
72 DisposeOptimizedCompileJob(job, true);
73 }
74 }
75 bool signal = false;
40 { 76 {
41 base::LockGuard<base::Mutex> lock_guard( 77 base::LockGuard<base::RecursiveMutex> lock(&thread->task_count_mutex_);
42 &isolate_->optimizing_compiler_thread()->output_queue_mutex_); 78 if (--thread->task_count_ == 0) {
43 isolate_->optimizing_compiler_thread()->output_queue_.Enqueue(job_); 79 if (static_cast<StopFlag>(base::Acquire_Load(&thread->stop_thread_)) ==
80 FLUSH) {
81 base::Release_Store(&thread->stop_thread_,
82 static_cast<base::AtomicWord>(CONTINUE));
83 signal = true;
84 }
85 }
44 } 86 }
45 isolate_->stack_guard()->RequestInstallCode(); 87 if (signal) thread->stop_semaphore_.Signal();
46 {
47 base::LockGuard<base::Mutex> lock_guard(
48 &isolate_->optimizing_compiler_thread()->input_queue_mutex_);
49 isolate_->optimizing_compiler_thread()->input_queue_length_--;
50 }
51 isolate_->optimizing_compiler_thread()->input_queue_semaphore_.Signal();
52 } 88 }
53 89
54 Isolate* isolate_; 90 Isolate* isolate_;
55 OptimizedCompileJob* job_;
56 91
57 DISALLOW_COPY_AND_ASSIGN(CompileTask); 92 DISALLOW_COPY_AND_ASSIGN(CompileTask);
58 }; 93 };
59 94
60 95
61 OptimizingCompilerThread::~OptimizingCompilerThread() { 96 OptimizingCompilerThread::~OptimizingCompilerThread() {
62 DCHECK_EQ(0, input_queue_length_); 97 DCHECK_EQ(0, input_queue_length_);
63 DeleteArray(input_queue_); 98 DeleteArray(input_queue_);
64 if (FLAG_concurrent_osr) { 99 if (FLAG_concurrent_osr) {
65 #ifdef DEBUG 100 #ifdef DEBUG
(...skipping 20 matching lines...) Expand all
86 return; 121 return;
87 } 122 }
88 123
89 base::ElapsedTimer total_timer; 124 base::ElapsedTimer total_timer;
90 if (tracing_enabled_) total_timer.Start(); 125 if (tracing_enabled_) total_timer.Start();
91 126
92 while (true) { 127 while (true) {
93 input_queue_semaphore_.Wait(); 128 input_queue_semaphore_.Wait();
94 TimerEventScope<TimerEventRecompileConcurrent> timer(isolate_); 129 TimerEventScope<TimerEventRecompileConcurrent> timer(isolate_);
95 130
96 if (FLAG_concurrent_recompilation_delay != 0) { 131 if (recompilation_delay_ != 0) {
97 base::OS::Sleep(FLAG_concurrent_recompilation_delay); 132 base::OS::Sleep(recompilation_delay_);
98 } 133 }
99 134
100 switch (static_cast<StopFlag>(base::Acquire_Load(&stop_thread_))) { 135 switch (static_cast<StopFlag>(base::Acquire_Load(&stop_thread_))) {
101 case CONTINUE: 136 case CONTINUE:
102 break; 137 break;
103 case STOP: 138 case STOP:
104 if (tracing_enabled_) { 139 if (tracing_enabled_) {
105 time_spent_total_ = total_timer.Elapsed(); 140 time_spent_total_ = total_timer.Elapsed();
106 } 141 }
107 stop_semaphore_.Signal(); 142 stop_semaphore_.Signal();
108 return; 143 return;
109 case FLUSH: 144 case FLUSH:
110 // The main thread is blocked, waiting for the stop semaphore. 145 // The main thread is blocked, waiting for the stop semaphore.
111 { AllowHandleDereference allow_handle_dereference; 146 { AllowHandleDereference allow_handle_dereference;
112 FlushInputQueue(true); 147 FlushInputQueue(true);
113 } 148 }
114 base::Release_Store(&stop_thread_, 149 base::Release_Store(&stop_thread_,
115 static_cast<base::AtomicWord>(CONTINUE)); 150 static_cast<base::AtomicWord>(CONTINUE));
116 stop_semaphore_.Signal(); 151 stop_semaphore_.Signal();
117 // Return to start of consumer loop. 152 // Return to start of consumer loop.
118 continue; 153 continue;
119 } 154 }
120 155
121 base::ElapsedTimer compiling_timer; 156 base::ElapsedTimer compiling_timer;
122 if (tracing_enabled_) compiling_timer.Start(); 157 if (tracing_enabled_) compiling_timer.Start();
123 158
124 CompileNext(); 159 CompileNext(NextInput());
125 160
126 if (tracing_enabled_) { 161 if (tracing_enabled_) {
127 time_spent_compiling_ += compiling_timer.Elapsed(); 162 time_spent_compiling_ += compiling_timer.Elapsed();
128 } 163 }
129 } 164 }
130 } 165 }
131 166
132 167
133 OptimizedCompileJob* OptimizingCompilerThread::NextInput() { 168 OptimizedCompileJob* OptimizingCompilerThread::NextInput(StopFlag* flag) {
134 base::LockGuard<base::Mutex> access_input_queue_(&input_queue_mutex_); 169 base::LockGuard<base::Mutex> access_input_queue_(&input_queue_mutex_);
135 DCHECK(!job_based_recompilation_); 170 if (input_queue_length_ == 0) {
136 if (input_queue_length_ == 0) return NULL; 171 if (flag) {
172 UNREACHABLE();
173 *flag = CONTINUE;
174 }
175 return NULL;
176 }
137 OptimizedCompileJob* job = input_queue_[InputQueueIndex(0)]; 177 OptimizedCompileJob* job = input_queue_[InputQueueIndex(0)];
138 DCHECK_NE(NULL, job); 178 DCHECK_NE(NULL, job);
139 input_queue_shift_ = InputQueueIndex(1); 179 input_queue_shift_ = InputQueueIndex(1);
140 input_queue_length_--; 180 input_queue_length_--;
181 if (flag) {
182 *flag = static_cast<StopFlag>(base::Acquire_Load(&stop_thread_));
183 }
141 return job; 184 return job;
142 } 185 }
143 186
144 187
145 void OptimizingCompilerThread::CompileNext() { 188 void OptimizingCompilerThread::CompileNext(OptimizedCompileJob* job) {
146 OptimizedCompileJob* job = NextInput();
147 DCHECK_NE(NULL, job); 189 DCHECK_NE(NULL, job);
148 190
149 // The function may have already been optimized by OSR. Simply continue. 191 // The function may have already been optimized by OSR. Simply continue.
150 OptimizedCompileJob::Status status = job->OptimizeGraph(); 192 OptimizedCompileJob::Status status = job->OptimizeGraph();
151 USE(status); // Prevent an unused-variable error in release mode. 193 USE(status); // Prevent an unused-variable error in release mode.
152 DCHECK(status != OptimizedCompileJob::FAILED); 194 DCHECK(status != OptimizedCompileJob::FAILED);
153 195
154 // The function may have already been optimized by OSR. Simply continue. 196 // The function may have already been optimized by OSR. Simply continue.
155 // Use a mutex to make sure that functions marked for install 197 // Use a mutex to make sure that functions marked for install
156 // are always also queued. 198 // are always also queued.
199 if (job_based_recompilation_) output_queue_mutex_.Lock();
157 output_queue_.Enqueue(job); 200 output_queue_.Enqueue(job);
201 if (job_based_recompilation_) output_queue_mutex_.Unlock();
158 isolate_->stack_guard()->RequestInstallCode(); 202 isolate_->stack_guard()->RequestInstallCode();
159 } 203 }
160 204
161 205
162 static void DisposeOptimizedCompileJob(OptimizedCompileJob* job,
163 bool restore_function_code) {
164 // The recompile job is allocated in the CompilationInfo's zone.
165 CompilationInfo* info = job->info();
166 if (restore_function_code) {
167 if (info->is_osr()) {
168 if (!job->IsWaitingForInstall()) {
169 // Remove stack check that guards OSR entry on original code.
170 Handle<Code> code = info->unoptimized_code();
171 uint32_t offset = code->TranslateAstIdToPcOffset(info->osr_ast_id());
172 BackEdgeTable::RemoveStackCheck(code, offset);
173 }
174 } else {
175 Handle<JSFunction> function = info->closure();
176 function->ReplaceCode(function->shared()->code());
177 }
178 }
179 delete info;
180 }
181
182
183 void OptimizingCompilerThread::FlushInputQueue(bool restore_function_code) { 206 void OptimizingCompilerThread::FlushInputQueue(bool restore_function_code) {
184 DCHECK(!job_based_recompilation_);
185 OptimizedCompileJob* job; 207 OptimizedCompileJob* job;
186 while ((job = NextInput())) { 208 while ((job = NextInput())) {
209 DCHECK(!job_based_recompilation_);
187 // This should not block, since we have one signal on the input queue 210 // This should not block, since we have one signal on the input queue
188 // semaphore corresponding to each element in the input queue. 211 // semaphore corresponding to each element in the input queue.
189 input_queue_semaphore_.Wait(); 212 input_queue_semaphore_.Wait();
190 // OSR jobs are dealt with separately. 213 // OSR jobs are dealt with separately.
191 if (!job->info()->is_osr()) { 214 if (!job->info()->is_osr()) {
192 DisposeOptimizedCompileJob(job, restore_function_code); 215 DisposeOptimizedCompileJob(job, restore_function_code);
193 } 216 }
194 } 217 }
195 } 218 }
196 219
197 220
198 void OptimizingCompilerThread::FlushOutputQueue(bool restore_function_code) { 221 void OptimizingCompilerThread::FlushOutputQueue(bool restore_function_code) {
222 base::LockGuard<base::Mutex> access_output_queue_(&output_queue_mutex_);
199 OptimizedCompileJob* job; 223 OptimizedCompileJob* job;
200 while (output_queue_.Dequeue(&job)) { 224 while (output_queue_.Dequeue(&job)) {
201 // OSR jobs are dealt with separately. 225 // OSR jobs are dealt with separately.
202 if (!job->info()->is_osr()) { 226 if (!job->info()->is_osr()) {
203 DisposeOptimizedCompileJob(job, restore_function_code); 227 DisposeOptimizedCompileJob(job, restore_function_code);
204 } 228 }
205 } 229 }
206 } 230 }
207 231
208 232
209 void OptimizingCompilerThread::FlushOsrBuffer(bool restore_function_code) { 233 void OptimizingCompilerThread::FlushOsrBuffer(bool restore_function_code) {
210 for (int i = 0; i < osr_buffer_capacity_; i++) { 234 for (int i = 0; i < osr_buffer_capacity_; i++) {
211 if (osr_buffer_[i] != NULL) { 235 if (osr_buffer_[i] != NULL) {
212 DisposeOptimizedCompileJob(osr_buffer_[i], restore_function_code); 236 DisposeOptimizedCompileJob(osr_buffer_[i], restore_function_code);
213 osr_buffer_[i] = NULL; 237 osr_buffer_[i] = NULL;
214 } 238 }
215 } 239 }
216 } 240 }
217 241
218 242
219 void OptimizingCompilerThread::Flush() { 243 void OptimizingCompilerThread::Flush() {
220 DCHECK(!IsOptimizerThread()); 244 DCHECK(!IsOptimizerThread());
221 base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(FLUSH)); 245 bool block = true;
222 if (FLAG_block_concurrent_recompilation) Unblock(); 246 if (job_based_recompilation_) {
223 if (!job_based_recompilation_) { 247 base::LockGuard<base::RecursiveMutex> lock(&task_count_mutex_);
224 input_queue_semaphore_.Signal(); 248 block = task_count_ > 0 || blocked_jobs_ > 0;
225 stop_semaphore_.Wait(); 249 if (block) {
250 base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(FLUSH));
251 }
252 if (FLAG_block_concurrent_recompilation) Unblock();
253 } else {
254 base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(FLUSH));
255 if (FLAG_block_concurrent_recompilation) Unblock();
226 } 256 }
257 if (!job_based_recompilation_) input_queue_semaphore_.Signal();
258 if (block) stop_semaphore_.Wait();
227 FlushOutputQueue(true); 259 FlushOutputQueue(true);
228 if (FLAG_concurrent_osr) FlushOsrBuffer(true); 260 if (FLAG_concurrent_osr) FlushOsrBuffer(true);
229 if (tracing_enabled_) { 261 if (tracing_enabled_) {
230 PrintF(" ** Flushed concurrent recompilation queues.\n"); 262 PrintF(" ** Flushed concurrent recompilation queues.\n");
231 } 263 }
232 } 264 }
233 265
234 266
235 void OptimizingCompilerThread::Stop() { 267 void OptimizingCompilerThread::Stop() {
236 DCHECK(!IsOptimizerThread()); 268 DCHECK(!IsOptimizerThread());
237 base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(STOP)); 269 bool block = true;
238 if (FLAG_block_concurrent_recompilation) Unblock(); 270 if (job_based_recompilation_) {
239 if (!job_based_recompilation_) { 271 base::LockGuard<base::RecursiveMutex> lock(&task_count_mutex_);
240 input_queue_semaphore_.Signal(); 272 block = task_count_ > 0 || blocked_jobs_ > 0;
241 stop_semaphore_.Wait(); 273 if (block) {
274 base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(FLUSH));
275 }
276 if (FLAG_block_concurrent_recompilation) Unblock();
277 } else {
278 base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(STOP));
279 if (FLAG_block_concurrent_recompilation) Unblock();
242 } 280 }
281 if (!job_based_recompilation_) input_queue_semaphore_.Signal();
282 if (block) stop_semaphore_.Wait();
243 283
244 if (job_based_recompilation_) { 284 if (recompilation_delay_ != 0) {
245 while (true) {
246 {
247 base::LockGuard<base::Mutex> access_input_queue(&input_queue_mutex_);
248 if (!input_queue_length_) break;
249 }
250 input_queue_semaphore_.Wait();
251 }
252 } else if (FLAG_concurrent_recompilation_delay != 0) {
253 // At this point the optimizing compiler thread's event loop has stopped. 285 // At this point the optimizing compiler thread's event loop has stopped.
254 // There is no need for a mutex when reading input_queue_length_. 286 // There is no need for a mutex when reading input_queue_length_.
255 while (input_queue_length_ > 0) CompileNext(); 287 while (input_queue_length_ > 0) CompileNext(NextInput());
256 InstallOptimizedFunctions(); 288 InstallOptimizedFunctions();
257 } else { 289 } else {
258 FlushInputQueue(false); 290 FlushInputQueue(false);
259 FlushOutputQueue(false); 291 FlushOutputQueue(false);
260 } 292 }
261 293
262 if (FLAG_concurrent_osr) FlushOsrBuffer(false); 294 if (FLAG_concurrent_osr) FlushOsrBuffer(false);
263 295
264 if (tracing_enabled_) { 296 if (tracing_enabled_) {
265 double percentage = time_spent_compiling_.PercentOf(time_spent_total_); 297 double percentage = time_spent_compiling_.PercentOf(time_spent_total_);
298 if (job_based_recompilation_) percentage = 100.0;
266 PrintF(" ** Compiler thread did %.2f%% useful work\n", percentage); 299 PrintF(" ** Compiler thread did %.2f%% useful work\n", percentage);
267 } 300 }
268 301
269 if ((FLAG_trace_osr || tracing_enabled_) && FLAG_concurrent_osr) { 302 if ((FLAG_trace_osr || tracing_enabled_) && FLAG_concurrent_osr) {
270 PrintF("[COSR hit rate %d / %d]\n", osr_hits_, osr_attempts_); 303 PrintF("[COSR hit rate %d / %d]\n", osr_hits_, osr_attempts_);
271 } 304 }
272 305
273 Join(); 306 Join();
274 } 307 }
275 308
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 input_queue_shift_ = InputQueueIndex(input_queue_capacity_ - 1); 359 input_queue_shift_ = InputQueueIndex(input_queue_capacity_ - 1);
327 input_queue_[InputQueueIndex(0)] = job; 360 input_queue_[InputQueueIndex(0)] = job;
328 input_queue_length_++; 361 input_queue_length_++;
329 } else { 362 } else {
330 // Add job to the back of the input queue. 363 // Add job to the back of the input queue.
331 base::LockGuard<base::Mutex> access_input_queue(&input_queue_mutex_); 364 base::LockGuard<base::Mutex> access_input_queue(&input_queue_mutex_);
332 DCHECK_LT(input_queue_length_, input_queue_capacity_); 365 DCHECK_LT(input_queue_length_, input_queue_capacity_);
333 input_queue_[InputQueueIndex(input_queue_length_)] = job; 366 input_queue_[InputQueueIndex(input_queue_length_)] = job;
334 input_queue_length_++; 367 input_queue_length_++;
335 } 368 }
336 if (job_based_recompilation_) { 369 if (FLAG_block_concurrent_recompilation) {
370 blocked_jobs_++;
371 } else if (job_based_recompilation_) {
372 base::LockGuard<base::RecursiveMutex> lock(&task_count_mutex_);
373 ++task_count_;
337 V8::GetCurrentPlatform()->CallOnBackgroundThread( 374 V8::GetCurrentPlatform()->CallOnBackgroundThread(
338 new CompileTask(isolate_, job), v8::Platform::kShortRunningTask); 375 new CompileTask(isolate_), v8::Platform::kShortRunningTask);
339 } else if (FLAG_block_concurrent_recompilation) {
340 blocked_jobs_++;
341 } else { 376 } else {
342 input_queue_semaphore_.Signal(); 377 input_queue_semaphore_.Signal();
343 } 378 }
344 } 379 }
345 380
346 381
347 void OptimizingCompilerThread::Unblock() { 382 void OptimizingCompilerThread::Unblock() {
348 DCHECK(!IsOptimizerThread()); 383 DCHECK(!IsOptimizerThread());
349 if (job_based_recompilation_) { 384 {
350 return; 385 base::LockGuard<base::RecursiveMutex> lock(&task_count_mutex_);
386 task_count_ += blocked_jobs_;
351 } 387 }
352 while (blocked_jobs_ > 0) { 388 while (blocked_jobs_ > 0) {
353 input_queue_semaphore_.Signal(); 389 if (job_based_recompilation_) {
390 V8::GetCurrentPlatform()->CallOnBackgroundThread(
391 new CompileTask(isolate_), v8::Platform::kShortRunningTask);
392 } else {
393 input_queue_semaphore_.Signal();
394 }
354 blocked_jobs_--; 395 blocked_jobs_--;
355 } 396 }
356 } 397 }
357 398
358 399
359 OptimizedCompileJob* OptimizingCompilerThread::FindReadyOSRCandidate( 400 OptimizedCompileJob* OptimizingCompilerThread::FindReadyOSRCandidate(
360 Handle<JSFunction> function, BailoutId osr_ast_id) { 401 Handle<JSFunction> function, BailoutId osr_ast_id) {
361 DCHECK(!IsOptimizerThread()); 402 DCHECK(!IsOptimizerThread());
362 for (int i = 0; i < osr_buffer_capacity_; i++) { 403 for (int i = 0; i < osr_buffer_capacity_; i++) {
363 OptimizedCompileJob* current = osr_buffer_[i]; 404 OptimizedCompileJob* current = osr_buffer_[i];
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 474
434 475
435 bool OptimizingCompilerThread::IsOptimizerThread() { 476 bool OptimizingCompilerThread::IsOptimizerThread() {
436 base::LockGuard<base::Mutex> lock_guard(&thread_id_mutex_); 477 base::LockGuard<base::Mutex> lock_guard(&thread_id_mutex_);
437 return ThreadId::Current().ToInteger() == thread_id_; 478 return ThreadId::Current().ToInteger() == thread_id_;
438 } 479 }
439 #endif 480 #endif
440 481
441 482
442 } } // namespace v8::internal 483 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/optimizing-compiler-thread.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698