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( |