blob: 6ff4f2a61ab33adc74f228f24df5b8a49b40dae0 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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_OPTIMIZING_COMPILER_THREAD_H_
6#define V8_OPTIMIZING_COMPILER_THREAD_H_
7
8#include "src/base/atomicops.h"
9#include "src/base/platform/mutex.h"
10#include "src/base/platform/platform.h"
11#include "src/base/platform/time.h"
12#include "src/flags.h"
13#include "src/list.h"
14#include "src/unbound-queue-inl.h"
15
16namespace v8 {
17namespace internal {
18
19class HOptimizedGraphBuilder;
20class OptimizedCompileJob;
21class SharedFunctionInfo;
22
23class OptimizingCompilerThread : public base::Thread {
24 public:
25 explicit OptimizingCompilerThread(Isolate* isolate)
26 : Thread(Options("OptimizingCompilerThread")),
27#ifdef DEBUG
28 thread_id_(0),
29#endif
30 isolate_(isolate),
31 stop_semaphore_(0),
32 input_queue_semaphore_(0),
33 input_queue_capacity_(FLAG_concurrent_recompilation_queue_length),
34 input_queue_length_(0),
35 input_queue_shift_(0),
36 osr_buffer_capacity_(FLAG_concurrent_recompilation_queue_length + 4),
37 osr_buffer_cursor_(0),
38 osr_hits_(0),
39 osr_attempts_(0),
40 blocked_jobs_(0) {
41 base::NoBarrier_Store(&stop_thread_,
42 static_cast<base::AtomicWord>(CONTINUE));
43 input_queue_ = NewArray<OptimizedCompileJob*>(input_queue_capacity_);
44 if (FLAG_concurrent_osr) {
45 // Allocate and mark OSR buffer slots as empty.
46 osr_buffer_ = NewArray<OptimizedCompileJob*>(osr_buffer_capacity_);
47 for (int i = 0; i < osr_buffer_capacity_; i++) osr_buffer_[i] = NULL;
48 }
49 }
50
51 ~OptimizingCompilerThread();
52
53 void Run();
54 void Stop();
55 void Flush();
56 void QueueForOptimization(OptimizedCompileJob* optimizing_compiler);
57 void Unblock();
58 void InstallOptimizedFunctions();
59 OptimizedCompileJob* FindReadyOSRCandidate(Handle<JSFunction> function,
60 BailoutId osr_ast_id);
61 bool IsQueuedForOSR(Handle<JSFunction> function, BailoutId osr_ast_id);
62
63 bool IsQueuedForOSR(JSFunction* function);
64
65 inline bool IsQueueAvailable() {
66 base::LockGuard<base::Mutex> access_input_queue(&input_queue_mutex_);
67 return input_queue_length_ < input_queue_capacity_;
68 }
69
70 inline void AgeBufferedOsrJobs() {
71 // Advance cursor of the cyclic buffer to next empty slot or stale OSR job.
72 // Dispose said OSR job in the latter case. Calling this on every GC
73 // should make sure that we do not hold onto stale jobs indefinitely.
74 AddToOsrBuffer(NULL);
75 }
76
77 static bool Enabled(int max_available) {
78 return (FLAG_concurrent_recompilation && max_available > 1);
79 }
80
81#ifdef DEBUG
82 static bool IsOptimizerThread(Isolate* isolate);
83 bool IsOptimizerThread();
84#endif
85
86 private:
87 enum StopFlag { CONTINUE, STOP, FLUSH };
88
89 void FlushInputQueue(bool restore_function_code);
90 void FlushOutputQueue(bool restore_function_code);
91 void FlushOsrBuffer(bool restore_function_code);
92 void CompileNext();
93 OptimizedCompileJob* NextInput();
94
95 // Add a recompilation task for OSR to the cyclic buffer, awaiting OSR entry.
96 // Tasks evicted from the cyclic buffer are discarded.
97 void AddToOsrBuffer(OptimizedCompileJob* compiler);
98
99 inline int InputQueueIndex(int i) {
100 int result = (i + input_queue_shift_) % input_queue_capacity_;
101 DCHECK_LE(0, result);
102 DCHECK_LT(result, input_queue_capacity_);
103 return result;
104 }
105
106#ifdef DEBUG
107 int thread_id_;
108 base::Mutex thread_id_mutex_;
109#endif
110
111 Isolate* isolate_;
112 base::Semaphore stop_semaphore_;
113 base::Semaphore input_queue_semaphore_;
114
115 // Circular queue of incoming recompilation tasks (including OSR).
116 OptimizedCompileJob** input_queue_;
117 int input_queue_capacity_;
118 int input_queue_length_;
119 int input_queue_shift_;
120 base::Mutex input_queue_mutex_;
121
122 // Queue of recompilation tasks ready to be installed (excluding OSR).
123 UnboundQueue<OptimizedCompileJob*> output_queue_;
124
125 // Cyclic buffer of recompilation tasks for OSR.
126 OptimizedCompileJob** osr_buffer_;
127 int osr_buffer_capacity_;
128 int osr_buffer_cursor_;
129
130 volatile base::AtomicWord stop_thread_;
131 base::TimeDelta time_spent_compiling_;
132 base::TimeDelta time_spent_total_;
133
134 int osr_hits_;
135 int osr_attempts_;
136
137 int blocked_jobs_;
138};
139
140} } // namespace v8::internal
141
142#endif // V8_OPTIMIZING_COMPILER_THREAD_H_