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/allocation.h"
11 #include "src/base/atomicops.h"
12 #include "src/base/platform/condition-variable.h"
13 #include "src/base/platform/mutex.h"
14 #include "src/base/platform/platform.h"
15 #include "src/flags.h"
16 #include "src/globals.h"
17 
18 namespace v8 {
19 namespace internal {
20 
21 class OptimizedCompilationJob;
22 class SharedFunctionInfo;
23 
24 class V8_EXPORT_PRIVATE OptimizingCompileDispatcher {
25  public:
OptimizingCompileDispatcher(Isolate * isolate)26   explicit OptimizingCompileDispatcher(Isolate* isolate)
27       : isolate_(isolate),
28         input_queue_capacity_(FLAG_concurrent_recompilation_queue_length),
29         input_queue_length_(0),
30         input_queue_shift_(0),
31         blocked_jobs_(0),
32         ref_count_(0),
33         recompilation_delay_(FLAG_concurrent_recompilation_delay) {
34     base::Relaxed_Store(&mode_, static_cast<base::AtomicWord>(COMPILE));
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 Unblock();
45   void InstallOptimizedFunctions();
46 
IsQueueAvailable()47   inline bool IsQueueAvailable() {
48     base::LockGuard<base::Mutex> 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  private:
55   class CompileTask;
56 
57   enum ModeFlag { COMPILE, FLUSH };
58 
59   void FlushOutputQueue(bool restore_function_code);
60   void CompileNext(OptimizedCompilationJob* job);
61   OptimizedCompilationJob* NextInput(bool check_if_flushing = false);
62 
InputQueueIndex(int i)63   inline int InputQueueIndex(int i) {
64     int result = (i + input_queue_shift_) % input_queue_capacity_;
65     DCHECK_LE(0, result);
66     DCHECK_LT(result, input_queue_capacity_);
67     return result;
68   }
69 
70   Isolate* isolate_;
71 
72   // Circular queue of incoming recompilation tasks (including OSR).
73   OptimizedCompilationJob** input_queue_;
74   int input_queue_capacity_;
75   int input_queue_length_;
76   int input_queue_shift_;
77   base::Mutex input_queue_mutex_;
78 
79   // Queue of recompilation tasks ready to be installed (excluding OSR).
80   std::queue<OptimizedCompilationJob*> output_queue_;
81   // Used for job based recompilation which has multiple producers on
82   // different threads.
83   base::Mutex output_queue_mutex_;
84 
85   volatile base::AtomicWord mode_;
86 
87   int blocked_jobs_;
88 
89   int ref_count_;
90   base::Mutex ref_count_mutex_;
91   base::ConditionVariable ref_count_zero_;
92 
93   // Copy of FLAG_concurrent_recompilation_delay that will be used from the
94   // background thread.
95   //
96   // Since flags might get modified while the background thread is running, it
97   // is not safe to access them directly.
98   int recompilation_delay_;
99 };
100 }  // namespace internal
101 }  // namespace v8
102 
103 #endif  // V8_COMPILER_DISPATCHER_OPTIMIZING_COMPILE_DISPATCHER_H_
104