Chromium Code Reviews| Index: src/optimizing-compiler-thread.cc |
| diff --git a/src/optimizing-compiler-thread.cc b/src/optimizing-compiler-thread.cc |
| index 21ef237107194d06a897110444c01710eae31bd0..d66c6bea94272d2eb9b136e3a9410a6e8cdd6eb6 100644 |
| --- a/src/optimizing-compiler-thread.cc |
| +++ b/src/optimizing-compiler-thread.cc |
| @@ -60,12 +60,23 @@ void OptimizingCompilerThread::Run() { |
| OS::Sleep(FLAG_parallel_recompilation_delay); |
| } |
| - if (Acquire_Load(&stop_thread_)) { |
| - stop_semaphore_->Signal(); |
| - if (FLAG_trace_parallel_recompilation) { |
| - time_spent_total_ = OS::Ticks() - epoch; |
| - } |
| - return; |
| + switch (static_cast<StopFlag>(Acquire_Load(&stop_thread_))) { |
| + case CONTINUE: |
| + break; |
| + case STOP: |
| + if (FLAG_trace_parallel_recompilation) { |
| + time_spent_total_ = OS::Ticks() - epoch; |
| + } |
| + stop_semaphore_->Signal(); |
| + return; |
| + case FLUSH: |
| + // Reset input queue semaphore. |
| + delete input_queue_semaphore_; |
| + input_queue_semaphore_ = OS::CreateSemaphore(0); |
| + // Signal for main thread to start flushing. |
| + stop_semaphore_->Signal(); |
| + // Return to start of consumer loop. |
| + continue; |
| } |
| int64_t compiling_start = 0; |
| @@ -102,9 +113,43 @@ void OptimizingCompilerThread::CompileNext() { |
| } |
| +void OptimizingCompilerThread::FlushQueue( |
| + UnboundQueue<OptimizingCompiler*>* queue, |
| + bool restore_function_code) { |
| + ASSERT(!IsOptimizerThread()); |
| + OptimizingCompiler* optimizing_compiler; |
| + // The optimizing compiler is allocated in the CompilationInfo's zone. |
| + while (queue->Dequeue(&optimizing_compiler)) { |
| + CompilationInfo* info = optimizing_compiler->info(); |
| + if (restore_function_code) { |
| + Handle<JSFunction> function = info->closure(); |
| + function->ReplaceCode(function->shared()->code()); |
| + } |
| + delete info; |
| + } |
| +} |
| + |
| + |
| +void OptimizingCompilerThread::Flush() { |
| + ASSERT(!IsOptimizerThread()); |
| + Release_Store(&stop_thread_, static_cast<AtomicWord>(FLUSH)); |
|
Michael Starzinger
2013/08/06 17:57:56
This is still racey, the FLUSH command might be ex
|
| + input_queue_semaphore_->Signal(); |
| + stop_semaphore_->Wait(); |
| + |
| + // At this point, the optimizing thread is idling. It is waiting for |
| + // the input semaphore, which has just been reset. It will not continue |
| + // as long as the input semaphore is not signaled (by the main thread). |
| + // Relying the input semaphore, we don't need any explicit memory barrier. |
| + FlushQueue(&input_queue_, true); |
| + FlushQueue(&output_queue_, true); |
| + NoBarrier_Store(&queue_length_, static_cast<AtomicWord>(0)); |
| + NoBarrier_Store(&stop_thread_, static_cast<AtomicWord>(CONTINUE)); |
| +} |
| + |
| + |
| void OptimizingCompilerThread::Stop() { |
| ASSERT(!IsOptimizerThread()); |
| - Release_Store(&stop_thread_, static_cast<AtomicWord>(true)); |
| + Release_Store(&stop_thread_, static_cast<AtomicWord>(STOP)); |
| input_queue_semaphore_->Signal(); |
| stop_semaphore_->Wait(); |
| @@ -114,14 +159,8 @@ void OptimizingCompilerThread::Stop() { |
| while (NoBarrier_Load(&queue_length_) > 0) CompileNext(); |
| InstallOptimizedFunctions(); |
| } else { |
| - OptimizingCompiler* optimizing_compiler; |
| - // The optimizing compiler is allocated in the CompilationInfo's zone. |
| - while (input_queue_.Dequeue(&optimizing_compiler)) { |
| - delete optimizing_compiler->info(); |
| - } |
| - while (output_queue_.Dequeue(&optimizing_compiler)) { |
| - delete optimizing_compiler->info(); |
| - } |
| + FlushQueue(&input_queue_, false); |
| + FlushQueue(&output_queue_, false); |
| } |
| if (FLAG_trace_parallel_recompilation) { |