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 TurbofanCompilationJob; 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 ref_count_(0), 34 recompilation_delay_(FLAG_concurrent_recompilation_delay) { 35 input_queue_ = NewArray<TurbofanCompilationJob*>(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(TurbofanCompilationJob* job); 44 void AwaitCompileTasks(); 45 void InstallOptimizedFunctions(); 46 IsQueueAvailable()47 inline bool IsQueueAvailable() { 48 base::MutexGuard 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 // This method must be called on the main thread. 55 bool HasJobs(); 56 57 // Whether to finalize and thus install the optimized code. Defaults to true. 58 // Only set to false for testing (where finalization is then manually 59 // requested using %FinalizeOptimization). finalize()60 bool finalize() const { return finalize_; } set_finalize(bool finalize)61 void set_finalize(bool finalize) { 62 CHECK(!HasJobs()); 63 finalize_ = finalize; 64 } 65 66 private: 67 class CompileTask; 68 69 enum ModeFlag { COMPILE, FLUSH }; 70 71 void FlushQueues(BlockingBehavior blocking_behavior, 72 bool restore_function_code); 73 void FlushInputQueue(); 74 void FlushOutputQueue(bool restore_function_code); 75 void CompileNext(TurbofanCompilationJob* job, LocalIsolate* local_isolate); 76 TurbofanCompilationJob* NextInput(LocalIsolate* local_isolate); 77 InputQueueIndex(int i)78 inline int InputQueueIndex(int i) { 79 int result = (i + input_queue_shift_) % input_queue_capacity_; 80 DCHECK_LE(0, result); 81 DCHECK_LT(result, input_queue_capacity_); 82 return result; 83 } 84 85 Isolate* isolate_; 86 87 // Circular queue of incoming recompilation tasks (including OSR). 88 TurbofanCompilationJob** input_queue_; 89 int input_queue_capacity_; 90 int input_queue_length_; 91 int input_queue_shift_; 92 base::Mutex input_queue_mutex_; 93 94 // Queue of recompilation tasks ready to be installed (excluding OSR). 95 std::queue<TurbofanCompilationJob*> output_queue_; 96 // Used for job based recompilation which has multiple producers on 97 // different threads. 98 base::Mutex output_queue_mutex_; 99 100 std::atomic<int> ref_count_; 101 base::Mutex ref_count_mutex_; 102 base::ConditionVariable ref_count_zero_; 103 104 // Copy of FLAG_concurrent_recompilation_delay that will be used from the 105 // background thread. 106 // 107 // Since flags might get modified while the background thread is running, it 108 // is not safe to access them directly. 109 int recompilation_delay_; 110 111 bool finalize_ = true; 112 }; 113 } // namespace internal 114 } // namespace v8 115 116 #endif // V8_COMPILER_DISPATCHER_OPTIMIZING_COMPILE_DISPATCHER_H_ 117