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         ref_count_(0),
34         recompilation_delay_(FLAG_concurrent_recompilation_delay) {
35     input_queue_ = NewArray<OptimizedCompilationJob*>(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(OptimizedCompilationJob* 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(OptimizedCompilationJob* job, LocalIsolate* local_isolate);
76   OptimizedCompilationJob* 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   OptimizedCompilationJob** 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<OptimizedCompilationJob*> 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