summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/interpreter-assembler.h
blob: fb79d3eaa2ff2a506faf3cb3cbd2e6f91b767b74 (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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
// 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_COMPILER_INTERPRETER_ASSEMBLER_H_
#define V8_COMPILER_INTERPRETER_ASSEMBLER_H_

// Clients of this interface shouldn't depend on lots of compiler internals.
// Do not include anything from src/compiler here!
#include "src/allocation.h"
#include "src/base/smart-pointers.h"
#include "src/builtins.h"
#include "src/frames.h"
#include "src/interpreter/bytecodes.h"
#include "src/runtime/runtime.h"

namespace v8 {
namespace internal {

class CallInterfaceDescriptor;
class Isolate;
class Zone;

namespace compiler {

class CallDescriptor;
class Graph;
class Node;
class Operator;
class RawMachineAssembler;
class Schedule;

class InterpreterAssembler {
 public:
  InterpreterAssembler(Isolate* isolate, Zone* zone,
                       interpreter::Bytecode bytecode);
  virtual ~InterpreterAssembler();

  Handle<Code> GenerateCode();

  // Returns the count immediate for bytecode operand |operand_index| in the
  // current bytecode.
  Node* BytecodeOperandCount(int operand_index);
  // Returns the index immediate for bytecode operand |operand_index| in the
  // current bytecode.
  Node* BytecodeOperandIdx(int operand_index);
  // Returns the Imm8 immediate for bytecode operand |operand_index| in the
  // current bytecode.
  Node* BytecodeOperandImm(int operand_index);
  // Returns the register index for bytecode operand |operand_index| in the
  // current bytecode.
  Node* BytecodeOperandReg(int operand_index);

  // Accumulator.
  Node* GetAccumulator();
  void SetAccumulator(Node* value);

  // Context.
  Node* GetContext();
  void SetContext(Node* value);

  // Loads from and stores to the interpreter register file.
  Node* LoadRegister(int offset);
  Node* LoadRegister(interpreter::Register reg);
  Node* LoadRegister(Node* reg_index);
  Node* StoreRegister(Node* value, int offset);
  Node* StoreRegister(Node* value, interpreter::Register reg);
  Node* StoreRegister(Node* value, Node* reg_index);

  // Returns the next consecutive register.
  Node* NextRegister(Node* reg_index);

  // Returns the location in memory of the register |reg_index| in the
  // interpreter register file.
  Node* RegisterLocation(Node* reg_index);

  // Constants.
  Node* Int32Constant(int value);
  Node* IntPtrConstant(intptr_t value);
  Node* NumberConstant(double value);
  Node* HeapConstant(Handle<HeapObject> object);
  Node* BooleanConstant(bool value);

  // Tag and untag Smi values.
  Node* SmiTag(Node* value);
  Node* SmiUntag(Node* value);

  // Basic arithmetic operations.
  Node* IntPtrAdd(Node* a, Node* b);
  Node* IntPtrSub(Node* a, Node* b);
  Node* WordShl(Node* value, int shift);

  // Load constant at |index| in the constant pool.
  Node* LoadConstantPoolEntry(Node* index);

  // Load an element from a fixed array on the heap.
  Node* LoadFixedArrayElement(Node* fixed_array, int index);

  // Load a field from an object on the heap.
  Node* LoadObjectField(Node* object, int offset);

  // Load |slot_index| from |context|.
  Node* LoadContextSlot(Node* context, int slot_index);
  Node* LoadContextSlot(Node* context, Node* slot_index);
  // Stores |value| into |slot_index| of |context|.
  Node* StoreContextSlot(Node* context, Node* slot_index, Node* value);

  // Load the TypeFeedbackVector for the current function.
  Node* LoadTypeFeedbackVector();

  // Project the output value at index |index|
  Node* Projection(int index, Node* node);

  // Call constructor |constructor| with |arg_count| arguments (not
  // including receiver) and the first argument located at
  // |first_arg|. The |new_target| is the same as the
  // |constructor| for the new keyword, but differs for the super
  // keyword.
  Node* CallConstruct(Node* new_target, Node* constructor, Node* first_arg,
                      Node* arg_count);

  // Call JSFunction or Callable |function| with |arg_count|
  // arguments (not including receiver) and the first argument
  // located at |first_arg|.
  Node* CallJS(Node* function, Node* first_arg, Node* arg_count);

  // Call an IC code stub.
  Node* CallIC(CallInterfaceDescriptor descriptor, Node* target, Node* arg1,
               Node* arg2, Node* arg3);
  Node* CallIC(CallInterfaceDescriptor descriptor, Node* target, Node* arg1,
               Node* arg2, Node* arg3, Node* arg4);
  Node* CallIC(CallInterfaceDescriptor descriptor, Node* target, Node* arg1,
               Node* arg2, Node* arg3, Node* arg4, Node* arg5);

  // Call runtime function.
  Node* CallRuntime(Node* function_id, Node* first_arg, Node* arg_count,
                    int return_size = 1);
  Node* CallRuntime(Runtime::FunctionId function_id, Node* arg1);
  Node* CallRuntime(Runtime::FunctionId function_id, Node* arg1, Node* arg2);
  Node* CallRuntime(Runtime::FunctionId function_id, Node* arg1, Node* arg2,
                    Node* arg3, Node* arg4);

  // Jump relative to the current bytecode by |jump_offset|.
  void Jump(Node* jump_offset);

  // Jump relative to the current bytecode by |jump_offset| if the
  // word values |lhs| and |rhs| are equal.
  void JumpIfWordEqual(Node* lhs, Node* rhs, Node* jump_offset);

  // Returns from the function.
  void Return();

  // Dispatch to the bytecode.
  void Dispatch();

  // Abort with the given bailout reason.
  void Abort(BailoutReason bailout_reason);

 protected:
  static bool TargetSupportsUnalignedAccess();

  // Protected helpers (for testing) which delegate to RawMachineAssembler.
  CallDescriptor* call_descriptor() const;
  Graph* graph();

 private:
  // Returns a raw pointer to start of the register file on the stack.
  Node* RegisterFileRawPointer();
  // Returns a tagged pointer to the current function's BytecodeArray object.
  Node* BytecodeArrayTaggedPointer();
  // Returns the offset from the BytecodeArrayPointer of the current bytecode.
  Node* BytecodeOffset();
  // Returns a raw pointer to first entry in the interpreter dispatch table.
  Node* DispatchTableRawPointer();

  // Saves and restores interpreter bytecode offset to the interpreter stack
  // frame when performing a call.
  void CallPrologue();
  void CallEpilogue();

  // Returns the offset of register |index| relative to RegisterFilePointer().
  Node* RegisterFrameOffset(Node* index);

  Node* SmiShiftBitsConstant();
  Node* BytecodeOperand(int operand_index);
  Node* BytecodeOperandSignExtended(int operand_index);
  Node* BytecodeOperandShort(int operand_index);
  Node* BytecodeOperandShortSignExtended(int operand_index);

  Node* CallN(CallDescriptor* descriptor, Node* code_target, Node** args);
  Node* CallIC(CallInterfaceDescriptor descriptor, Node* target, Node** args);

  // Returns BytecodeOffset() advanced by delta bytecodes. Note: this does not
  // update BytecodeOffset() itself.
  Node* Advance(int delta);
  Node* Advance(Node* delta);

  // Starts next instruction dispatch at |new_bytecode_offset|.
  void DispatchTo(Node* new_bytecode_offset);

  // Abort operations for debug code.
  void AbortIfWordNotEqual(Node* lhs, Node* rhs, BailoutReason bailout_reason);

  // Private helpers which delegate to RawMachineAssembler.
  Isolate* isolate();
  Zone* zone();

  interpreter::Bytecode bytecode_;
  base::SmartPointer<RawMachineAssembler> raw_assembler_;

  Node* accumulator_;
  Node* bytecode_offset_;
  Node* context_;

  bool code_generated_;

  DISALLOW_COPY_AND_ASSIGN(InterpreterAssembler);
};

}  // namespace compiler
}  // namespace internal
}  // namespace v8

#endif  // V8_COMPILER_INTERPRETER_ASSEMBLER_H_