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