summaryrefslogtreecommitdiff
path: root/deps/v8/src/interpreter/interpreter.h
blob: 04f7e85b39350d36431523eee791db47dd920ef1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_INTERPRETER_INTERPRETER_H_
#define V8_INTERPRETER_INTERPRETER_H_

#include <memory>

// Clients of this interface shouldn't depend on lots of interpreter internals.
// Do not include anything from src/interpreter other than
// src/interpreter/bytecodes.h here!
#include "src/base/macros.h"
#include "src/builtins/builtins.h"
#include "src/interpreter/bytecodes.h"
#include "src/parsing/token.h"
#include "src/runtime/runtime.h"

namespace v8 {
namespace internal {

class Isolate;
class Callable;
class CompilationInfo;
class CompilationJob;

namespace compiler {
class Node;
}  // namespace compiler

namespace interpreter {

class InterpreterAssembler;

class Interpreter {
 public:
  explicit Interpreter(Isolate* isolate);
  virtual ~Interpreter() {}

  // Initializes the interpreter dispatch table.
  void Initialize();

  // Returns the interrupt budget which should be used for the profiler counter.
  static int InterruptBudget();

  // Creates a compilation job which will generate bytecode for |info|.
  static CompilationJob* NewCompilationJob(CompilationInfo* info);

  // Return bytecode handler for |bytecode|.
  Code* GetBytecodeHandler(Bytecode bytecode, OperandScale operand_scale);

  // GC support.
  void IterateDispatchTable(ObjectVisitor* v);

  // Disassembler support (only useful with ENABLE_DISASSEMBLER defined).
  void TraceCodegen(Handle<Code> code);
  const char* LookupNameOfBytecodeHandler(Code* code);

  V8_EXPORT_PRIVATE Local<v8::Object> GetDispatchCountersObject();

  Address dispatch_table_address() {
    return reinterpret_cast<Address>(&dispatch_table_[0]);
  }

  Address bytecode_dispatch_counters_table() {
    return reinterpret_cast<Address>(bytecode_dispatch_counters_table_.get());
  }

  // TODO(ignition): Tune code size multiplier.
  static const int kCodeSizeMultiplier = 32;

 private:
// Bytecode handler generator functions.
#define DECLARE_BYTECODE_HANDLER_GENERATOR(Name, ...) \
  void Do##Name(InterpreterAssembler* assembler);
  BYTECODE_LIST(DECLARE_BYTECODE_HANDLER_GENERATOR)
#undef DECLARE_BYTECODE_HANDLER_GENERATOR

  typedef void (Interpreter::*BytecodeGeneratorFunc)(InterpreterAssembler*);

  // Generates handler for given |bytecode| and |operand_scale| using
  // |generator| and installs it into the dispatch table.
  void InstallBytecodeHandler(Zone* zone, Bytecode bytecode,
                              OperandScale operand_scale,
                              BytecodeGeneratorFunc generator);

  // Generates code to perform the binary operation via |Generator|.
  template <class Generator>
  void DoBinaryOpWithFeedback(InterpreterAssembler* assembler);

  // Generates code to perform the comparison via |Generator| while gathering
  // type feedback.
  void DoCompareOpWithFeedback(Token::Value compare_op,
                               InterpreterAssembler* assembler);

  // Generates code to perform the bitwise binary operation corresponding to
  // |bitwise_op| while gathering type feedback.
  void DoBitwiseBinaryOp(Token::Value bitwise_op,
                         InterpreterAssembler* assembler);

  // Generates code to perform the binary operation via |Generator| using
  // an immediate value rather the accumulator as the rhs operand.
  template <class Generator>
  void DoBinaryOpWithImmediate(InterpreterAssembler* assembler);

  // Generates code to perform the unary operation via |Generator| while
  // gatering type feedback.
  template <class Generator>
  void DoUnaryOpWithFeedback(InterpreterAssembler* assembler);

  // Generates code to perform the comparison operation associated with
  // |compare_op|.
  void DoCompareOp(Token::Value compare_op, InterpreterAssembler* assembler);

  // Generates code to perform a global store via |ic|.
  void DoStaGlobal(Callable ic, InterpreterAssembler* assembler);

  // Generates code to perform a named property store via |ic|.
  void DoStoreIC(Callable ic, InterpreterAssembler* assembler);

  // Generates code to perform a keyed property store via |ic|.
  void DoKeyedStoreIC(Callable ic, InterpreterAssembler* assembler);

  // Generates code to perform a JS call that collects type feedback.
  void DoJSCall(InterpreterAssembler* assembler, TailCallMode tail_call_mode);

  // Generates code to perform delete via function_id.
  void DoDelete(Runtime::FunctionId function_id,
                InterpreterAssembler* assembler);

  // Generates code to perform a lookup slot load via |function_id|.
  void DoLdaLookupSlot(Runtime::FunctionId function_id,
                       InterpreterAssembler* assembler);

  // Generates code to perform a lookup slot load via |function_id| that can
  // fast path to a context slot load.
  void DoLdaLookupContextSlot(Runtime::FunctionId function_id,
                              InterpreterAssembler* assembler);

  // Generates code to perform a lookup slot load via |function_id| that can
  // fast path to a global load.
  void DoLdaLookupGlobalSlot(Runtime::FunctionId function_id,
                             InterpreterAssembler* assembler);

  // Generates code to perform a lookup slot store depending on
  // |language_mode|.
  void DoStaLookupSlot(LanguageMode language_mode,
                       InterpreterAssembler* assembler);

  // Generates code to load a global.
  compiler::Node* BuildLoadGlobal(Callable ic, compiler::Node* context,
                                  compiler::Node* name_index,
                                  compiler::Node* feedback_slot,
                                  InterpreterAssembler* assembler);

  // Generates code to prepare the result for ForInPrepare. Cache data
  // are placed into the consecutive series of registers starting at
  // |output_register|.
  void BuildForInPrepareResult(compiler::Node* output_register,
                               compiler::Node* cache_type,
                               compiler::Node* cache_array,
                               compiler::Node* cache_length,
                               InterpreterAssembler* assembler);

  // Generates code to perform the unary operation via |callable|.
  compiler::Node* BuildUnaryOp(Callable callable,
                               InterpreterAssembler* assembler);

  uintptr_t GetDispatchCounter(Bytecode from, Bytecode to) const;

  // Get dispatch table index of bytecode.
  static size_t GetDispatchTableIndex(Bytecode bytecode,
                                      OperandScale operand_scale);

  bool IsDispatchTableInitialized();
  bool ShouldInitializeDispatchTable();

  static const int kNumberOfWideVariants = 3;
  static const int kDispatchTableSize = kNumberOfWideVariants * (kMaxUInt8 + 1);
  static const int kNumberOfBytecodes = static_cast<int>(Bytecode::kLast) + 1;

  Isolate* isolate_;
  Address dispatch_table_[kDispatchTableSize];
  std::unique_ptr<uintptr_t[]> bytecode_dispatch_counters_table_;

  DISALLOW_COPY_AND_ASSIGN(Interpreter);
};

}  // namespace interpreter
}  // namespace internal
}  // namespace v8

#endif  // V8_INTERPRETER_INTERPRETER_H_