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

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

Issue 948863002: Get rid of recursive locks for job based recompilation (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: updates Created 5 years, 10 months 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"
(...skipping 24 matching lines...) Expand all
35 } 35 }
36 } 36 }
37 delete info; 37 delete info;
38 } 38 }
39 39
40 } // namespace 40 } // namespace
41 41
42 42
43 class OptimizingCompilerThread::CompileTask : public v8::Task { 43 class OptimizingCompilerThread::CompileTask : public v8::Task {
44 public: 44 public:
45 explicit CompileTask(Isolate* isolate) : isolate_(isolate) {} 45 explicit CompileTask(Isolate* isolate) : isolate_(isolate) {
46 base::NoBarrier_AtomicIncrement(
47 &isolate_->optimizing_compiler_thread()->ref_count_, 1);
48 }
46 49
47 virtual ~CompileTask() {} 50 virtual ~CompileTask() {}
48 51
49 private: 52 private:
50 // v8::Task overrides. 53 // v8::Task overrides.
51 void Run() OVERRIDE { 54 void Run() OVERRIDE {
52 DisallowHeapAllocation no_allocation; 55 DisallowHeapAllocation no_allocation;
53 DisallowHandleAllocation no_handles; 56 DisallowHandleAllocation no_handles;
54 DisallowHandleDereference no_deref; 57 DisallowHandleDereference no_deref;
55 58
56 OptimizingCompilerThread* thread = isolate_->optimizing_compiler_thread(); 59 OptimizingCompilerThread* thread = isolate_->optimizing_compiler_thread();
60 StopFlag flag = CONTINUE;
57 61
58 { 62 {
59 TimerEventScope<TimerEventRecompileConcurrent> timer(isolate_); 63 TimerEventScope<TimerEventRecompileConcurrent> timer(isolate_);
60 64
61 if (thread->recompilation_delay_ != 0) { 65 if (thread->recompilation_delay_ != 0) {
62 base::OS::Sleep(thread->recompilation_delay_); 66 base::OS::Sleep(thread->recompilation_delay_);
63 } 67 }
64 68
65 StopFlag flag;
66 OptimizedCompileJob* job = thread->NextInput(&flag); 69 OptimizedCompileJob* job = thread->NextInput(&flag);
67 70
68 if (flag == CONTINUE) { 71 switch (flag) {
69 thread->CompileNext(job); 72 case CONTINUE:
70 } else { 73 thread->CompileNext(job);
71 AllowHandleDereference allow_handle_dereference; 74 break;
72 if (!job->info()->is_osr()) { 75
73 DisposeOptimizedCompileJob(job, true); 76 case STOP:
77 case FLUSH: {
78 AllowHandleDereference allow_handle_dereference;
79 if (!job->info()->is_osr()) {
80 DisposeOptimizedCompileJob(job, true);
81 }
82 break;
74 } 83 }
75 } 84 }
76 } 85 }
86 if (flag == STOP) {
87 base::Release_Store(&thread->stop_thread_,
88 static_cast<base::AtomicWord>(CONTINUE));
89 thread->stop_semaphore_.Signal();
90 }
77 91
78 bool signal = false; 92 if (base::NoBarrier_AtomicIncrement(&thread->ref_count_, -1) == 0) {
79 { 93 thread->stop_semaphore_.Signal();
80 base::LockGuard<base::RecursiveMutex> lock(&thread->task_count_mutex_);
81 if (--thread->task_count_ == 0) {
82 if (static_cast<StopFlag>(base::Acquire_Load(&thread->stop_thread_)) ==
83 FLUSH) {
84 base::Release_Store(&thread->stop_thread_,
85 static_cast<base::AtomicWord>(CONTINUE));
86 signal = true;
87 }
88 }
89 } 94 }
90 if (signal) thread->stop_semaphore_.Signal();
91 } 95 }
92 96
93 Isolate* isolate_; 97 Isolate* isolate_;
94 98
95 DISALLOW_COPY_AND_ASSIGN(CompileTask); 99 DISALLOW_COPY_AND_ASSIGN(CompileTask);
96 }; 100 };
97 101
98 102
99 OptimizingCompilerThread::~OptimizingCompilerThread() { 103 OptimizingCompilerThread::~OptimizingCompilerThread() {
104 if (base::NoBarrier_AtomicIncrement(&ref_count_, -1) > 0) {
105 stop_semaphore_.Wait();
106 }
100 DCHECK_EQ(0, input_queue_length_); 107 DCHECK_EQ(0, input_queue_length_);
101 DeleteArray(input_queue_); 108 DeleteArray(input_queue_);
102 if (FLAG_concurrent_osr) { 109 if (FLAG_concurrent_osr) {
103 #ifdef DEBUG 110 #ifdef DEBUG
104 for (int i = 0; i < osr_buffer_capacity_; i++) { 111 for (int i = 0; i < osr_buffer_capacity_; i++) {
105 CHECK_NULL(osr_buffer_[i]); 112 CHECK_NULL(osr_buffer_[i]);
106 } 113 }
107 #endif 114 #endif
108 DeleteArray(osr_buffer_); 115 DeleteArray(osr_buffer_);
109 } 116 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 UNREACHABLE(); 182 UNREACHABLE();
176 *flag = CONTINUE; 183 *flag = CONTINUE;
177 } 184 }
178 return NULL; 185 return NULL;
179 } 186 }
180 OptimizedCompileJob* job = input_queue_[InputQueueIndex(0)]; 187 OptimizedCompileJob* job = input_queue_[InputQueueIndex(0)];
181 DCHECK_NOT_NULL(job); 188 DCHECK_NOT_NULL(job);
182 input_queue_shift_ = InputQueueIndex(1); 189 input_queue_shift_ = InputQueueIndex(1);
183 input_queue_length_--; 190 input_queue_length_--;
184 if (flag) { 191 if (flag) {
185 *flag = static_cast<StopFlag>(base::Acquire_Load(&stop_thread_)); 192 switch (static_cast<StopFlag>(base::Acquire_Load(&stop_thread_))) {
193 case CONTINUE:
194 *flag = CONTINUE;
195 break;
196
197 case FLUSH:
198 if (input_queue_length_ == 0) {
199 *flag = STOP;
200 } else {
201 *flag = FLUSH;
202 }
203 break;
204
205 case STOP:
206 UNREACHABLE();
207 *flag = CONTINUE;
208 break;
209 }
186 } 210 }
187 return job; 211 return job;
188 } 212 }
189 213
190 214
191 void OptimizingCompilerThread::CompileNext(OptimizedCompileJob* job) { 215 void OptimizingCompilerThread::CompileNext(OptimizedCompileJob* job) {
192 DCHECK_NOT_NULL(job); 216 DCHECK_NOT_NULL(job);
193 217
194 // The function may have already been optimized by OSR. Simply continue. 218 // The function may have already been optimized by OSR. Simply continue.
195 OptimizedCompileJob::Status status = job->OptimizeGraph(); 219 OptimizedCompileJob::Status status = job->OptimizeGraph();
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 osr_buffer_[i] = NULL; 264 osr_buffer_[i] = NULL;
241 } 265 }
242 } 266 }
243 } 267 }
244 268
245 269
246 void OptimizingCompilerThread::Flush() { 270 void OptimizingCompilerThread::Flush() {
247 DCHECK(!IsOptimizerThread()); 271 DCHECK(!IsOptimizerThread());
248 bool block = true; 272 bool block = true;
249 if (job_based_recompilation_) { 273 if (job_based_recompilation_) {
250 base::LockGuard<base::RecursiveMutex> lock(&task_count_mutex_); 274 if (FLAG_block_concurrent_recompilation) Unblock();
251 block = task_count_ > 0 || blocked_jobs_ > 0; 275 {
252 if (block) { 276 base::LockGuard<base::Mutex> lock(&input_queue_mutex_);
253 base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(FLUSH)); 277 block = input_queue_length_ > 0;
278 if (block) {
279 base::Release_Store(&stop_thread_,
280 static_cast<base::AtomicWord>(FLUSH));
281 }
254 } 282 }
255 if (FLAG_block_concurrent_recompilation) Unblock();
256 } else { 283 } else {
257 base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(FLUSH)); 284 base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(FLUSH));
258 if (FLAG_block_concurrent_recompilation) Unblock(); 285 if (FLAG_block_concurrent_recompilation) Unblock();
259 } 286 }
260 if (!job_based_recompilation_) input_queue_semaphore_.Signal(); 287 if (!job_based_recompilation_) input_queue_semaphore_.Signal();
261 if (block) stop_semaphore_.Wait(); 288 if (block) stop_semaphore_.Wait();
262 FlushOutputQueue(true); 289 FlushOutputQueue(true);
263 if (FLAG_concurrent_osr) FlushOsrBuffer(true); 290 if (FLAG_concurrent_osr) FlushOsrBuffer(true);
264 if (tracing_enabled_) { 291 if (tracing_enabled_) {
265 PrintF(" ** Flushed concurrent recompilation queues.\n"); 292 PrintF(" ** Flushed concurrent recompilation queues.\n");
266 } 293 }
267 } 294 }
268 295
269 296
270 void OptimizingCompilerThread::Stop() { 297 void OptimizingCompilerThread::Stop() {
271 DCHECK(!IsOptimizerThread()); 298 DCHECK(!IsOptimizerThread());
272 bool block = true; 299 bool block = true;
273 if (job_based_recompilation_) { 300 if (job_based_recompilation_) {
274 base::LockGuard<base::RecursiveMutex> lock(&task_count_mutex_); 301 if (FLAG_block_concurrent_recompilation) Unblock();
275 block = task_count_ > 0 || blocked_jobs_ > 0; 302 {
276 if (block) { 303 base::LockGuard<base::Mutex> lock(&input_queue_mutex_);
277 base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(FLUSH)); 304 block = input_queue_length_ > 0;
305 if (block) {
306 base::Release_Store(&stop_thread_,
307 static_cast<base::AtomicWord>(FLUSH));
308 }
278 } 309 }
279 if (FLAG_block_concurrent_recompilation) Unblock();
280 } else { 310 } else {
281 base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(STOP)); 311 base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(STOP));
282 if (FLAG_block_concurrent_recompilation) Unblock(); 312 if (FLAG_block_concurrent_recompilation) Unblock();
283 } 313 }
284 if (!job_based_recompilation_) input_queue_semaphore_.Signal(); 314 if (!job_based_recompilation_) input_queue_semaphore_.Signal();
285 if (block) stop_semaphore_.Wait(); 315 if (block) stop_semaphore_.Wait();
286 316
287 if (recompilation_delay_ != 0) { 317 if (recompilation_delay_ != 0) {
288 // At this point the optimizing compiler thread's event loop has stopped. 318 // At this point the optimizing compiler thread's event loop has stopped.
289 // There is no need for a mutex when reading input_queue_length_. 319 // There is no need for a mutex when reading input_queue_length_.
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 } else { 395 } else {
366 // Add job to the back of the input queue. 396 // Add job to the back of the input queue.
367 base::LockGuard<base::Mutex> access_input_queue(&input_queue_mutex_); 397 base::LockGuard<base::Mutex> access_input_queue(&input_queue_mutex_);
368 DCHECK_LT(input_queue_length_, input_queue_capacity_); 398 DCHECK_LT(input_queue_length_, input_queue_capacity_);
369 input_queue_[InputQueueIndex(input_queue_length_)] = job; 399 input_queue_[InputQueueIndex(input_queue_length_)] = job;
370 input_queue_length_++; 400 input_queue_length_++;
371 } 401 }
372 if (FLAG_block_concurrent_recompilation) { 402 if (FLAG_block_concurrent_recompilation) {
373 blocked_jobs_++; 403 blocked_jobs_++;
374 } else if (job_based_recompilation_) { 404 } else if (job_based_recompilation_) {
375 base::LockGuard<base::RecursiveMutex> lock(&task_count_mutex_);
376 ++task_count_;
377 V8::GetCurrentPlatform()->CallOnBackgroundThread( 405 V8::GetCurrentPlatform()->CallOnBackgroundThread(
378 new CompileTask(isolate_), v8::Platform::kShortRunningTask); 406 new CompileTask(isolate_), v8::Platform::kShortRunningTask);
379 } else { 407 } else {
380 input_queue_semaphore_.Signal(); 408 input_queue_semaphore_.Signal();
381 } 409 }
382 } 410 }
383 411
384 412
385 void OptimizingCompilerThread::Unblock() { 413 void OptimizingCompilerThread::Unblock() {
386 DCHECK(!IsOptimizerThread()); 414 DCHECK(!IsOptimizerThread());
387 {
388 base::LockGuard<base::RecursiveMutex> lock(&task_count_mutex_);
389 task_count_ += blocked_jobs_;
390 }
391 while (blocked_jobs_ > 0) { 415 while (blocked_jobs_ > 0) {
392 if (job_based_recompilation_) { 416 if (job_based_recompilation_) {
393 V8::GetCurrentPlatform()->CallOnBackgroundThread( 417 V8::GetCurrentPlatform()->CallOnBackgroundThread(
394 new CompileTask(isolate_), v8::Platform::kShortRunningTask); 418 new CompileTask(isolate_), v8::Platform::kShortRunningTask);
395 } else { 419 } else {
396 input_queue_semaphore_.Signal(); 420 input_queue_semaphore_.Signal();
397 } 421 }
398 blocked_jobs_--; 422 blocked_jobs_--;
399 } 423 }
400 } 424 }
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 501
478 502
479 bool OptimizingCompilerThread::IsOptimizerThread() { 503 bool OptimizingCompilerThread::IsOptimizerThread() {
480 base::LockGuard<base::Mutex> lock_guard(&thread_id_mutex_); 504 base::LockGuard<base::Mutex> lock_guard(&thread_id_mutex_);
481 return ThreadId::Current().ToInteger() == thread_id_; 505 return ThreadId::Current().ToInteger() == thread_id_;
482 } 506 }
483 #endif 507 #endif
484 508
485 509
486 } } // namespace v8::internal 510 } } // 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