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 // Clients of this interface shouldn't depend on lots of interpreter internals.
      9 // Do not include anything from src/interpreter other than
     10 // src/interpreter/bytecodes.h here!
     11 #include "src/base/macros.h"
     12 #include "src/builtins.h"
     13 #include "src/interpreter/bytecodes.h"
     14 #include "src/parsing/token.h"
     15 #include "src/runtime/runtime.h"
     16 
     17 namespace v8 {
     18 namespace internal {
     19 
     20 class Isolate;
     21 class Callable;
     22 class CompilationInfo;
     23 
     24 namespace compiler {
     25 class Node;
     26 }  // namespace compiler
     27 
     28 namespace interpreter {
     29 
     30 class InterpreterAssembler;
     31 
     32 class Interpreter {
     33  public:
     34   explicit Interpreter(Isolate* isolate);
     35   virtual ~Interpreter() {}
     36 
     37   // Initializes the interpreter dispatch table.
     38   void Initialize();
     39 
     40   // Returns the interrupt budget which should be used for the profiler counter.
     41   static int InterruptBudget();
     42 
     43   // Generate bytecode for |info|.
     44   static bool MakeBytecode(CompilationInfo* info);
     45 
     46   // Return bytecode handler for |bytecode|.
     47   Code* GetBytecodeHandler(Bytecode bytecode, OperandScale operand_scale);
     48 
     49   // GC support.
     50   void IterateDispatchTable(ObjectVisitor* v);
     51 
     52   // Disassembler support (only useful with ENABLE_DISASSEMBLER defined).
     53   void TraceCodegen(Handle<Code> code);
     54   const char* LookupNameOfBytecodeHandler(Code* code);
     55 
     56   Local<v8::Object> GetDispatchCountersObject();
     57 
     58   Address dispatch_table_address() {
     59     return reinterpret_cast<Address>(&dispatch_table_[0]);
     60   }
     61 
     62   Address bytecode_dispatch_counters_table() {
     63     return reinterpret_cast<Address>(bytecode_dispatch_counters_table_.get());
     64   }
     65 
     66  private:
     67 // Bytecode handler generator functions.
     68 #define DECLARE_BYTECODE_HANDLER_GENERATOR(Name, ...) \
     69   void Do##Name(InterpreterAssembler* assembler);
     70   BYTECODE_LIST(DECLARE_BYTECODE_HANDLER_GENERATOR)
     71 #undef DECLARE_BYTECODE_HANDLER_GENERATOR
     72 
     73   // Generates code to perform the binary operation via |Generator|.
     74   template <class Generator>
     75   void DoBinaryOp(InterpreterAssembler* assembler);
     76 
     77   // Generates code to perform the unary operation via |callable|.
     78   void DoUnaryOp(Callable callable, InterpreterAssembler* assembler);
     79 
     80   // Generates code to perform the unary operation via |Generator|.
     81   template <class Generator>
     82   void DoUnaryOp(InterpreterAssembler* assembler);
     83 
     84   // Generates code to perform the comparison operation associated with
     85   // |compare_op|.
     86   void DoCompareOp(Token::Value compare_op, InterpreterAssembler* assembler);
     87 
     88   // Generates code to perform a global store via |ic|.
     89   void DoStaGlobal(Callable ic, InterpreterAssembler* assembler);
     90 
     91   // Generates code to perform a named property store via |ic|.
     92   void DoStoreIC(Callable ic, InterpreterAssembler* assembler);
     93 
     94   // Generates code to perform a keyed property store via |ic|.
     95   void DoKeyedStoreIC(Callable ic, InterpreterAssembler* assembler);
     96 
     97   // Generates code to perform a JS call.
     98   void DoJSCall(InterpreterAssembler* assembler, TailCallMode tail_call_mode);
     99 
    100   // Generates code to perform a runtime call.
    101   void DoCallRuntimeCommon(InterpreterAssembler* assembler);
    102 
    103   // Generates code to perform a runtime call returning a pair.
    104   void DoCallRuntimeForPairCommon(InterpreterAssembler* assembler);
    105 
    106   // Generates code to perform a JS runtime call.
    107   void DoCallJSRuntimeCommon(InterpreterAssembler* assembler);
    108 
    109   // Generates code to perform a constructor call.
    110   void DoCallConstruct(InterpreterAssembler* assembler);
    111 
    112   // Generates code to perform delete via function_id.
    113   void DoDelete(Runtime::FunctionId function_id,
    114                 InterpreterAssembler* assembler);
    115 
    116   // Generates code to perform a lookup slot load via |function_id|.
    117   void DoLdaLookupSlot(Runtime::FunctionId function_id,
    118                        InterpreterAssembler* assembler);
    119 
    120   // Generates code to perform a lookup slot store depending on |language_mode|.
    121   void DoStaLookupSlot(LanguageMode language_mode,
    122                        InterpreterAssembler* assembler);
    123 
    124   // Generates a node with the undefined constant.
    125   compiler::Node* BuildLoadUndefined(InterpreterAssembler* assembler);
    126 
    127   // Generates code to load a context slot.
    128   compiler::Node* BuildLoadContextSlot(InterpreterAssembler* assembler);
    129 
    130   // Generates code to load a global.
    131   compiler::Node* BuildLoadGlobal(Callable ic, InterpreterAssembler* assembler);
    132 
    133   // Generates code to load a named property.
    134   compiler::Node* BuildLoadNamedProperty(Callable ic,
    135                                          InterpreterAssembler* assembler);
    136 
    137   // Generates code to load a keyed property.
    138   compiler::Node* BuildLoadKeyedProperty(Callable ic,
    139                                          InterpreterAssembler* assembler);
    140 
    141   // Generates code to perform logical-not on boolean |value| and returns the
    142   // result.
    143   compiler::Node* BuildLogicalNot(compiler::Node* value,
    144                                   InterpreterAssembler* assembler);
    145 
    146   // Generates code to convert |value| to a boolean and returns the
    147   // result.
    148   compiler::Node* BuildToBoolean(compiler::Node* value,
    149                                  InterpreterAssembler* assembler);
    150 
    151   uintptr_t GetDispatchCounter(Bytecode from, Bytecode to) const;
    152 
    153   // Get dispatch table index of bytecode.
    154   static size_t GetDispatchTableIndex(Bytecode bytecode,
    155                                       OperandScale operand_scale);
    156 
    157   bool IsDispatchTableInitialized();
    158 
    159   static const int kNumberOfWideVariants = 3;
    160   static const int kDispatchTableSize = kNumberOfWideVariants * (kMaxUInt8 + 1);
    161   static const int kNumberOfBytecodes = static_cast<int>(Bytecode::kLast) + 1;
    162 
    163   Isolate* isolate_;
    164   Address dispatch_table_[kDispatchTableSize];
    165   v8::base::SmartArrayPointer<uintptr_t> bytecode_dispatch_counters_table_;
    166 
    167   DISALLOW_COPY_AND_ASSIGN(Interpreter);
    168 };
    169 
    170 }  // namespace interpreter
    171 }  // namespace internal
    172 }  // namespace v8
    173 
    174 #endif  // V8_INTERPRETER_INTERPRETER_H_
    175