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