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 <atomic> 9 #include <queue> 10 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/common/globals.h" 15 #include "src/flags/flags.h" 16 #include "src/utils/allocation.h" 17 18 namespace v8 { 19 namespace internal { 20 21 class OptimizedCompilationJob; 22 class RuntimeCallStats; 23 class SharedFunctionInfo; 24 25 class V8_EXPORT_PRIVATE OptimizingCompileDispatcher { 26 public: 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 mode_(COMPILE), 33 blocked_jobs_(0), 34 ref_count_(0), 35 recompilation_delay_(FLAG_concurrent_recompilation_delay) { 36 input_queue_ = NewArray<OptimizedCompilationJob*>(input_queue_capacity_); 37 } 38 39 ~OptimizingCompileDispatcher(); 40 41 void Stop(); 42 void Flush(BlockingBehavior blocking_behavior); 43 // Takes ownership of |job|. 44 void QueueForOptimization(OptimizedCompilationJob* job); 45 void Unblock(); 46 void InstallOptimizedFunctions(); 47 IsQueueAvailable()48 inline bool IsQueueAvailable() { 49 base::MutexGuard 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(OptimizedCompilationJob* job, RuntimeCallStats* stats); 62 OptimizedCompilationJob* 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 OptimizedCompilationJob** 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<OptimizedCompilationJob*> output_queue_; 82 // Used for job based recompilation which has multiple producers on 83 // different threads. 84 base::Mutex output_queue_mutex_; 85 86 std::atomic<ModeFlag> 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