OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/optimizing-compile-dispatcher.h" | 5 #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h" |
6 | 6 |
7 #include "src/base/atomicops.h" | 7 #include "src/base/atomicops.h" |
8 #include "src/full-codegen/full-codegen.h" | 8 #include "src/full-codegen/full-codegen.h" |
9 #include "src/isolate.h" | 9 #include "src/isolate.h" |
10 #include "src/tracing/trace-event.h" | 10 #include "src/tracing/trace-event.h" |
11 #include "src/v8.h" | 11 #include "src/v8.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 | 15 |
16 namespace { | 16 namespace { |
17 | 17 |
18 void DisposeCompilationJob(CompilationJob* job, bool restore_function_code) { | 18 void DisposeCompilationJob(CompilationJob* job, bool restore_function_code) { |
19 if (restore_function_code) { | 19 if (restore_function_code) { |
20 Handle<JSFunction> function = job->info()->closure(); | 20 Handle<JSFunction> function = job->info()->closure(); |
21 function->ReplaceCode(function->shared()->code()); | 21 function->ReplaceCode(function->shared()->code()); |
22 // TODO(mvstanton): We can't call ensureliterals here due to allocation, | 22 // TODO(mvstanton): We can't call ensureliterals here due to allocation, |
23 // but we probably shouldn't call ReplaceCode either, as this | 23 // but we probably shouldn't call ReplaceCode either, as this |
24 // sometimes runs on the worker thread! | 24 // sometimes runs on the worker thread! |
25 // JSFunction::EnsureLiterals(function); | 25 // JSFunction::EnsureLiterals(function); |
26 } | 26 } |
27 delete job; | 27 delete job; |
28 } | 28 } |
29 | 29 |
30 } // namespace | 30 } // namespace |
31 | 31 |
32 | |
33 class OptimizingCompileDispatcher::CompileTask : public v8::Task { | 32 class OptimizingCompileDispatcher::CompileTask : public v8::Task { |
34 public: | 33 public: |
35 explicit CompileTask(Isolate* isolate) : isolate_(isolate) { | 34 explicit CompileTask(Isolate* isolate) : isolate_(isolate) { |
36 OptimizingCompileDispatcher* dispatcher = | 35 OptimizingCompileDispatcher* dispatcher = |
37 isolate_->optimizing_compile_dispatcher(); | 36 isolate_->optimizing_compile_dispatcher(); |
38 base::LockGuard<base::Mutex> lock_guard(&dispatcher->ref_count_mutex_); | 37 base::LockGuard<base::Mutex> lock_guard(&dispatcher->ref_count_mutex_); |
39 ++dispatcher->ref_count_; | 38 ++dispatcher->ref_count_; |
40 } | 39 } |
41 | 40 |
42 virtual ~CompileTask() {} | 41 virtual ~CompileTask() {} |
(...skipping 26 matching lines...) Expand all Loading... |
69 dispatcher->ref_count_zero_.NotifyOne(); | 68 dispatcher->ref_count_zero_.NotifyOne(); |
70 } | 69 } |
71 } | 70 } |
72 } | 71 } |
73 | 72 |
74 Isolate* isolate_; | 73 Isolate* isolate_; |
75 | 74 |
76 DISALLOW_COPY_AND_ASSIGN(CompileTask); | 75 DISALLOW_COPY_AND_ASSIGN(CompileTask); |
77 }; | 76 }; |
78 | 77 |
79 | |
80 OptimizingCompileDispatcher::~OptimizingCompileDispatcher() { | 78 OptimizingCompileDispatcher::~OptimizingCompileDispatcher() { |
81 #ifdef DEBUG | 79 #ifdef DEBUG |
82 { | 80 { |
83 base::LockGuard<base::Mutex> lock_guard(&ref_count_mutex_); | 81 base::LockGuard<base::Mutex> lock_guard(&ref_count_mutex_); |
84 DCHECK_EQ(0, ref_count_); | 82 DCHECK_EQ(0, ref_count_); |
85 } | 83 } |
86 #endif | 84 #endif |
87 DCHECK_EQ(0, input_queue_length_); | 85 DCHECK_EQ(0, input_queue_length_); |
88 DeleteArray(input_queue_); | 86 DeleteArray(input_queue_); |
89 } | 87 } |
(...skipping 23 matching lines...) Expand all Loading... |
113 USE(status); // Prevent an unused-variable error. | 111 USE(status); // Prevent an unused-variable error. |
114 | 112 |
115 // The function may have already been optimized by OSR. Simply continue. | 113 // The function may have already been optimized by OSR. Simply continue. |
116 // Use a mutex to make sure that functions marked for install | 114 // Use a mutex to make sure that functions marked for install |
117 // are always also queued. | 115 // are always also queued. |
118 base::LockGuard<base::Mutex> access_output_queue_(&output_queue_mutex_); | 116 base::LockGuard<base::Mutex> access_output_queue_(&output_queue_mutex_); |
119 output_queue_.push(job); | 117 output_queue_.push(job); |
120 isolate_->stack_guard()->RequestInstallCode(); | 118 isolate_->stack_guard()->RequestInstallCode(); |
121 } | 119 } |
122 | 120 |
123 | |
124 void OptimizingCompileDispatcher::FlushOutputQueue(bool restore_function_code) { | 121 void OptimizingCompileDispatcher::FlushOutputQueue(bool restore_function_code) { |
125 for (;;) { | 122 for (;;) { |
126 CompilationJob* job = NULL; | 123 CompilationJob* job = NULL; |
127 { | 124 { |
128 base::LockGuard<base::Mutex> access_output_queue_(&output_queue_mutex_); | 125 base::LockGuard<base::Mutex> access_output_queue_(&output_queue_mutex_); |
129 if (output_queue_.empty()) return; | 126 if (output_queue_.empty()) return; |
130 job = output_queue_.front(); | 127 job = output_queue_.front(); |
131 output_queue_.pop(); | 128 output_queue_.pop(); |
132 } | 129 } |
133 | 130 |
134 DisposeCompilationJob(job, restore_function_code); | 131 DisposeCompilationJob(job, restore_function_code); |
135 } | 132 } |
136 } | 133 } |
137 | 134 |
138 | |
139 void OptimizingCompileDispatcher::Flush() { | 135 void OptimizingCompileDispatcher::Flush() { |
140 base::Release_Store(&mode_, static_cast<base::AtomicWord>(FLUSH)); | 136 base::Release_Store(&mode_, static_cast<base::AtomicWord>(FLUSH)); |
141 if (FLAG_block_concurrent_recompilation) Unblock(); | 137 if (FLAG_block_concurrent_recompilation) Unblock(); |
142 { | 138 { |
143 base::LockGuard<base::Mutex> lock_guard(&ref_count_mutex_); | 139 base::LockGuard<base::Mutex> lock_guard(&ref_count_mutex_); |
144 while (ref_count_ > 0) ref_count_zero_.Wait(&ref_count_mutex_); | 140 while (ref_count_ > 0) ref_count_zero_.Wait(&ref_count_mutex_); |
145 base::Release_Store(&mode_, static_cast<base::AtomicWord>(COMPILE)); | 141 base::Release_Store(&mode_, static_cast<base::AtomicWord>(COMPILE)); |
146 } | 142 } |
147 FlushOutputQueue(true); | 143 FlushOutputQueue(true); |
148 if (FLAG_trace_concurrent_recompilation) { | 144 if (FLAG_trace_concurrent_recompilation) { |
149 PrintF(" ** Flushed concurrent recompilation queues.\n"); | 145 PrintF(" ** Flushed concurrent recompilation queues.\n"); |
150 } | 146 } |
151 } | 147 } |
152 | 148 |
153 | |
154 void OptimizingCompileDispatcher::Stop() { | 149 void OptimizingCompileDispatcher::Stop() { |
155 base::Release_Store(&mode_, static_cast<base::AtomicWord>(FLUSH)); | 150 base::Release_Store(&mode_, static_cast<base::AtomicWord>(FLUSH)); |
156 if (FLAG_block_concurrent_recompilation) Unblock(); | 151 if (FLAG_block_concurrent_recompilation) Unblock(); |
157 { | 152 { |
158 base::LockGuard<base::Mutex> lock_guard(&ref_count_mutex_); | 153 base::LockGuard<base::Mutex> lock_guard(&ref_count_mutex_); |
159 while (ref_count_ > 0) ref_count_zero_.Wait(&ref_count_mutex_); | 154 while (ref_count_ > 0) ref_count_zero_.Wait(&ref_count_mutex_); |
160 base::Release_Store(&mode_, static_cast<base::AtomicWord>(COMPILE)); | 155 base::Release_Store(&mode_, static_cast<base::AtomicWord>(COMPILE)); |
161 } | 156 } |
162 | 157 |
163 if (recompilation_delay_ != 0) { | 158 if (recompilation_delay_ != 0) { |
164 // At this point the optimizing compiler thread's event loop has stopped. | 159 // At this point the optimizing compiler thread's event loop has stopped. |
165 // There is no need for a mutex when reading input_queue_length_. | 160 // There is no need for a mutex when reading input_queue_length_. |
166 while (input_queue_length_ > 0) CompileNext(NextInput()); | 161 while (input_queue_length_ > 0) CompileNext(NextInput()); |
167 InstallOptimizedFunctions(); | 162 InstallOptimizedFunctions(); |
168 } else { | 163 } else { |
169 FlushOutputQueue(false); | 164 FlushOutputQueue(false); |
170 } | 165 } |
171 } | 166 } |
172 | 167 |
173 | |
174 void OptimizingCompileDispatcher::InstallOptimizedFunctions() { | 168 void OptimizingCompileDispatcher::InstallOptimizedFunctions() { |
175 HandleScope handle_scope(isolate_); | 169 HandleScope handle_scope(isolate_); |
176 | 170 |
177 for (;;) { | 171 for (;;) { |
178 CompilationJob* job = NULL; | 172 CompilationJob* job = NULL; |
179 { | 173 { |
180 base::LockGuard<base::Mutex> access_output_queue_(&output_queue_mutex_); | 174 base::LockGuard<base::Mutex> access_output_queue_(&output_queue_mutex_); |
181 if (output_queue_.empty()) return; | 175 if (output_queue_.empty()) return; |
182 job = output_queue_.front(); | 176 job = output_queue_.front(); |
183 output_queue_.pop(); | 177 output_queue_.pop(); |
(...skipping 23 matching lines...) Expand all Loading... |
207 input_queue_length_++; | 201 input_queue_length_++; |
208 } | 202 } |
209 if (FLAG_block_concurrent_recompilation) { | 203 if (FLAG_block_concurrent_recompilation) { |
210 blocked_jobs_++; | 204 blocked_jobs_++; |
211 } else { | 205 } else { |
212 V8::GetCurrentPlatform()->CallOnBackgroundThread( | 206 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
213 new CompileTask(isolate_), v8::Platform::kShortRunningTask); | 207 new CompileTask(isolate_), v8::Platform::kShortRunningTask); |
214 } | 208 } |
215 } | 209 } |
216 | 210 |
217 | |
218 void OptimizingCompileDispatcher::Unblock() { | 211 void OptimizingCompileDispatcher::Unblock() { |
219 while (blocked_jobs_ > 0) { | 212 while (blocked_jobs_ > 0) { |
220 V8::GetCurrentPlatform()->CallOnBackgroundThread( | 213 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
221 new CompileTask(isolate_), v8::Platform::kShortRunningTask); | 214 new CompileTask(isolate_), v8::Platform::kShortRunningTask); |
222 blocked_jobs_--; | 215 blocked_jobs_--; |
223 } | 216 } |
224 } | 217 } |
225 | 218 |
226 | |
227 } // namespace internal | 219 } // namespace internal |
228 } // namespace v8 | 220 } // namespace v8 |
OLD | NEW |