Home | History | Annotate | Download | only in interpreter
      1 // Copyright 2015 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_INTERPRETER_INTERPRETER_H_
      6 #define V8_INTERPRETER_INTERPRETER_H_
      7 
      8 #include <memory>
      9 
     10 // Clients of this interface shouldn't depend on lots of interpreter internals.
     11 // Do not include anything from src/interpreter other than
     12 // src/interpreter/bytecodes.h here!
     13 #include "src/base/macros.h"
     14 #include "src/builtins/builtins.h"
     15 #include "src/interpreter/bytecodes.h"
     16 #include "src/parsing/token.h"
     17 #include "src/runtime/runtime.h"
     18 
     19 namespace v8 {
     20 namespace internal {
     21 
     22 class Isolate;
     23 class Callable;
     24 class CompilationInfo;
     25 class CompilationJob;
     26 
     27 namespace compiler {
     28 class Node;
     29 }  // namespace compiler
     30 
     31 namespace interpreter {
     32 
     33 class InterpreterAssembler;
     34 
     35 class Interpreter {
     36  public:
     37   explicit Interpreter(Isolate* isolate);
     38   virtual ~Interpreter() {}
     39 
     40   // Initializes the interpreter dispatch table.
     41   void Initialize();
     42 
     43   // Returns the interrupt budget which should be used for the profiler counter.
     44   static int InterruptBudget();
     45 
     46   // Creates a compilation job which will generate bytecode for |info|.
     47   static CompilationJob* NewCompilationJob(CompilationInfo* info);
     48 
     49   // Return bytecode handler for |bytecode|.
     50   Code* GetBytecodeHandler(Bytecode bytecode, OperandScale operand_scale);
     51 
     52   // GC support.
     53   void IterateDispatchTable(ObjectVisitor* v);
     54 
     55   // Disassembler support (only useful with ENABLE_DISASSEMBLER defined).
     56   void TraceCodegen(Handle<Code> code);
     57   const char* LookupNameOfBytecodeHandler(Code* code);
     58 
     59   V8_EXPORT_PRIVATE Local<v8::Object> GetDispatchCountersObject();
     60 
     61   Address dispatch_table_address() {
     62     return reinterpret_cast<Address>(&dispatch_table_[0]);
     63   }
     64 
     65   Address bytecode_dispatch_counters_table() {
     66     return reinterpret_cast<Address>(bytecode_dispatch_counters_table_.get());
     67   }
     68 
     69   // TODO(ignition): Tune code size multiplier.
     70   static const int kCodeSizeMultiplier = 32;
     71 
     72  private:
     73 // Bytecode handler generator functions.
     74 #define DECLARE_BYTECODE_HANDLER_GENERATOR(Name, ...) \
     75   void Do##Name(InterpreterAssembler* assembler);
     76   BYTECODE_LIST(DECLARE_BYTECODE_HANDLER_GENERATOR)
     77 #undef DECLARE_BYTECODE_HANDLER_GENERATOR
     78 
     79   // Generates code to perform the binary operation via |Generator|.
     80   template <class Generator>
     81   void DoBinaryOpWithFeedback(InterpreterAssembler* assembler);
     82 
     83   // Generates code to perform the comparison via |Generator| while gathering
     84   // type feedback.
     85   void DoCompareOpWithFeedback(Token::Value compare_op,
     86                                InterpreterAssembler* assembler);
     87 
     88   // Generates code to perform the bitwise binary operation corresponding to
     89   // |bitwise_op| while gathering type feedback.
     90   void DoBitwiseBinaryOp(Token::Value bitwise_op,
     91                          InterpreterAssembler* assembler);
     92 
     93   // Generates code to perform the binary operation via |Generator| using
     94   // an immediate value rather the accumulator as the rhs operand.
     95   template <class Generator>
     96   void DoBinaryOpWithImmediate(InterpreterAssembler* assembler);
     97 
     98   // Generates code to perform the unary operation via |Generator| while
     99   // gatering type feedback.
    100   template <class Generator>
    101   void DoUnaryOpWithFeedback(InterpreterAssembler* assembler);
    102 
    103   // Generates code to perform the comparison operation associated with
    104   // |compare_op|.
    105   void DoCompareOp(Token::Value compare_op, InterpreterAssembler* assembler);
    106 
    107   // Generates code to perform a global store via |ic|.
    108   void DoStaGlobal(Callable ic, InterpreterAssembler* assembler);
    109 
    110   // Generates code to perform a named property store via |ic|.
    111   void DoStoreIC(Callable ic, InterpreterAssembler* assembler);
    112 
    113   // Generates code to perform a keyed property store via |ic|.
    114   void DoKeyedStoreIC(Callable ic, InterpreterAssembler* assembler);
    115 
    116   // Generates code to perform a JS call that collects type feedback.
    117   void DoJSCall(InterpreterAssembler* assembler, TailCallMode tail_call_mode);
    118 
    119   // Generates code to perform delete via function_id.
    120   void DoDelete(Runtime::FunctionId function_id,
    121                 InterpreterAssembler* assembler);
    122 
    123   // Generates code to perform a lookup slot load via |function_id|.
    124   void DoLdaLookupSlot(Runtime::FunctionId function_id,
    125                        InterpreterAssembler* assembler);
    126 
    127   // Generates code to perform a lookup slot load via |function_id| that can
    128   // fast path to a context slot load.
    129   void DoLdaLookupContextSlot(Runtime::FunctionId function_id,
    130                               InterpreterAssembler* assembler);
    131 
    132   // Generates code to perform a lookup slot load via |function_id| that can
    133   // fast path to a global load.
    134   void DoLdaLookupGlobalSlot(Runtime::FunctionId function_id,
    135                              InterpreterAssembler* assembler);
    136 
    137   // Generates code to perform a lookup slot store depending on
    138   // |language_mode|.
    139   void DoStaLookupSlot(LanguageMode language_mode,
    140                        InterpreterAssembler* assembler);
    141 
    142   // Generates code to load a global.
    143   compiler::Node* BuildLoadGlobal(Callable ic, compiler::Node* context,
    144                                   compiler::Node* feedback_slot,
    145                                   InterpreterAssembler* assembler);
    146 
    147   // Generates code to prepare the result for ForInPrepare. Cache data
    148   // are placed into the consecutive series of registers starting at
    149   // |output_register|.
    150   void BuildForInPrepareResult(compiler::Node* output_register,
    151                                compiler::Node* cache_type,
    152                                compiler::Node* cache_array,
    153                                compiler::Node* cache_length,
    154                                InterpreterAssembler* assembler);
    155 
    156   // Generates code to perform the unary operation via |callable|.
    157   compiler::Node* BuildUnaryOp(Callable callable,
    158                                InterpreterAssembler* assembler);
    159 
    160   uintptr_t GetDispatchCounter(Bytecode from, Bytecode to) const;
    161 
    162   // Get dispatch table index of bytecode.
    163   static size_t GetDispatchTableIndex(Bytecode bytecode,
    164                                       OperandScale operand_scale);
    165 
    166   bool IsDispatchTableInitialized();
    167   bool ShouldInitializeDispatchTable();
    168 
    169   static const int kNumberOfWideVariants = 3;
    170   static const int kDispatchTableSize = kNumberOfWideVariants * (kMaxUInt8 + 1);
    171   static const int kNumberOfBytecodes = static_cast<int>(Bytecode::kLast) + 1;
    172 
    173   Isolate* isolate_;
    174   Address dispatch_table_[kDispatchTableSize];
    175   std::unique_ptr<uintptr_t[]> bytecode_dispatch_counters_table_;
    176 
    177   DISALLOW_COPY_AND_ASSIGN(Interpreter);
    178 };
    179 
    180 }  // namespace interpreter
    181 }  // namespace internal
    182 }  // namespace v8
    183 
    184 #endif  // V8_INTERPRETER_INTERPRETER_H_
    185