Home | History | Annotate | Download | only in src
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 #ifndef V8_OPTIMIZING_COMPILER_THREAD_H_
     29 #define V8_OPTIMIZING_COMPILER_THREAD_H_
     30 
     31 #include "atomicops.h"
     32 #include "flags.h"
     33 #include "list.h"
     34 #include "platform.h"
     35 #include "platform/mutex.h"
     36 #include "platform/time.h"
     37 #include "unbound-queue-inl.h"
     38 
     39 namespace v8 {
     40 namespace internal {
     41 
     42 class HOptimizedGraphBuilder;
     43 class RecompileJob;
     44 class SharedFunctionInfo;
     45 
     46 class OptimizingCompilerThread : public Thread {
     47  public:
     48   explicit OptimizingCompilerThread(Isolate *isolate) :
     49       Thread("OptimizingCompilerThread"),
     50 #ifdef DEBUG
     51       thread_id_(0),
     52 #endif
     53       isolate_(isolate),
     54       stop_semaphore_(0),
     55       input_queue_semaphore_(0),
     56       input_queue_capacity_(FLAG_concurrent_recompilation_queue_length),
     57       input_queue_length_(0),
     58       input_queue_shift_(0),
     59       osr_buffer_capacity_(FLAG_concurrent_recompilation_queue_length + 4),
     60       osr_buffer_cursor_(0),
     61       osr_hits_(0),
     62       osr_attempts_(0),
     63       blocked_jobs_(0) {
     64     NoBarrier_Store(&stop_thread_, static_cast<AtomicWord>(CONTINUE));
     65     input_queue_ = NewArray<RecompileJob*>(input_queue_capacity_);
     66     if (FLAG_concurrent_osr) {
     67       // Allocate and mark OSR buffer slots as empty.
     68       osr_buffer_ = NewArray<RecompileJob*>(osr_buffer_capacity_);
     69       for (int i = 0; i < osr_buffer_capacity_; i++) osr_buffer_[i] = NULL;
     70     }
     71   }
     72 
     73   ~OptimizingCompilerThread();
     74 
     75   void Run();
     76   void Stop();
     77   void Flush();
     78   void QueueForOptimization(RecompileJob* optimizing_compiler);
     79   void Unblock();
     80   void InstallOptimizedFunctions();
     81   RecompileJob* FindReadyOSRCandidate(Handle<JSFunction> function,
     82                                       uint32_t osr_pc_offset);
     83   bool IsQueuedForOSR(Handle<JSFunction> function, uint32_t osr_pc_offset);
     84 
     85   bool IsQueuedForOSR(JSFunction* function);
     86 
     87   inline bool IsQueueAvailable() {
     88     LockGuard<Mutex> access_input_queue(&input_queue_mutex_);
     89     return input_queue_length_ < input_queue_capacity_;
     90   }
     91 
     92   inline void AgeBufferedOsrJobs() {
     93     // Advance cursor of the cyclic buffer to next empty slot or stale OSR job.
     94     // Dispose said OSR job in the latter case.  Calling this on every GC
     95     // should make sure that we do not hold onto stale jobs indefinitely.
     96     AddToOsrBuffer(NULL);
     97   }
     98 
     99   static bool Enabled(int max_available) {
    100     return (FLAG_concurrent_recompilation && max_available > 1);
    101   }
    102 
    103 #ifdef DEBUG
    104   static bool IsOptimizerThread(Isolate* isolate);
    105   bool IsOptimizerThread();
    106 #endif
    107 
    108  private:
    109   enum StopFlag { CONTINUE, STOP, FLUSH };
    110 
    111   void FlushInputQueue(bool restore_function_code);
    112   void FlushOutputQueue(bool restore_function_code);
    113   void FlushOsrBuffer(bool restore_function_code);
    114   void CompileNext();
    115   RecompileJob* NextInput();
    116 
    117   // Add a recompilation task for OSR to the cyclic buffer, awaiting OSR entry.
    118   // Tasks evicted from the cyclic buffer are discarded.
    119   void AddToOsrBuffer(RecompileJob* compiler);
    120 
    121   inline int InputQueueIndex(int i) {
    122     int result = (i + input_queue_shift_) % input_queue_capacity_;
    123     ASSERT_LE(0, result);
    124     ASSERT_LT(result, input_queue_capacity_);
    125     return result;
    126   }
    127 
    128 #ifdef DEBUG
    129   int thread_id_;
    130   Mutex thread_id_mutex_;
    131 #endif
    132 
    133   Isolate* isolate_;
    134   Semaphore stop_semaphore_;
    135   Semaphore input_queue_semaphore_;
    136 
    137   // Circular queue of incoming recompilation tasks (including OSR).
    138   RecompileJob** input_queue_;
    139   int input_queue_capacity_;
    140   int input_queue_length_;
    141   int input_queue_shift_;
    142   Mutex input_queue_mutex_;
    143 
    144   // Queue of recompilation tasks ready to be installed (excluding OSR).
    145   UnboundQueue<RecompileJob*> output_queue_;
    146 
    147   // Cyclic buffer of recompilation tasks for OSR.
    148   RecompileJob** osr_buffer_;
    149   int osr_buffer_capacity_;
    150   int osr_buffer_cursor_;
    151 
    152   volatile AtomicWord stop_thread_;
    153   TimeDelta time_spent_compiling_;
    154   TimeDelta time_spent_total_;
    155 
    156   int osr_hits_;
    157   int osr_attempts_;
    158 
    159   int blocked_jobs_;
    160 };
    161 
    162 } }  // namespace v8::internal
    163 
    164 #endif  // V8_OPTIMIZING_COMPILER_THREAD_H_
    165