• Home
  • 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_COMPILER_INTERPRETER_ASSEMBLER_H_
6 #define V8_COMPILER_INTERPRETER_ASSEMBLER_H_
7 
8 // Clients of this interface shouldn't depend on lots of compiler internals.
9 // Do not include anything from src/compiler here!
10 #include "src/allocation.h"
11 #include "src/base/smart-pointers.h"
12 #include "src/builtins.h"
13 #include "src/frames.h"
14 #include "src/interpreter/bytecodes.h"
15 #include "src/runtime/runtime.h"
16 
17 namespace v8 {
18 namespace internal {
19 
20 class CallInterfaceDescriptor;
21 class Isolate;
22 class Zone;
23 
24 namespace compiler {
25 
26 class CallDescriptor;
27 class Graph;
28 class Node;
29 class Operator;
30 class RawMachineAssembler;
31 class Schedule;
32 
33 class InterpreterAssembler {
34  public:
35   InterpreterAssembler(Isolate* isolate, Zone* zone,
36                        interpreter::Bytecode bytecode);
37   virtual ~InterpreterAssembler();
38 
39   Handle<Code> GenerateCode();
40 
41   // Returns the count immediate for bytecode operand |operand_index| in the
42   // current bytecode.
43   Node* BytecodeOperandCount(int operand_index);
44   // Returns the index immediate for bytecode operand |operand_index| in the
45   // current bytecode.
46   Node* BytecodeOperandIdx(int operand_index);
47   // Returns the Imm8 immediate for bytecode operand |operand_index| in the
48   // current bytecode.
49   Node* BytecodeOperandImm(int operand_index);
50   // Returns the register index for bytecode operand |operand_index| in the
51   // current bytecode.
52   Node* BytecodeOperandReg(int operand_index);
53 
54   // Accumulator.
55   Node* GetAccumulator();
56   void SetAccumulator(Node* value);
57 
58   // Context.
59   Node* GetContext();
60   void SetContext(Node* value);
61 
62   // Loads from and stores to the interpreter register file.
63   Node* LoadRegister(int offset);
64   Node* LoadRegister(interpreter::Register reg);
65   Node* LoadRegister(Node* reg_index);
66   Node* StoreRegister(Node* value, int offset);
67   Node* StoreRegister(Node* value, interpreter::Register reg);
68   Node* StoreRegister(Node* value, Node* reg_index);
69 
70   // Returns the next consecutive register.
71   Node* NextRegister(Node* reg_index);
72 
73   // Returns the location in memory of the register |reg_index| in the
74   // interpreter register file.
75   Node* RegisterLocation(Node* reg_index);
76 
77   // Constants.
78   Node* Int32Constant(int value);
79   Node* IntPtrConstant(intptr_t value);
80   Node* NumberConstant(double value);
81   Node* HeapConstant(Handle<HeapObject> object);
82   Node* BooleanConstant(bool value);
83 
84   // Tag and untag Smi values.
85   Node* SmiTag(Node* value);
86   Node* SmiUntag(Node* value);
87 
88   // Basic arithmetic operations.
89   Node* IntPtrAdd(Node* a, Node* b);
90   Node* IntPtrSub(Node* a, Node* b);
91   Node* WordShl(Node* value, int shift);
92 
93   // Load constant at |index| in the constant pool.
94   Node* LoadConstantPoolEntry(Node* index);
95 
96   // Load an element from a fixed array on the heap.
97   Node* LoadFixedArrayElement(Node* fixed_array, int index);
98 
99   // Load a field from an object on the heap.
100   Node* LoadObjectField(Node* object, int offset);
101 
102   // Load |slot_index| from |context|.
103   Node* LoadContextSlot(Node* context, int slot_index);
104   Node* LoadContextSlot(Node* context, Node* slot_index);
105   // Stores |value| into |slot_index| of |context|.
106   Node* StoreContextSlot(Node* context, Node* slot_index, Node* value);
107 
108   // Load the TypeFeedbackVector for the current function.
109   Node* LoadTypeFeedbackVector();
110 
111   // Project the output value at index |index|
112   Node* Projection(int index, Node* node);
113 
114   // Call constructor |constructor| with |arg_count| arguments (not
115   // including receiver) and the first argument located at
116   // |first_arg|. The |new_target| is the same as the
117   // |constructor| for the new keyword, but differs for the super
118   // keyword.
119   Node* CallConstruct(Node* new_target, Node* constructor, Node* first_arg,
120                       Node* arg_count);
121 
122   // Call JSFunction or Callable |function| with |arg_count|
123   // arguments (not including receiver) and the first argument
124   // located at |first_arg|.
125   Node* CallJS(Node* function, Node* first_arg, Node* arg_count);
126 
127   // Call an IC code stub.
128   Node* CallIC(CallInterfaceDescriptor descriptor, Node* target, Node* arg1,
129                Node* arg2, Node* arg3);
130   Node* CallIC(CallInterfaceDescriptor descriptor, Node* target, Node* arg1,
131                Node* arg2, Node* arg3, Node* arg4);
132   Node* CallIC(CallInterfaceDescriptor descriptor, Node* target, Node* arg1,
133                Node* arg2, Node* arg3, Node* arg4, Node* arg5);
134 
135   // Call runtime function.
136   Node* CallRuntime(Node* function_id, Node* first_arg, Node* arg_count,
137                     int return_size = 1);
138   Node* CallRuntime(Runtime::FunctionId function_id, Node* arg1);
139   Node* CallRuntime(Runtime::FunctionId function_id, Node* arg1, Node* arg2);
140   Node* CallRuntime(Runtime::FunctionId function_id, Node* arg1, Node* arg2,
141                     Node* arg3, Node* arg4);
142 
143   // Jump relative to the current bytecode by |jump_offset|.
144   void Jump(Node* jump_offset);
145 
146   // Jump relative to the current bytecode by |jump_offset| if the
147   // word values |lhs| and |rhs| are equal.
148   void JumpIfWordEqual(Node* lhs, Node* rhs, Node* jump_offset);
149 
150   // Returns from the function.
151   void Return();
152 
153   // Dispatch to the bytecode.
154   void Dispatch();
155 
156   // Abort with the given bailout reason.
157   void Abort(BailoutReason bailout_reason);
158 
159  protected:
160   static bool TargetSupportsUnalignedAccess();
161 
162   // Protected helpers (for testing) which delegate to RawMachineAssembler.
163   CallDescriptor* call_descriptor() const;
164   Graph* graph();
165 
166  private:
167   // Returns a raw pointer to start of the register file on the stack.
168   Node* RegisterFileRawPointer();
169   // Returns a tagged pointer to the current function's BytecodeArray object.
170   Node* BytecodeArrayTaggedPointer();
171   // Returns the offset from the BytecodeArrayPointer of the current bytecode.
172   Node* BytecodeOffset();
173   // Returns a raw pointer to first entry in the interpreter dispatch table.
174   Node* DispatchTableRawPointer();
175 
176   // Saves and restores interpreter bytecode offset to the interpreter stack
177   // frame when performing a call.
178   void CallPrologue();
179   void CallEpilogue();
180 
181   // Returns the offset of register |index| relative to RegisterFilePointer().
182   Node* RegisterFrameOffset(Node* index);
183 
184   Node* SmiShiftBitsConstant();
185   Node* BytecodeOperand(int operand_index);
186   Node* BytecodeOperandSignExtended(int operand_index);
187   Node* BytecodeOperandShort(int operand_index);
188   Node* BytecodeOperandShortSignExtended(int operand_index);
189 
190   Node* CallN(CallDescriptor* descriptor, Node* code_target, Node** args);
191   Node* CallIC(CallInterfaceDescriptor descriptor, Node* target, Node** args);
192 
193   // Returns BytecodeOffset() advanced by delta bytecodes. Note: this does not
194   // update BytecodeOffset() itself.
195   Node* Advance(int delta);
196   Node* Advance(Node* delta);
197 
198   // Starts next instruction dispatch at |new_bytecode_offset|.
199   void DispatchTo(Node* new_bytecode_offset);
200 
201   // Abort operations for debug code.
202   void AbortIfWordNotEqual(Node* lhs, Node* rhs, BailoutReason bailout_reason);
203 
204   // Private helpers which delegate to RawMachineAssembler.
205   Isolate* isolate();
206   Zone* zone();
207 
208   interpreter::Bytecode bytecode_;
209   base::SmartPointer<RawMachineAssembler> raw_assembler_;
210 
211   Node* accumulator_;
212   Node* bytecode_offset_;
213   Node* context_;
214 
215   bool code_generated_;
216 
217   DISALLOW_COPY_AND_ASSIGN(InterpreterAssembler);
218 };
219 
220 }  // namespace compiler
221 }  // namespace internal
222 }  // namespace v8
223 
224 #endif  // V8_COMPILER_INTERPRETER_ASSEMBLER_H_
225