| 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 |