1304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 4304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 5304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org#ifndef V8_OPTIMIZING_COMPILER_THREAD_H_ 6304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org#define V8_OPTIMIZING_COMPILER_THREAD_H_ 7304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 81e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org#include "src/base/atomicops.h" 95de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/platform/mutex.h" 105de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/platform/platform.h" 115de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/platform/time.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/flags.h" 13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/list.h" 14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/unbound-queue-inl.h" 15304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 16304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.orgnamespace v8 { 17304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.orgnamespace internal { 18304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 19a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass HOptimizedGraphBuilder; 204954674151afa960af66efb4831df06bde727333yangguo@chromium.orgclass OptimizedCompileJob; 21fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgclass SharedFunctionInfo; 22304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 235de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.orgclass OptimizingCompilerThread : public base::Thread { 24304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org public: 255e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org explicit OptimizingCompilerThread(Isolate* isolate) 265e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org : Thread(Options("OptimizingCompilerThread")), 271f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org#ifdef DEBUG 285e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org thread_id_(0), 291f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org#endif 305e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org isolate_(isolate), 315e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org stop_semaphore_(0), 325e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org input_queue_semaphore_(0), 335e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org input_queue_capacity_(FLAG_concurrent_recompilation_queue_length), 345e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org input_queue_length_(0), 355e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org input_queue_shift_(0), 365e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org osr_buffer_capacity_(FLAG_concurrent_recompilation_queue_length + 4), 375e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org osr_buffer_cursor_(0), 385e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org osr_hits_(0), 395e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org osr_attempts_(0), 405e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org blocked_jobs_(0) { 411e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org base::NoBarrier_Store(&stop_thread_, 421e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org static_cast<base::AtomicWord>(CONTINUE)); 434954674151afa960af66efb4831df06bde727333yangguo@chromium.org input_queue_ = NewArray<OptimizedCompileJob*>(input_queue_capacity_); 448e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org if (FLAG_concurrent_osr) { 452ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org // Allocate and mark OSR buffer slots as empty. 464954674151afa960af66efb4831df06bde727333yangguo@chromium.org osr_buffer_ = NewArray<OptimizedCompileJob*>(osr_buffer_capacity_); 472ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org for (int i = 0; i < osr_buffer_capacity_; i++) osr_buffer_[i] = NULL; 488e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org } 498e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org } 508e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 512ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org ~OptimizingCompilerThread(); 52304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 53304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org void Run(); 54304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org void Stop(); 55594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org void Flush(); 564954674151afa960af66efb4831df06bde727333yangguo@chromium.org void QueueForOptimization(OptimizedCompileJob* optimizing_compiler); 57a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org void Unblock(); 58304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org void InstallOptimizedFunctions(); 594954674151afa960af66efb4831df06bde727333yangguo@chromium.org OptimizedCompileJob* FindReadyOSRCandidate(Handle<JSFunction> function, 604954674151afa960af66efb4831df06bde727333yangguo@chromium.org BailoutId osr_ast_id); 614954674151afa960af66efb4831df06bde727333yangguo@chromium.org bool IsQueuedForOSR(Handle<JSFunction> function, BailoutId osr_ast_id); 623d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org 63e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org bool IsQueuedForOSR(JSFunction* function); 64304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 65304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org inline bool IsQueueAvailable() { 665de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::LockGuard<base::Mutex> access_input_queue(&input_queue_mutex_); 672ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org return input_queue_length_ < input_queue_capacity_; 682ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org } 692ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org 702ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org inline void AgeBufferedOsrJobs() { 712ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org // Advance cursor of the cyclic buffer to next empty slot or stale OSR job. 722ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org // Dispose said OSR job in the latter case. Calling this on every GC 732ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org // should make sure that we do not hold onto stale jobs indefinitely. 742ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org AddToOsrBuffer(NULL); 75304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 76304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 779af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org static bool Enabled(int max_available) { 789af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org return (FLAG_concurrent_recompilation && max_available > 1); 799af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org } 809af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 81304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org#ifdef DEBUG 829af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org static bool IsOptimizerThread(Isolate* isolate); 83304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org bool IsOptimizerThread(); 84304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org#endif 85304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 86304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org private: 87594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org enum StopFlag { CONTINUE, STOP, FLUSH }; 88594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 89594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org void FlushInputQueue(bool restore_function_code); 90594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org void FlushOutputQueue(bool restore_function_code); 918e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org void FlushOsrBuffer(bool restore_function_code); 92594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org void CompileNext(); 934954674151afa960af66efb4831df06bde727333yangguo@chromium.org OptimizedCompileJob* NextInput(); 94594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org 958e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // Add a recompilation task for OSR to the cyclic buffer, awaiting OSR entry. 968e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // Tasks evicted from the cyclic buffer are discarded. 974954674151afa960af66efb4831df06bde727333yangguo@chromium.org void AddToOsrBuffer(OptimizedCompileJob* compiler); 982ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org 992ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org inline int InputQueueIndex(int i) { 1002ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org int result = (i + input_queue_shift_) % input_queue_capacity_; 101e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_LE(0, result); 102e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_LT(result, input_queue_capacity_); 1032ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org return result; 1048e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org } 1058e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 1061f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org#ifdef DEBUG 1071f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org int thread_id_; 1085de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::Mutex thread_id_mutex_; 1091f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org#endif 1101f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 111304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org Isolate* isolate_; 1125de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::Semaphore stop_semaphore_; 1135de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::Semaphore input_queue_semaphore_; 1143d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org 1152ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org // Circular queue of incoming recompilation tasks (including OSR). 1164954674151afa960af66efb4831df06bde727333yangguo@chromium.org OptimizedCompileJob** input_queue_; 1172ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org int input_queue_capacity_; 1182ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org int input_queue_length_; 1192ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org int input_queue_shift_; 1205de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::Mutex input_queue_mutex_; 1212ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org 1223d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org // Queue of recompilation tasks ready to be installed (excluding OSR). 1234954674151afa960af66efb4831df06bde727333yangguo@chromium.org UnboundQueue<OptimizedCompileJob*> output_queue_; 1242ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org 1258e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // Cyclic buffer of recompilation tasks for OSR. 1264954674151afa960af66efb4831df06bde727333yangguo@chromium.org OptimizedCompileJob** osr_buffer_; 1272ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org int osr_buffer_capacity_; 1282ed0d029906d9c6f0ae06fe8eb7f1180077ae2b0mstarzinger@chromium.org int osr_buffer_cursor_; 1293d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org 1301e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org volatile base::AtomicWord stop_thread_; 1315de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::TimeDelta time_spent_compiling_; 1325de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::TimeDelta time_spent_total_; 1333d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org 1343d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org int osr_hits_; 1353d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org int osr_attempts_; 136a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org 137a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org int blocked_jobs_; 138304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org}; 139304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 140304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org} } // namespace v8::internal 141304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 142304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org#endif // V8_OPTIMIZING_COMPILER_THREAD_H_ 143