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