• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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