V8 Project
raw-machine-assembler.h
Go to the documentation of this file.
1 // Copyright 2014 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_RAW_MACHINE_ASSEMBLER_H_
6 #define V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_
7 
8 #include "src/v8.h"
9 
12 #include "src/compiler/linkage.h"
14 #include "src/compiler/node.h"
15 #include "src/compiler/operator.h"
16 
17 
18 namespace v8 {
19 namespace internal {
20 namespace compiler {
21 
22 class BasicBlock;
23 class Schedule;
24 
25 
27  public:
28  class Label {
29  public:
31  ~Label() { DCHECK(bound_ || !used_); }
32 
33  BasicBlock* block() { return block_; }
34 
35  private:
36  // Private constructor for exit label.
37  explicit Label(BasicBlock* block)
39 
40  BasicBlock* block_;
41  bool used_;
42  bool bound_;
43  friend class RawMachineAssembler;
45  };
46 
48  MachineType word = kMachPtr);
49  virtual ~RawMachineAssembler() {}
50 
51  Isolate* isolate() const { return zone()->isolate(); }
52  Zone* zone() const { return graph()->zone(); }
53  MachineOperatorBuilder* machine() { return &machine_; }
54  CommonOperatorBuilder* common() { return &common_; }
55  CallDescriptor* call_descriptor() const { return call_descriptor_; }
56  size_t parameter_count() const { return machine_sig_->parameter_count(); }
58 
61  isolate()->factory()->undefined_value());
62  return NewNode(common()->HeapConstant(unique));
63  }
64 
65  // Constants.
66  Node* PointerConstant(void* value) {
67  return IntPtrConstant(reinterpret_cast<intptr_t>(value));
68  }
69  Node* IntPtrConstant(intptr_t value) {
70  // TODO(dcarney): mark generated code as unserializable if value != 0.
71  return kPointerSize == 8 ? Int64Constant(value)
72  : Int32Constant(static_cast<int>(value));
73  }
74  Node* Int32Constant(int32_t value) {
75  return NewNode(common()->Int32Constant(value));
76  }
77  Node* Int64Constant(int64_t value) {
78  return NewNode(common()->Int64Constant(value));
79  }
80  Node* NumberConstant(double value) {
81  return NewNode(common()->NumberConstant(value));
82  }
83  Node* Float32Constant(float value) {
84  return NewNode(common()->Float32Constant(value));
85  }
86  Node* Float64Constant(double value) {
87  return NewNode(common()->Float64Constant(value));
88  }
89  Node* HeapConstant(Handle<Object> object) {
91  return NewNode(common()->HeapConstant(val));
92  }
93 
94  Node* Projection(int index, Node* a) {
95  return NewNode(common()->Projection(index), a);
96  }
97 
98  // Memory Operations.
99  Node* Load(MachineType rep, Node* base) {
100  return Load(rep, base, Int32Constant(0));
101  }
102  Node* Load(MachineType rep, Node* base, Node* index) {
103  return NewNode(machine()->Load(rep), base, index);
104  }
105  void Store(MachineType rep, Node* base, Node* value) {
106  Store(rep, base, Int32Constant(0), value);
107  }
108  void Store(MachineType rep, Node* base, Node* index, Node* value) {
109  NewNode(machine()->Store(StoreRepresentation(rep, kNoWriteBarrier)), base,
110  index, value);
111  }
112  // Arithmetic Operations.
113  Node* WordAnd(Node* a, Node* b) {
114  return NewNode(machine()->WordAnd(), a, b);
115  }
116  Node* WordOr(Node* a, Node* b) { return NewNode(machine()->WordOr(), a, b); }
117  Node* WordXor(Node* a, Node* b) {
118  return NewNode(machine()->WordXor(), a, b);
119  }
120  Node* WordShl(Node* a, Node* b) {
121  return NewNode(machine()->WordShl(), a, b);
122  }
123  Node* WordShr(Node* a, Node* b) {
124  return NewNode(machine()->WordShr(), a, b);
125  }
126  Node* WordSar(Node* a, Node* b) {
127  return NewNode(machine()->WordSar(), a, b);
128  }
129  Node* WordRor(Node* a, Node* b) {
130  return NewNode(machine()->WordRor(), a, b);
131  }
132  Node* WordEqual(Node* a, Node* b) {
133  return NewNode(machine()->WordEqual(), a, b);
134  }
135  Node* WordNotEqual(Node* a, Node* b) {
136  return WordBinaryNot(WordEqual(a, b));
137  }
138  Node* WordNot(Node* a) {
139  if (machine()->Is32()) {
140  return Word32Not(a);
141  } else {
142  return Word64Not(a);
143  }
144  }
145  Node* WordBinaryNot(Node* a) {
146  if (machine()->Is32()) {
147  return Word32BinaryNot(a);
148  } else {
149  return Word64BinaryNot(a);
150  }
151  }
152 
153  Node* Word32And(Node* a, Node* b) {
154  return NewNode(machine()->Word32And(), a, b);
155  }
156  Node* Word32Or(Node* a, Node* b) {
157  return NewNode(machine()->Word32Or(), a, b);
158  }
159  Node* Word32Xor(Node* a, Node* b) {
160  return NewNode(machine()->Word32Xor(), a, b);
161  }
162  Node* Word32Shl(Node* a, Node* b) {
163  return NewNode(machine()->Word32Shl(), a, b);
164  }
165  Node* Word32Shr(Node* a, Node* b) {
166  return NewNode(machine()->Word32Shr(), a, b);
167  }
168  Node* Word32Sar(Node* a, Node* b) {
169  return NewNode(machine()->Word32Sar(), a, b);
170  }
171  Node* Word32Ror(Node* a, Node* b) {
172  return NewNode(machine()->Word32Ror(), a, b);
173  }
174  Node* Word32Equal(Node* a, Node* b) {
175  return NewNode(machine()->Word32Equal(), a, b);
176  }
177  Node* Word32NotEqual(Node* a, Node* b) {
178  return Word32BinaryNot(Word32Equal(a, b));
179  }
180  Node* Word32Not(Node* a) { return Word32Xor(a, Int32Constant(-1)); }
181  Node* Word32BinaryNot(Node* a) { return Word32Equal(a, Int32Constant(0)); }
182 
183  Node* Word64And(Node* a, Node* b) {
184  return NewNode(machine()->Word64And(), a, b);
185  }
186  Node* Word64Or(Node* a, Node* b) {
187  return NewNode(machine()->Word64Or(), a, b);
188  }
189  Node* Word64Xor(Node* a, Node* b) {
190  return NewNode(machine()->Word64Xor(), a, b);
191  }
192  Node* Word64Shl(Node* a, Node* b) {
193  return NewNode(machine()->Word64Shl(), a, b);
194  }
195  Node* Word64Shr(Node* a, Node* b) {
196  return NewNode(machine()->Word64Shr(), a, b);
197  }
198  Node* Word64Sar(Node* a, Node* b) {
199  return NewNode(machine()->Word64Sar(), a, b);
200  }
201  Node* Word64Ror(Node* a, Node* b) {
202  return NewNode(machine()->Word64Ror(), a, b);
203  }
204  Node* Word64Equal(Node* a, Node* b) {
205  return NewNode(machine()->Word64Equal(), a, b);
206  }
207  Node* Word64NotEqual(Node* a, Node* b) {
208  return Word64BinaryNot(Word64Equal(a, b));
209  }
210  Node* Word64Not(Node* a) { return Word64Xor(a, Int64Constant(-1)); }
211  Node* Word64BinaryNot(Node* a) { return Word64Equal(a, Int64Constant(0)); }
212 
213  Node* Int32Add(Node* a, Node* b) {
214  return NewNode(machine()->Int32Add(), a, b);
215  }
216  Node* Int32AddWithOverflow(Node* a, Node* b) {
217  return NewNode(machine()->Int32AddWithOverflow(), a, b);
218  }
219  Node* Int32Sub(Node* a, Node* b) {
220  return NewNode(machine()->Int32Sub(), a, b);
221  }
222  Node* Int32SubWithOverflow(Node* a, Node* b) {
223  return NewNode(machine()->Int32SubWithOverflow(), a, b);
224  }
225  Node* Int32Mul(Node* a, Node* b) {
226  return NewNode(machine()->Int32Mul(), a, b);
227  }
228  Node* Int32Div(Node* a, Node* b) {
229  return NewNode(machine()->Int32Div(), a, b);
230  }
231  Node* Int32UDiv(Node* a, Node* b) {
232  return NewNode(machine()->Int32UDiv(), a, b);
233  }
234  Node* Int32Mod(Node* a, Node* b) {
235  return NewNode(machine()->Int32Mod(), a, b);
236  }
237  Node* Int32UMod(Node* a, Node* b) {
238  return NewNode(machine()->Int32UMod(), a, b);
239  }
240  Node* Int32LessThan(Node* a, Node* b) {
241  return NewNode(machine()->Int32LessThan(), a, b);
242  }
243  Node* Int32LessThanOrEqual(Node* a, Node* b) {
244  return NewNode(machine()->Int32LessThanOrEqual(), a, b);
245  }
246  Node* Uint32LessThan(Node* a, Node* b) {
247  return NewNode(machine()->Uint32LessThan(), a, b);
248  }
249  Node* Uint32LessThanOrEqual(Node* a, Node* b) {
250  return NewNode(machine()->Uint32LessThanOrEqual(), a, b);
251  }
252  Node* Int32GreaterThan(Node* a, Node* b) { return Int32LessThan(b, a); }
253  Node* Int32GreaterThanOrEqual(Node* a, Node* b) {
254  return Int32LessThanOrEqual(b, a);
255  }
256  Node* Int32Neg(Node* a) { return Int32Sub(Int32Constant(0), a); }
257 
258  Node* Int64Add(Node* a, Node* b) {
259  return NewNode(machine()->Int64Add(), a, b);
260  }
261  Node* Int64Sub(Node* a, Node* b) {
262  return NewNode(machine()->Int64Sub(), a, b);
263  }
264  Node* Int64Mul(Node* a, Node* b) {
265  return NewNode(machine()->Int64Mul(), a, b);
266  }
267  Node* Int64Div(Node* a, Node* b) {
268  return NewNode(machine()->Int64Div(), a, b);
269  }
270  Node* Int64UDiv(Node* a, Node* b) {
271  return NewNode(machine()->Int64UDiv(), a, b);
272  }
273  Node* Int64Mod(Node* a, Node* b) {
274  return NewNode(machine()->Int64Mod(), a, b);
275  }
276  Node* Int64UMod(Node* a, Node* b) {
277  return NewNode(machine()->Int64UMod(), a, b);
278  }
279  Node* Int64Neg(Node* a) { return Int64Sub(Int64Constant(0), a); }
280  Node* Int64LessThan(Node* a, Node* b) {
281  return NewNode(machine()->Int64LessThan(), a, b);
282  }
283  Node* Int64LessThanOrEqual(Node* a, Node* b) {
284  return NewNode(machine()->Int64LessThanOrEqual(), a, b);
285  }
286  Node* Int64GreaterThan(Node* a, Node* b) { return Int64LessThan(b, a); }
287  Node* Int64GreaterThanOrEqual(Node* a, Node* b) {
288  return Int64LessThanOrEqual(b, a);
289  }
290 
291  // TODO(turbofan): What is this used for?
292  Node* ConvertIntPtrToInt32(Node* a) {
293  return kPointerSize == 8 ? NewNode(machine()->TruncateInt64ToInt32(), a)
294  : a;
295  }
296  Node* ConvertInt32ToIntPtr(Node* a) {
297  return kPointerSize == 8 ? NewNode(machine()->ChangeInt32ToInt64(), a) : a;
298  }
299 
300 #define INTPTR_BINOP(prefix, name) \
301  Node* IntPtr##name(Node* a, Node* b) { \
302  return kPointerSize == 8 ? prefix##64##name(a, b) \
303  : prefix##32##name(a, b); \
304  }
305 
306  INTPTR_BINOP(Int, Add);
307  INTPTR_BINOP(Int, Sub);
308  INTPTR_BINOP(Int, LessThan);
309  INTPTR_BINOP(Int, LessThanOrEqual);
310  INTPTR_BINOP(Word, Equal);
311  INTPTR_BINOP(Word, NotEqual);
312  INTPTR_BINOP(Int, GreaterThanOrEqual);
313  INTPTR_BINOP(Int, GreaterThan);
314 
315 #undef INTPTR_BINOP
316 
317  Node* Float64Add(Node* a, Node* b) {
318  return NewNode(machine()->Float64Add(), a, b);
319  }
320  Node* Float64Sub(Node* a, Node* b) {
321  return NewNode(machine()->Float64Sub(), a, b);
322  }
323  Node* Float64Mul(Node* a, Node* b) {
324  return NewNode(machine()->Float64Mul(), a, b);
325  }
326  Node* Float64Div(Node* a, Node* b) {
327  return NewNode(machine()->Float64Div(), a, b);
328  }
329  Node* Float64Mod(Node* a, Node* b) {
330  return NewNode(machine()->Float64Mod(), a, b);
331  }
332  Node* Float64Equal(Node* a, Node* b) {
333  return NewNode(machine()->Float64Equal(), a, b);
334  }
335  Node* Float64NotEqual(Node* a, Node* b) {
336  return WordBinaryNot(Float64Equal(a, b));
337  }
338  Node* Float64LessThan(Node* a, Node* b) {
339  return NewNode(machine()->Float64LessThan(), a, b);
340  }
341  Node* Float64LessThanOrEqual(Node* a, Node* b) {
342  return NewNode(machine()->Float64LessThanOrEqual(), a, b);
343  }
344  Node* Float64GreaterThan(Node* a, Node* b) { return Float64LessThan(b, a); }
345  Node* Float64GreaterThanOrEqual(Node* a, Node* b) {
346  return Float64LessThanOrEqual(b, a);
347  }
348 
349  // Conversions.
350  Node* ChangeFloat32ToFloat64(Node* a) {
351  return NewNode(machine()->ChangeFloat32ToFloat64(), a);
352  }
353  Node* ChangeInt32ToFloat64(Node* a) {
354  return NewNode(machine()->ChangeInt32ToFloat64(), a);
355  }
356  Node* ChangeUint32ToFloat64(Node* a) {
357  return NewNode(machine()->ChangeUint32ToFloat64(), a);
358  }
359  Node* ChangeFloat64ToInt32(Node* a) {
360  return NewNode(machine()->ChangeFloat64ToInt32(), a);
361  }
362  Node* ChangeFloat64ToUint32(Node* a) {
363  return NewNode(machine()->ChangeFloat64ToUint32(), a);
364  }
365  Node* ChangeInt32ToInt64(Node* a) {
366  return NewNode(machine()->ChangeInt32ToInt64(), a);
367  }
368  Node* ChangeUint32ToUint64(Node* a) {
369  return NewNode(machine()->ChangeUint32ToUint64(), a);
370  }
371  Node* TruncateFloat64ToFloat32(Node* a) {
372  return NewNode(machine()->TruncateFloat64ToFloat32(), a);
373  }
374  Node* TruncateFloat64ToInt32(Node* a) {
375  return NewNode(machine()->TruncateFloat64ToInt32(), a);
376  }
377  Node* TruncateInt64ToInt32(Node* a) {
378  return NewNode(machine()->TruncateInt64ToInt32(), a);
379  }
380 
381  // Parameters.
382  Node* Parameter(size_t index);
383 
384  // Control flow.
385  Label* Exit();
386  void Goto(Label* label);
387  void Branch(Node* condition, Label* true_val, Label* false_val);
388  // Call through CallFunctionStub with lazy deopt and frame-state.
389  Node* CallFunctionStub0(Node* function, Node* receiver, Node* context,
390  Node* frame_state, CallFunctionFlags flags);
391  // Call to a JS function with zero parameters.
392  Node* CallJS0(Node* function, Node* receiver, Node* context,
393  Node* frame_state);
394  // Call to a runtime function with zero parameters.
395  Node* CallRuntime1(Runtime::FunctionId function, Node* arg0, Node* context,
396  Node* frame_state);
397  void Return(Node* value);
398  void Bind(Label* label);
399  void Deoptimize(Node* state);
400 
401  // Variables.
402  Node* Phi(MachineType type, Node* n1, Node* n2) {
403  return NewNode(common()->Phi(type, 2), n1, n2);
404  }
405  Node* Phi(MachineType type, Node* n1, Node* n2, Node* n3) {
406  return NewNode(common()->Phi(type, 3), n1, n2, n3);
407  }
408  Node* Phi(MachineType type, Node* n1, Node* n2, Node* n3, Node* n4) {
409  return NewNode(common()->Phi(type, 4), n1, n2, n3, n4);
410  }
411 
412  // MachineAssembler is invalid after export.
413  Schedule* Export();
414 
415  protected:
416  virtual Node* MakeNode(const Operator* op, int input_count,
417  Node** inputs) FINAL;
418 
419  bool ScheduleValid() { return schedule_ != NULL; }
420 
423  return schedule_;
424  }
425 
426  private:
427  BasicBlock* Use(Label* label);
428  BasicBlock* EnsureBlock(Label* label);
429  BasicBlock* CurrentBlock();
430 
432  MachineOperatorBuilder machine_;
433  CommonOperatorBuilder common_;
435  CallDescriptor* call_descriptor_;
436  Node** parameters_;
438  BasicBlock* current_block_;
439 
441 };
442 
443 } // namespace compiler
444 } // namespace internal
445 } // namespace v8
446 
447 #endif // V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_
static Unique< T > CreateImmovable(Handle< T > handle)
Definition: unique.h:116
static Unique< T > CreateUninitialized(Handle< T > handle)
Definition: unique.h:112
Isolate * isolate() const
Definition: zone.h:68
Node * NewNode(const Operator *op)
Definition: graph-builder.h:27
Node * CallJS0(Node *function, Node *receiver, Node *context, Node *frame_state)
Node * Load(MachineType rep, Node *base, Node *index)
Node * HeapConstant(Handle< Object > object)
void Store(MachineType rep, Node *base, Node *value)
Node * Phi(MachineType type, Node *n1, Node *n2, Node *n3)
Node * Phi(MachineType type, Node *n1, Node *n2, Node *n3, Node *n4)
Node * Phi(MachineType type, Node *n1, Node *n2)
RawMachineAssembler(Graph *graph, MachineSignature *machine_sig, MachineType word=kMachPtr)
void Branch(Node *condition, Label *true_val, Label *false_val)
virtual Node * MakeNode(const Operator *op, int input_count, Node **inputs) FINAL
void Store(MachineType rep, Node *base, Node *index, Node *value)
Node * Load(MachineType rep, Node *base)
Node * CallRuntime1(Runtime::FunctionId function, Node *arg0, Node *context, Node *frame_state)
Node * CallFunctionStub0(Node *function, Node *receiver, Node *context, Node *frame_state, CallFunctionFlags flags)
#define FINAL
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DCHECK(condition)
Definition: logging.h:205
int int32_t
Definition: unicode.cc:24
const int kPointerSize
Definition: globals.h:129
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20