Line data Source code
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 :
28 60631 : 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 121262 : recompilation_delay_(FLAG_concurrent_recompilation_delay) {
36 60631 : base::NoBarrier_Store(&mode_, static_cast<base::AtomicWord>(COMPILE));
37 60631 : input_queue_ = NewArray<CompilationJob*>(input_queue_capacity_);
38 60631 : }
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 :
49 : inline bool IsQueueAvailable() {
50 51827 : base::LockGuard<base::Mutex> access_input_queue(&input_queue_mutex_);
51 51827 : return input_queue_length_ < input_queue_capacity_;
52 : }
53 :
54 60782 : 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 :
65 : inline int InputQueueIndex(int i) {
66 154959 : 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_
|