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