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   typedef void (Interpreter::*BytecodeGeneratorFunc)(InterpreterAssembler*);
     80 
     81   // Generates handler for given |bytecode| and |operand_scale| using
     82   // |generator| and installs it into the dispatch table.
     83   void InstallBytecodeHandler(Zone* zone, Bytecode bytecode,
     84                               OperandScale operand_scale,
     85                               BytecodeGeneratorFunc generator);
     86 
     87   // Generates code to perform the binary operation via |Generator|.
     88   template <class Generator>
     89   void DoBinaryOpWithFeedback(InterpreterAssembler* assembler);
     90 
     91   // Generates code to perform the comparison via |Generator| while gathering
     92   // type feedback.
     93   void DoCompareOpWithFeedback(Token::Value compare_op,
     94                                InterpreterAssembler* assembler);
     95 
     96   // Generates code to perform the bitwise binary operation corresponding to
     97   // |bitwise_op| while gathering type feedback.
     98   void DoBitwiseBinaryOp(Token::Value bitwise_op,
     99                          InterpreterAssembler* assembler);
    100 
    101   // Generates code to perform the binary operation via |Generator| using
    102   // an immediate value rather the accumulator as the rhs operand.
    103   template <class Generator>
    104   void DoBinaryOpWithImmediate(InterpreterAssembler* assembler);
    105 
    106   // Generates code to perform the unary operation via |Generator| while
    107   // gatering type feedback.
    108   template <class Generator>
    109   void DoUnaryOpWithFeedback(InterpreterAssembler* assembler);
    110 
    111   // Generates code to perform the comparison operation associated with
    112   // |compare_op|.
    113   void DoCompareOp(Token::Value compare_op, InterpreterAssembler* assembler);
    114 
    115   // Generates code to perform a global store via |ic|.
    116   void DoStaGlobal(Callable ic, InterpreterAssembler* assembler);
    117 
    118   // Generates code to perform a named property store via |ic|.
    119   void DoStoreIC(Callable ic, InterpreterAssembler* assembler);
    120 
    121   // Generates code to perform a keyed property store via |ic|.
    122   void DoKeyedStoreIC(Callable ic, InterpreterAssembler* assembler);
    123 
    124   // Generates code to perform a JS call that collects type feedback.
    125   void DoJSCall(InterpreterAssembler* assembler, TailCallMode tail_call_mode);
    126 
    127   // Generates code to perform delete via function_id.
    128   void DoDelete(Runtime::FunctionId function_id,
    129                 InterpreterAssembler* assembler);
    130 
    131   // Generates code to perform a lookup slot load via |function_id|.
    132   void DoLdaLookupSlot(Runtime::FunctionId function_id,
    133                        InterpreterAssembler* assembler);
    134 
    135   // Generates code to perform a lookup slot load via |function_id| that can
    136   // fast path to a context slot load.
    137   void DoLdaLookupContextSlot(Runtime::FunctionId function_id,
    138                               InterpreterAssembler* assembler);
    139 
    140   // Generates code to perform a lookup slot load via |function_id| that can
    141   // fast path to a global load.
    142   void DoLdaLookupGlobalSlot(Runtime::FunctionId function_id,
    143                              InterpreterAssembler* assembler);
    144 
    145   // Generates code to perform a lookup slot store depending on
    146   // |language_mode|.
    147   void DoStaLookupSlot(LanguageMode language_mode,
    148                        InterpreterAssembler* assembler);
    149 
    150   // Generates code to load a global.
    151   void BuildLoadGlobal(int slot_operand_index, int name_operand_index,
    152                        TypeofMode typeof_mode, InterpreterAssembler* assembler);
    153 
    154   // Generates code to prepare the result for ForInPrepare. Cache data
    155   // are placed into the consecutive series of registers starting at
    156   // |output_register|.
    157   void BuildForInPrepareResult(compiler::Node* output_register,
    158                                compiler::Node* cache_type,
    159                                compiler::Node* cache_array,
    160                                compiler::Node* cache_length,
    161                                InterpreterAssembler* assembler);
    162 
    163   // Generates code to perform the unary operation via |callable|.
    164   compiler::Node* BuildUnaryOp(Callable callable,
    165                                InterpreterAssembler* assembler);
    166 
    167   uintptr_t GetDispatchCounter(Bytecode from, Bytecode to) const;
    168 
    169   // Get dispatch table index of bytecode.
    170   static size_t GetDispatchTableIndex(Bytecode bytecode,
    171                                       OperandScale operand_scale);
    172 
    173   bool IsDispatchTableInitialized();
    174   bool ShouldInitializeDispatchTable();
    175 
    176   static const int kNumberOfWideVariants = 3;
    177   static const int kDispatchTableSize = kNumberOfWideVariants * (kMaxUInt8 + 1);
    178   static const int kNumberOfBytecodes = static_cast<int>(Bytecode::kLast) + 1;
    179 
    180   Isolate* isolate_;
    181   Address dispatch_table_[kDispatchTableSize];
    182   std::unique_ptr<uintptr_t[]> bytecode_dispatch_counters_table_;
    183 
    184   DISALLOW_COPY_AND_ASSIGN(Interpreter);
    185 };
    186 
    187 }  // namespace interpreter
    188 }  // namespace internal
    189 }  // namespace v8
    190 
    191 #endif  // V8_INTERPRETER_INTERPRETER_H_
    192