1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_OPTIMIZING_COMPILER_THREAD_H_ 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_OPTIMIZING_COMPILER_THREAD_H_ 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/atomicops.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/platform/mutex.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/platform/platform.h" 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/platform/time.h" 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/flags.h" 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/list.h" 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/unbound-queue-inl.h" 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass HOptimizedGraphBuilder; 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass OptimizedCompileJob; 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass SharedFunctionInfo; 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass OptimizingCompilerThread : public base::Thread { 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit OptimizingCompilerThread(Isolate* isolate) 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Thread(Options("OptimizingCompilerThread")), 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch thread_id_(0), 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate_(isolate), 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stop_semaphore_(0), 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch input_queue_semaphore_(0), 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch input_queue_capacity_(FLAG_concurrent_recompilation_queue_length), 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch input_queue_length_(0), 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch input_queue_shift_(0), 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch osr_buffer_capacity_(FLAG_concurrent_recompilation_queue_length + 4), 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch osr_buffer_cursor_(0), 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch osr_hits_(0), 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch osr_attempts_(0), 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch blocked_jobs_(0) { 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::NoBarrier_Store(&stop_thread_, 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static_cast<base::AtomicWord>(CONTINUE)); 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch input_queue_ = NewArray<OptimizedCompileJob*>(input_queue_capacity_); 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_concurrent_osr) { 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate and mark OSR buffer slots as empty. 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch osr_buffer_ = NewArray<OptimizedCompileJob*>(osr_buffer_capacity_); 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < osr_buffer_capacity_; i++) osr_buffer_[i] = NULL; 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~OptimizingCompilerThread(); 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Run(); 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Stop(); 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Flush(); 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void QueueForOptimization(OptimizedCompileJob* optimizing_compiler); 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Unblock(); 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void InstallOptimizedFunctions(); 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OptimizedCompileJob* FindReadyOSRCandidate(Handle<JSFunction> function, 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutId osr_ast_id); 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsQueuedForOSR(Handle<JSFunction> function, BailoutId osr_ast_id); 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsQueuedForOSR(JSFunction* function); 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline bool IsQueueAvailable() { 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::LockGuard<base::Mutex> access_input_queue(&input_queue_mutex_); 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return input_queue_length_ < input_queue_capacity_; 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline void AgeBufferedOsrJobs() { 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Advance cursor of the cyclic buffer to next empty slot or stale OSR job. 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Dispose said OSR job in the latter case. Calling this on every GC 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // should make sure that we do not hold onto stale jobs indefinitely. 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddToOsrBuffer(NULL); 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool Enabled(int max_available) { 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return (FLAG_concurrent_recompilation && max_available > 1); 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static bool IsOptimizerThread(Isolate* isolate); 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsOptimizerThread(); 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum StopFlag { CONTINUE, STOP, FLUSH }; 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void FlushInputQueue(bool restore_function_code); 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void FlushOutputQueue(bool restore_function_code); 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void FlushOsrBuffer(bool restore_function_code); 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CompileNext(); 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OptimizedCompileJob* NextInput(); 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Add a recompilation task for OSR to the cyclic buffer, awaiting OSR entry. 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Tasks evicted from the cyclic buffer are discarded. 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddToOsrBuffer(OptimizedCompileJob* compiler); 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch inline int InputQueueIndex(int i) { 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int result = (i + input_queue_shift_) % input_queue_capacity_; 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_LE(0, result); 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_LT(result, input_queue_capacity_); 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int thread_id_; 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::Mutex thread_id_mutex_; 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate_; 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::Semaphore stop_semaphore_; 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::Semaphore input_queue_semaphore_; 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Circular queue of incoming recompilation tasks (including OSR). 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OptimizedCompileJob** input_queue_; 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int input_queue_capacity_; 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int input_queue_length_; 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int input_queue_shift_; 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::Mutex input_queue_mutex_; 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Queue of recompilation tasks ready to be installed (excluding OSR). 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnboundQueue<OptimizedCompileJob*> output_queue_; 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Cyclic buffer of recompilation tasks for OSR. 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OptimizedCompileJob** osr_buffer_; 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int osr_buffer_capacity_; 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int osr_buffer_cursor_; 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch volatile base::AtomicWord stop_thread_; 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::TimeDelta time_spent_compiling_; 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::TimeDelta time_spent_total_; 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int osr_hits_; 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int osr_attempts_; 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int blocked_jobs_; 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} } // namespace v8::internal 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_OPTIMIZING_COMPILER_THREAD_H_ 143