OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 | 107 |
108 // The function may have already been optimized by OSR. Simply continue. | 108 // The function may have already been optimized by OSR. Simply continue. |
109 // Use a mutex to make sure that functions marked for install | 109 // Use a mutex to make sure that functions marked for install |
110 // are always also queued. | 110 // are always also queued. |
111 LockGuard<Mutex> access_queue(&queue_mutex_); | 111 LockGuard<Mutex> access_queue(&queue_mutex_); |
112 output_queue_.Enqueue(job); | 112 output_queue_.Enqueue(job); |
113 isolate_->stack_guard()->RequestInstallCode(); | 113 isolate_->stack_guard()->RequestInstallCode(); |
114 } | 114 } |
115 | 115 |
116 | 116 |
117 static void DisposeRecompileJob(RecompileJob* compiler, | 117 static void DisposeRecompileJob(RecompileJob* job, |
118 bool restore_function_code) { | 118 bool restore_function_code) { |
119 // The recompile job is allocated in the CompilationInfo's zone. | 119 // The recompile job is allocated in the CompilationInfo's zone. |
120 CompilationInfo* info = compiler->info(); | 120 CompilationInfo* info = job->info(); |
121 if (restore_function_code) { | 121 if (restore_function_code) { |
122 Handle<JSFunction> function = info->closure(); | 122 if (info->is_osr()) { |
123 function->ReplaceCode(function->shared()->code()); | 123 if (!job->IsWaitingForInstall()) BackEdgeTable::RemoveStackCheck(info); |
| 124 } else { |
| 125 Handle<JSFunction> function = info->closure(); |
| 126 function->ReplaceCode(function->shared()->code()); |
| 127 } |
124 } | 128 } |
125 delete info; | 129 delete info; |
126 } | 130 } |
127 | 131 |
128 | 132 |
129 void OptimizingCompilerThread::FlushInputQueue(bool restore_function_code) { | 133 void OptimizingCompilerThread::FlushInputQueue(bool restore_function_code) { |
130 RecompileJob* job; | 134 RecompileJob* job; |
131 while (input_queue_.Dequeue(&job)) { | 135 while (input_queue_.Dequeue(&job)) { |
132 // This should not block, since we have one signal on the input queue | 136 // This should not block, since we have one signal on the input queue |
133 // semaphore corresponding to each element in the input queue. | 137 // semaphore corresponding to each element in the input queue. |
134 input_queue_semaphore_.Wait(); | 138 input_queue_semaphore_.Wait(); |
135 if (job->info()->osr_ast_id().IsNone()) { | 139 // OSR jobs are dealt with separately. |
136 // OSR jobs are dealt with separately. | 140 if (!job->info()->is_osr()) { |
137 DisposeRecompileJob(job, restore_function_code); | 141 DisposeRecompileJob(job, restore_function_code); |
138 } | 142 } |
139 } | 143 } |
140 Release_Store(&queue_length_, static_cast<AtomicWord>(0)); | 144 Release_Store(&queue_length_, static_cast<AtomicWord>(0)); |
141 } | 145 } |
142 | 146 |
143 | 147 |
144 void OptimizingCompilerThread::FlushOutputQueue(bool restore_function_code) { | 148 void OptimizingCompilerThread::FlushOutputQueue(bool restore_function_code) { |
145 RecompileJob* job; | 149 RecompileJob* job; |
146 while (true) { | 150 while (true) { |
147 { LockGuard<Mutex> access_queue(&queue_mutex_); | 151 { LockGuard<Mutex> access_queue(&queue_mutex_); |
148 if (!output_queue_.Dequeue(&job)) break; | 152 if (!output_queue_.Dequeue(&job)) break; |
149 } | 153 } |
150 if (job->info()->osr_ast_id().IsNone()) { | 154 // OSR jobs are dealt with separately. |
151 // OSR jobs are dealt with separately. | 155 if (!job->info()->is_osr()) { |
152 DisposeRecompileJob(job, restore_function_code); | 156 DisposeRecompileJob(job, restore_function_code); |
153 } | 157 } |
154 } | 158 } |
155 } | 159 } |
156 | 160 |
157 | 161 |
158 void OptimizingCompilerThread::FlushOsrBuffer(bool restore_function_code) { | 162 void OptimizingCompilerThread::FlushOsrBuffer(bool restore_function_code) { |
159 RecompileJob* job; | 163 RecompileJob* job; |
160 for (int i = 0; i < osr_buffer_size_; i++) { | 164 for (int i = 0; i < osr_buffer_size_; i++) { |
161 job = osr_buffer_[i]; | 165 job = osr_buffer_[i]; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 void OptimizingCompilerThread::InstallOptimizedFunctions() { | 218 void OptimizingCompilerThread::InstallOptimizedFunctions() { |
215 ASSERT(!IsOptimizerThread()); | 219 ASSERT(!IsOptimizerThread()); |
216 HandleScope handle_scope(isolate_); | 220 HandleScope handle_scope(isolate_); |
217 | 221 |
218 RecompileJob* job; | 222 RecompileJob* job; |
219 while (true) { | 223 while (true) { |
220 { LockGuard<Mutex> access_queue(&queue_mutex_); | 224 { LockGuard<Mutex> access_queue(&queue_mutex_); |
221 if (!output_queue_.Dequeue(&job)) break; | 225 if (!output_queue_.Dequeue(&job)) break; |
222 } | 226 } |
223 CompilationInfo* info = job->info(); | 227 CompilationInfo* info = job->info(); |
224 if (info->osr_ast_id().IsNone()) { | 228 if (info->is_osr()) { |
225 Compiler::InstallOptimizedCode(job); | |
226 } else { | |
227 if (FLAG_trace_osr) { | 229 if (FLAG_trace_osr) { |
228 PrintF("[COSR - "); | 230 PrintF("[COSR - "); |
229 info->closure()->PrintName(); | 231 info->closure()->PrintName(); |
230 PrintF(" is ready for install and entry at AST id %d]\n", | 232 PrintF(" is ready for install and entry at AST id %d]\n", |
231 info->osr_ast_id().ToInt()); | 233 info->osr_ast_id().ToInt()); |
232 } | 234 } |
233 job->WaitForInstall(); | 235 job->WaitForInstall(); |
234 BackEdgeTable::RemoveStackCheck(info); | 236 BackEdgeTable::RemoveStackCheck(info); |
| 237 } else { |
| 238 Compiler::InstallOptimizedCode(job); |
235 } | 239 } |
236 } | 240 } |
237 } | 241 } |
238 | 242 |
239 | 243 |
240 void OptimizingCompilerThread::QueueForOptimization(RecompileJob* job) { | 244 void OptimizingCompilerThread::QueueForOptimization(RecompileJob* job) { |
241 ASSERT(IsQueueAvailable()); | 245 ASSERT(IsQueueAvailable()); |
242 ASSERT(!IsOptimizerThread()); | 246 ASSERT(!IsOptimizerThread()); |
243 Barrier_AtomicIncrement(&queue_length_, static_cast<Atomic32>(1)); | 247 Barrier_AtomicIncrement(&queue_length_, static_cast<Atomic32>(1)); |
244 CompilationInfo* info = job->info(); | 248 CompilationInfo* info = job->info(); |
245 if (info->osr_ast_id().IsNone()) { | 249 if (info->is_osr()) { |
246 info->closure()->MarkInRecompileQueue(); | |
247 } else { | |
248 if (FLAG_trace_concurrent_recompilation) { | 250 if (FLAG_trace_concurrent_recompilation) { |
249 PrintF(" ** Queueing "); | 251 PrintF(" ** Queueing "); |
250 info->closure()->PrintName(); | 252 info->closure()->PrintName(); |
251 PrintF(" for concurrent on-stack replacement.\n"); | 253 PrintF(" for concurrent on-stack replacement.\n"); |
252 } | 254 } |
253 AddToOsrBuffer(job); | 255 AddToOsrBuffer(job); |
254 osr_attempts_++; | 256 osr_attempts_++; |
255 BackEdgeTable::AddStackCheck(info); | 257 BackEdgeTable::AddStackCheck(info); |
| 258 } else { |
| 259 info->closure()->MarkInRecompileQueue(); |
256 } | 260 } |
257 input_queue_.Enqueue(job); | 261 input_queue_.Enqueue(job); |
258 input_queue_semaphore_.Signal(); | 262 input_queue_semaphore_.Signal(); |
259 } | 263 } |
260 | 264 |
261 | 265 |
262 RecompileJob* OptimizingCompilerThread::FindReadyOSRCandidate( | 266 RecompileJob* OptimizingCompilerThread::FindReadyOSRCandidate( |
263 Handle<JSFunction> function, uint32_t osr_pc_offset) { | 267 Handle<JSFunction> function, uint32_t osr_pc_offset) { |
264 ASSERT(!IsOptimizerThread()); | 268 ASSERT(!IsOptimizerThread()); |
265 RecompileJob* result = NULL; | 269 RecompileJob* result = NULL; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 while (true) { | 314 while (true) { |
311 stale = osr_buffer_[osr_cursor_]; | 315 stale = osr_buffer_[osr_cursor_]; |
312 if (stale == NULL) break; | 316 if (stale == NULL) break; |
313 if (stale->IsWaitingForInstall()) { | 317 if (stale->IsWaitingForInstall()) { |
314 CompilationInfo* info = stale->info(); | 318 CompilationInfo* info = stale->info(); |
315 if (FLAG_trace_osr) { | 319 if (FLAG_trace_osr) { |
316 PrintF("[COSR - Discarded "); | 320 PrintF("[COSR - Discarded "); |
317 info->closure()->PrintName(); | 321 info->closure()->PrintName(); |
318 PrintF(", AST id %d]\n", info->osr_ast_id().ToInt()); | 322 PrintF(", AST id %d]\n", info->osr_ast_id().ToInt()); |
319 } | 323 } |
320 BackEdgeTable::RemoveStackCheck(info); | |
321 DisposeRecompileJob(stale, false); | 324 DisposeRecompileJob(stale, false); |
322 break; | 325 break; |
323 } | 326 } |
324 AdvanceOsrCursor(); | 327 AdvanceOsrCursor(); |
325 } | 328 } |
326 | 329 |
327 osr_buffer_[osr_cursor_] = job; | 330 osr_buffer_[osr_cursor_] = job; |
328 AdvanceOsrCursor(); | 331 AdvanceOsrCursor(); |
329 } | 332 } |
330 | 333 |
331 | 334 |
332 #ifdef DEBUG | 335 #ifdef DEBUG |
333 bool OptimizingCompilerThread::IsOptimizerThread() { | 336 bool OptimizingCompilerThread::IsOptimizerThread() { |
334 if (!FLAG_concurrent_recompilation) return false; | 337 if (!FLAG_concurrent_recompilation) return false; |
335 LockGuard<Mutex> lock_guard(&thread_id_mutex_); | 338 LockGuard<Mutex> lock_guard(&thread_id_mutex_); |
336 return ThreadId::Current().ToInteger() == thread_id_; | 339 return ThreadId::Current().ToInteger() == thread_id_; |
337 } | 340 } |
338 #endif | 341 #endif |
339 | 342 |
340 | 343 |
341 } } // namespace v8::internal | 344 } } // namespace v8::internal |
OLD | NEW |