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); ~Interpreter()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 dispatch_table_address()61 Address dispatch_table_address() { 62 return reinterpret_cast<Address>(&dispatch_table_[0]); 63 } 64 bytecode_dispatch_counters_table()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