| Index: src/optimizing-compiler-thread.cc
 | 
| diff --git a/src/optimizing-compiler-thread.cc b/src/optimizing-compiler-thread.cc
 | 
| index 5999df9d6d724916c4c3d5d99f177e0e29c70a5c..153b618e438f8bf942bdb19bbff7a7417264cb8a 100644
 | 
| --- a/src/optimizing-compiler-thread.cc
 | 
| +++ b/src/optimizing-compiler-thread.cc
 | 
| @@ -42,7 +42,10 @@ void DisposeOptimizedCompileJob(OptimizedCompileJob* job,
 | 
|  
 | 
|  class OptimizingCompilerThread::CompileTask : public v8::Task {
 | 
|   public:
 | 
| -  explicit CompileTask(Isolate* isolate) : isolate_(isolate) {}
 | 
| +  explicit CompileTask(Isolate* isolate) : isolate_(isolate) {
 | 
| +    base::NoBarrier_AtomicIncrement(
 | 
| +        &isolate_->optimizing_compiler_thread()->ref_count_, 1);
 | 
| +  }
 | 
|  
 | 
|    virtual ~CompileTask() {}
 | 
|  
 | 
| @@ -54,6 +57,7 @@ class OptimizingCompilerThread::CompileTask : public v8::Task {
 | 
|      DisallowHandleDereference no_deref;
 | 
|  
 | 
|      OptimizingCompilerThread* thread = isolate_->optimizing_compiler_thread();
 | 
| +    StopFlag flag = CONTINUE;
 | 
|  
 | 
|      {
 | 
|        TimerEventScope<TimerEventRecompileConcurrent> timer(isolate_);
 | 
| @@ -62,32 +66,32 @@ class OptimizingCompilerThread::CompileTask : public v8::Task {
 | 
|          base::OS::Sleep(thread->recompilation_delay_);
 | 
|        }
 | 
|  
 | 
| -      StopFlag flag;
 | 
|        OptimizedCompileJob* job = thread->NextInput(&flag);
 | 
|  
 | 
| -      if (flag == CONTINUE) {
 | 
| -        thread->CompileNext(job);
 | 
| -      } else {
 | 
| -        AllowHandleDereference allow_handle_dereference;
 | 
| -        if (!job->info()->is_osr()) {
 | 
| -          DisposeOptimizedCompileJob(job, true);
 | 
| +      switch (flag) {
 | 
| +        case CONTINUE:
 | 
| +          thread->CompileNext(job);
 | 
| +          break;
 | 
| +
 | 
| +        case STOP:
 | 
| +        case FLUSH: {
 | 
| +          AllowHandleDereference allow_handle_dereference;
 | 
| +          if (!job->info()->is_osr()) {
 | 
| +            DisposeOptimizedCompileJob(job, true);
 | 
| +          }
 | 
| +          break;
 | 
|          }
 | 
|        }
 | 
|      }
 | 
| +    if (flag == STOP) {
 | 
| +      base::Release_Store(&thread->stop_thread_,
 | 
| +                          static_cast<base::AtomicWord>(CONTINUE));
 | 
| +      thread->stop_semaphore_.Signal();
 | 
| +    }
 | 
|  
 | 
| -    bool signal = false;
 | 
| -    {
 | 
| -      base::LockGuard<base::RecursiveMutex> lock(&thread->task_count_mutex_);
 | 
| -      if (--thread->task_count_ == 0) {
 | 
| -        if (static_cast<StopFlag>(base::Acquire_Load(&thread->stop_thread_)) ==
 | 
| -            FLUSH) {
 | 
| -          base::Release_Store(&thread->stop_thread_,
 | 
| -                              static_cast<base::AtomicWord>(CONTINUE));
 | 
| -          signal = true;
 | 
| -        }
 | 
| -      }
 | 
| +    if (base::NoBarrier_AtomicIncrement(&thread->ref_count_, -1) == 0) {
 | 
| +      thread->stop_semaphore_.Signal();
 | 
|      }
 | 
| -    if (signal) thread->stop_semaphore_.Signal();
 | 
|    }
 | 
|  
 | 
|    Isolate* isolate_;
 | 
| @@ -97,6 +101,9 @@ class OptimizingCompilerThread::CompileTask : public v8::Task {
 | 
|  
 | 
|  
 | 
|  OptimizingCompilerThread::~OptimizingCompilerThread() {
 | 
| +  if (base::NoBarrier_AtomicIncrement(&ref_count_, -1) > 0) {
 | 
| +    stop_semaphore_.Wait();
 | 
| +  }
 | 
|    DCHECK_EQ(0, input_queue_length_);
 | 
|    DeleteArray(input_queue_);
 | 
|    if (FLAG_concurrent_osr) {
 | 
| @@ -182,7 +189,24 @@ OptimizedCompileJob* OptimizingCompilerThread::NextInput(StopFlag* flag) {
 | 
|    input_queue_shift_ = InputQueueIndex(1);
 | 
|    input_queue_length_--;
 | 
|    if (flag) {
 | 
| -    *flag = static_cast<StopFlag>(base::Acquire_Load(&stop_thread_));
 | 
| +    switch (static_cast<StopFlag>(base::Acquire_Load(&stop_thread_))) {
 | 
| +      case CONTINUE:
 | 
| +        *flag = CONTINUE;
 | 
| +        break;
 | 
| +
 | 
| +      case FLUSH:
 | 
| +        if (input_queue_length_ == 0) {
 | 
| +          *flag = STOP;
 | 
| +        } else {
 | 
| +          *flag = FLUSH;
 | 
| +        }
 | 
| +        break;
 | 
| +
 | 
| +      case STOP:
 | 
| +        UNREACHABLE();
 | 
| +        *flag = CONTINUE;
 | 
| +        break;
 | 
| +    }
 | 
|    }
 | 
|    return job;
 | 
|  }
 | 
| @@ -247,12 +271,15 @@ void OptimizingCompilerThread::Flush() {
 | 
|    DCHECK(!IsOptimizerThread());
 | 
|    bool block = true;
 | 
|    if (job_based_recompilation_) {
 | 
| -    base::LockGuard<base::RecursiveMutex> lock(&task_count_mutex_);
 | 
| -    block = task_count_ > 0 || blocked_jobs_ > 0;
 | 
| -    if (block) {
 | 
| -      base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(FLUSH));
 | 
| -    }
 | 
|      if (FLAG_block_concurrent_recompilation) Unblock();
 | 
| +    {
 | 
| +      base::LockGuard<base::Mutex> lock(&input_queue_mutex_);
 | 
| +      block = input_queue_length_ > 0;
 | 
| +      if (block) {
 | 
| +        base::Release_Store(&stop_thread_,
 | 
| +                            static_cast<base::AtomicWord>(FLUSH));
 | 
| +      }
 | 
| +    }
 | 
|    } else {
 | 
|      base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(FLUSH));
 | 
|      if (FLAG_block_concurrent_recompilation) Unblock();
 | 
| @@ -271,12 +298,15 @@ void OptimizingCompilerThread::Stop() {
 | 
|    DCHECK(!IsOptimizerThread());
 | 
|    bool block = true;
 | 
|    if (job_based_recompilation_) {
 | 
| -    base::LockGuard<base::RecursiveMutex> lock(&task_count_mutex_);
 | 
| -    block = task_count_ > 0 || blocked_jobs_ > 0;
 | 
| -    if (block) {
 | 
| -      base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(FLUSH));
 | 
| -    }
 | 
|      if (FLAG_block_concurrent_recompilation) Unblock();
 | 
| +    {
 | 
| +      base::LockGuard<base::Mutex> lock(&input_queue_mutex_);
 | 
| +      block = input_queue_length_ > 0;
 | 
| +      if (block) {
 | 
| +        base::Release_Store(&stop_thread_,
 | 
| +                            static_cast<base::AtomicWord>(FLUSH));
 | 
| +      }
 | 
| +    }
 | 
|    } else {
 | 
|      base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(STOP));
 | 
|      if (FLAG_block_concurrent_recompilation) Unblock();
 | 
| @@ -372,8 +402,6 @@ void OptimizingCompilerThread::QueueForOptimization(OptimizedCompileJob* job) {
 | 
|    if (FLAG_block_concurrent_recompilation) {
 | 
|      blocked_jobs_++;
 | 
|    } else if (job_based_recompilation_) {
 | 
| -    base::LockGuard<base::RecursiveMutex> lock(&task_count_mutex_);
 | 
| -    ++task_count_;
 | 
|      V8::GetCurrentPlatform()->CallOnBackgroundThread(
 | 
|          new CompileTask(isolate_), v8::Platform::kShortRunningTask);
 | 
|    } else {
 | 
| @@ -384,10 +412,6 @@ void OptimizingCompilerThread::QueueForOptimization(OptimizedCompileJob* job) {
 | 
|  
 | 
|  void OptimizingCompilerThread::Unblock() {
 | 
|    DCHECK(!IsOptimizerThread());
 | 
| -  {
 | 
| -    base::LockGuard<base::RecursiveMutex> lock(&task_count_mutex_);
 | 
| -    task_count_ += blocked_jobs_;
 | 
| -  }
 | 
|    while (blocked_jobs_ > 0) {
 | 
|      if (job_based_recompilation_) {
 | 
|        V8::GetCurrentPlatform()->CallOnBackgroundThread(
 | 
| 
 |