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/globals.h" 16 #include "src/list.h" 17 18 namespace v8 { 19 namespace internal { 20 21 class CompilationJob; 22 class SharedFunctionInfo; 23 24 class V8_EXPORT_PRIVATE OptimizingCompileDispatcher { 25 public: 26 enum class BlockingBehavior { kBlock, kDontBlock }; 27 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 blocked_jobs_(0), 34 ref_count_(0), 35 recompilation_delay_(FLAG_concurrent_recompilation_delay) { 36 base::NoBarrier_Store(&mode_, static_cast<base::AtomicWord>(COMPILE)); 37 input_queue_ = NewArray<CompilationJob*>(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(CompilationJob* job); 46 void Unblock(); 47 void InstallOptimizedFunctions(); 48 IsQueueAvailable()49 inline bool IsQueueAvailable() { 50 base::LockGuard<base::Mutex> 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(CompilationJob* job); 63 CompilationJob* NextInput(bool check_if_flushing = false); 64 InputQueueIndex(int i)65 inline int InputQueueIndex(int i) { 66 int result = (i + input_queue_shift_) % input_queue_capacity_; 67 DCHECK_LE(0, result); 68 DCHECK_LT(result, input_queue_capacity_); 69 return result; 70 } 71 72 Isolate* isolate_; 73 74 // Circular queue of incoming recompilation tasks (including OSR). 75 CompilationJob** input_queue_; 76 int input_queue_capacity_; 77 int input_queue_length_; 78 int input_queue_shift_; 79 base::Mutex input_queue_mutex_; 80 81 // Queue of recompilation tasks ready to be installed (excluding OSR). 82 std::queue<CompilationJob*> output_queue_; 83 // Used for job based recompilation which has multiple producers on 84 // different threads. 85 base::Mutex output_queue_mutex_; 86 87 volatile base::AtomicWord mode_; 88 89 int blocked_jobs_; 90 91 int ref_count_; 92 base::Mutex ref_count_mutex_; 93 base::ConditionVariable ref_count_zero_; 94 95 // Copy of FLAG_concurrent_recompilation_delay that will be used from the 96 // background thread. 97 // 98 // Since flags might get modified while the background thread is running, it 99 // is not safe to access them directly. 100 int recompilation_delay_; 101 }; 102 } // namespace internal 103 } // namespace v8 104 105 #endif // V8_COMPILER_DISPATCHER_OPTIMIZING_COMPILE_DISPATCHER_H_ 106