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 3 // found in the LICENSE file. 4 5 #ifndef V8_COMPILER_DISPATCHER_OPTIMIZING_COMPILE_DISPATCHER_H_ 6 #define V8_COMPILER_DISPATCHER_OPTIMIZING_COMPILE_DISPATCHER_H_ 7 8 #include <queue> 9 10 #include "src/allocation.h" 11 #include "src/base/atomicops.h" 12 #include "src/base/platform/condition-variable.h" 13 #include "src/base/platform/mutex.h" 14 #include "src/base/platform/platform.h" 15 #include "src/flags.h" 16 #include "src/globals.h" 17 18 namespace v8 { 19 namespace internal { 20 21 class OptimizedCompilationJob; 22 class SharedFunctionInfo; 23 24 class V8_EXPORT_PRIVATE OptimizingCompileDispatcher { 25 public: OptimizingCompileDispatcher(Isolate * isolate)26 explicit OptimizingCompileDispatcher(Isolate* isolate) 27 : isolate_(isolate), 28 input_queue_capacity_(FLAG_concurrent_recompilation_queue_length), 29 input_queue_length_(0), 30 input_queue_shift_(0), 31 blocked_jobs_(0), 32 ref_count_(0), 33 recompilation_delay_(FLAG_concurrent_recompilation_delay) { 34 base::Relaxed_Store(&mode_, static_cast<base::AtomicWord>(COMPILE)); 35 input_queue_ = NewArray<OptimizedCompilationJob*>(input_queue_capacity_); 36 } 37 38 ~OptimizingCompileDispatcher(); 39 40 void Stop(); 41 void Flush(BlockingBehavior blocking_behavior); 42 // Takes ownership of |job|. 43 void QueueForOptimization(OptimizedCompilationJob* job); 44 void Unblock(); 45 void InstallOptimizedFunctions(); 46 IsQueueAvailable()47 inline bool IsQueueAvailable() { 48 base::LockGuard<base::Mutex> access_input_queue(&input_queue_mutex_); 49 return input_queue_length_ < input_queue_capacity_; 50 } 51 Enabled()52 static bool Enabled() { return FLAG_concurrent_recompilation; } 53 54 private: 55 class CompileTask; 56 57 enum ModeFlag { COMPILE, FLUSH }; 58 59 void FlushOutputQueue(bool restore_function_code); 60 void CompileNext(OptimizedCompilationJob* job); 61 OptimizedCompilationJob* NextInput(bool check_if_flushing = false); 62 InputQueueIndex(int i)63 inline int InputQueueIndex(int i) { 64 int result = (i + input_queue_shift_) % input_queue_capacity_; 65 DCHECK_LE(0, result); 66 DCHECK_LT(result, input_queue_capacity_); 67 return result; 68 } 69 70 Isolate* isolate_; 71 72 // Circular queue of incoming recompilation tasks (including OSR). 73 OptimizedCompilationJob** input_queue_; 74 int input_queue_capacity_; 75 int input_queue_length_; 76 int input_queue_shift_; 77 base::Mutex input_queue_mutex_; 78 79 // Queue of recompilation tasks ready to be installed (excluding OSR). 80 std::queue<OptimizedCompilationJob*> output_queue_; 81 // Used for job based recompilation which has multiple producers on 82 // different threads. 83 base::Mutex output_queue_mutex_; 84 85 volatile base::AtomicWord mode_; 86 87 int blocked_jobs_; 88 89 int ref_count_; 90 base::Mutex ref_count_mutex_; 91 base::ConditionVariable ref_count_zero_; 92 93 // Copy of FLAG_concurrent_recompilation_delay that will be used from the 94 // background thread. 95 // 96 // Since flags might get modified while the background thread is running, it 97 // is not safe to access them directly. 98 int recompilation_delay_; 99 }; 100 } // namespace internal 101 } // namespace v8 102 103 #endif // V8_COMPILER_DISPATCHER_OPTIMIZING_COMPILE_DISPATCHER_H_ 104