| OLD | NEW | 
|    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  Loading... | 
|   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  Loading... | 
|  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  Loading... | 
|  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 | 
| OLD | NEW |