OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_COMPILER_CODE_STUB_ASSEMBLER_H_ | 5 #ifndef V8_COMPILER_CODE_STUB_ASSEMBLER_H_ |
6 #define V8_COMPILER_CODE_STUB_ASSEMBLER_H_ | 6 #define V8_COMPILER_CODE_STUB_ASSEMBLER_H_ |
7 | 7 |
8 #include <map> | 8 #include <map> |
9 | 9 |
10 // Clients of this interface shouldn't depend on lots of compiler internals. | 10 // Clients of this interface shouldn't depend on lots of compiler internals. |
(...skipping 21 matching lines...) Expand all Loading... |
32 class Node; | 32 class Node; |
33 class Operator; | 33 class Operator; |
34 class RawMachineAssembler; | 34 class RawMachineAssembler; |
35 class RawMachineLabel; | 35 class RawMachineLabel; |
36 class Schedule; | 36 class Schedule; |
37 | 37 |
38 #define CODE_STUB_ASSEMBLER_BINARY_OP_LIST(V) \ | 38 #define CODE_STUB_ASSEMBLER_BINARY_OP_LIST(V) \ |
39 V(Float64Equal) \ | 39 V(Float64Equal) \ |
40 V(Float64LessThan) \ | 40 V(Float64LessThan) \ |
41 V(Float64LessThanOrEqual) \ | 41 V(Float64LessThanOrEqual) \ |
| 42 V(Float64GreaterThan) \ |
| 43 V(Float64GreaterThanOrEqual) \ |
42 V(IntPtrAdd) \ | 44 V(IntPtrAdd) \ |
43 V(IntPtrSub) \ | 45 V(IntPtrSub) \ |
44 V(Int32Add) \ | 46 V(Int32Add) \ |
45 V(Int32Sub) \ | 47 V(Int32Sub) \ |
46 V(Int32Mul) \ | 48 V(Int32Mul) \ |
| 49 V(Int32GreaterThan) \ |
47 V(Int32GreaterThanOrEqual) \ | 50 V(Int32GreaterThanOrEqual) \ |
48 V(Int32LessThan) \ | 51 V(Int32LessThan) \ |
| 52 V(Int32LessThanOrEqual) \ |
49 V(WordEqual) \ | 53 V(WordEqual) \ |
50 V(WordNotEqual) \ | 54 V(WordNotEqual) \ |
51 V(WordOr) \ | 55 V(WordOr) \ |
52 V(WordAnd) \ | 56 V(WordAnd) \ |
53 V(WordXor) \ | 57 V(WordXor) \ |
54 V(WordShl) \ | 58 V(WordShl) \ |
55 V(WordShr) \ | 59 V(WordShr) \ |
56 V(WordSar) \ | 60 V(WordSar) \ |
57 V(WordRor) \ | 61 V(WordRor) \ |
58 V(Word32Equal) \ | 62 V(Word32Equal) \ |
59 V(Word32NotEqual) \ | 63 V(Word32NotEqual) \ |
60 V(Word32Or) \ | 64 V(Word32Or) \ |
61 V(Word32And) \ | 65 V(Word32And) \ |
62 V(Word32Xor) \ | 66 V(Word32Xor) \ |
63 V(Word32Shl) \ | 67 V(Word32Shl) \ |
64 V(Word32Shr) \ | 68 V(Word32Shr) \ |
65 V(Word32Sar) \ | 69 V(Word32Sar) \ |
66 V(Word32Ror) \ | 70 V(Word32Ror) \ |
67 V(Word64Equal) \ | 71 V(Word64Equal) \ |
68 V(Word64NotEqual) \ | 72 V(Word64NotEqual) \ |
69 V(Word64Or) \ | 73 V(Word64Or) \ |
70 V(Word64And) \ | 74 V(Word64And) \ |
71 V(Word64Xor) \ | 75 V(Word64Xor) \ |
72 V(Word64Shr) \ | 76 V(Word64Shr) \ |
73 V(Word64Sar) \ | 77 V(Word64Sar) \ |
74 V(Word64Ror) \ | 78 V(Word64Ror) \ |
| 79 V(IntPtrLessThan) \ |
| 80 V(IntPtrLessThanOrEqual) \ |
75 V(UintPtrGreaterThanOrEqual) | 81 V(UintPtrGreaterThanOrEqual) |
76 | 82 |
77 #define CODE_STUB_ASSEMBLER_UNARY_OP_LIST(V) \ | 83 #define CODE_STUB_ASSEMBLER_UNARY_OP_LIST(V) \ |
78 V(ChangeFloat64ToUint32) \ | 84 V(ChangeFloat64ToUint32) \ |
79 V(ChangeInt32ToFloat64) \ | 85 V(ChangeInt32ToFloat64) \ |
80 V(ChangeInt32ToInt64) \ | 86 V(ChangeInt32ToInt64) \ |
81 V(ChangeUint32ToFloat64) \ | 87 V(ChangeUint32ToFloat64) \ |
82 V(ChangeUint32ToUint64) | 88 V(ChangeUint32ToUint64) |
83 | 89 |
84 class CodeStubAssembler { | 90 class CodeStubAssembler { |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context); | 201 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context); |
196 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context, | 202 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context, |
197 Node* arg1); | 203 Node* arg1); |
198 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context, | 204 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context, |
199 Node* arg1, Node* arg2); | 205 Node* arg1, Node* arg2); |
200 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context, | 206 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context, |
201 Node* arg1, Node* arg2, Node* arg3); | 207 Node* arg1, Node* arg2, Node* arg3); |
202 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context, | 208 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context, |
203 Node* arg1, Node* arg2, Node* arg3, Node* arg4); | 209 Node* arg1, Node* arg2, Node* arg3, Node* arg4); |
204 | 210 |
| 211 Node* CallStub(Callable const& callable, Node* context, Node* arg1, |
| 212 size_t result_size = 1); |
| 213 |
205 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target, | 214 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target, |
206 Node* context, Node* arg1, size_t result_size = 1); | 215 Node* context, Node* arg1, size_t result_size = 1); |
207 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target, | 216 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target, |
208 Node* context, Node* arg1, Node* arg2, size_t result_size = 1); | 217 Node* context, Node* arg1, Node* arg2, size_t result_size = 1); |
209 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target, | 218 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target, |
210 Node* context, Node* arg1, Node* arg2, Node* arg3, | 219 Node* context, Node* arg1, Node* arg2, Node* arg3, |
211 size_t result_size = 1); | 220 size_t result_size = 1); |
212 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target, | 221 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target, |
213 Node* context, Node* arg1, Node* arg2, Node* arg3, Node* arg4, | 222 Node* context, Node* arg1, Node* arg2, Node* arg3, Node* arg4, |
214 size_t result_size = 1); | 223 size_t result_size = 1); |
(...skipping 20 matching lines...) Expand all Loading... |
235 // Untag a Smi value as a Word. | 244 // Untag a Smi value as a Word. |
236 Node* SmiUntag(Node* value); | 245 Node* SmiUntag(Node* value); |
237 | 246 |
238 // Smi conversions. | 247 // Smi conversions. |
239 Node* SmiToFloat64(Node* value); | 248 Node* SmiToFloat64(Node* value); |
240 Node* SmiToInt32(Node* value); | 249 Node* SmiToInt32(Node* value); |
241 | 250 |
242 // Smi operations. | 251 // Smi operations. |
243 Node* SmiAdd(Node* a, Node* b); | 252 Node* SmiAdd(Node* a, Node* b); |
244 Node* SmiEqual(Node* a, Node* b); | 253 Node* SmiEqual(Node* a, Node* b); |
| 254 Node* SmiLessThan(Node* a, Node* b); |
| 255 Node* SmiLessThanOrEqual(Node* a, Node* b); |
245 | 256 |
246 // Load a value from the root array. | 257 // Load a value from the root array. |
247 Node* LoadRoot(Heap::RootListIndex root_index); | 258 Node* LoadRoot(Heap::RootListIndex root_index); |
248 | 259 |
249 // Check a value for smi-ness | 260 // Check a value for smi-ness |
250 Node* WordIsSmi(Node* a); | 261 Node* WordIsSmi(Node* a); |
251 | 262 |
252 // Load an object pointer from a buffer that isn't in the heap. | 263 // Load an object pointer from a buffer that isn't in the heap. |
253 Node* LoadBufferObject(Node* buffer, int offset); | 264 Node* LoadBufferObject(Node* buffer, int offset); |
254 // Load a field from an object on the heap. | 265 // Load a field from an object on the heap. |
(...skipping 19 matching lines...) Expand all Loading... |
274 // Returns a node that is true if the given bit is set in |word32|. | 285 // Returns a node that is true if the given bit is set in |word32|. |
275 template <typename T> | 286 template <typename T> |
276 Node* BitFieldDecode(Node* word32) { | 287 Node* BitFieldDecode(Node* word32) { |
277 return BitFieldDecode(word32, T::kShift, T::kMask); | 288 return BitFieldDecode(word32, T::kShift, T::kMask); |
278 } | 289 } |
279 | 290 |
280 Node* BitFieldDecode(Node* word32, uint32_t shift, uint32_t mask); | 291 Node* BitFieldDecode(Node* word32, uint32_t shift, uint32_t mask); |
281 | 292 |
282 // Branching helpers. | 293 // Branching helpers. |
283 // TODO(danno): Can we be more cleverish wrt. edge-split? | 294 // TODO(danno): Can we be more cleverish wrt. edge-split? |
| 295 void BranchIfSmiLessThan(Node* a, Node* b, Label* if_true, Label* if_false); |
| 296 void BranchIfSmiLessThanOrEqual(Node* a, Node* b, Label* if_true, |
| 297 Label* if_false); |
284 void BranchIfFloat64Equal(Node* a, Node* b, Label* if_true, Label* if_false); | 298 void BranchIfFloat64Equal(Node* a, Node* b, Label* if_true, Label* if_false); |
| 299 void BranchIfFloat64LessThan(Node* a, Node* b, Label* if_true, |
| 300 Label* if_false); |
| 301 void BranchIfFloat64LessThanOrEqual(Node* a, Node* b, Label* if_true, |
| 302 Label* if_false); |
| 303 void BranchIfFloat64GreaterThan(Node* a, Node* b, Label* if_true, |
| 304 Label* if_false); |
| 305 void BranchIfFloat64GreaterThanOrEqual(Node* a, Node* b, Label* if_true, |
| 306 Label* if_false); |
285 void BranchIfFloat64IsNaN(Node* value, Label* if_true, Label* if_false) { | 307 void BranchIfFloat64IsNaN(Node* value, Label* if_true, Label* if_false) { |
286 BranchIfFloat64Equal(value, value, if_false, if_true); | 308 BranchIfFloat64Equal(value, value, if_false, if_true); |
287 } | 309 } |
288 | 310 |
289 protected: | 311 // Helpers which delegate to RawMachineAssembler. |
290 // Protected helpers which delegate to RawMachineAssembler. | |
291 Graph* graph() const; | |
292 Factory* factory() const; | 312 Factory* factory() const; |
293 Isolate* isolate() const; | 313 Isolate* isolate() const; |
294 Zone* zone() const; | 314 Zone* zone() const; |
295 | 315 |
| 316 protected: |
| 317 // Protected helpers which delegate to RawMachineAssembler. |
| 318 Graph* graph() const; |
| 319 |
296 // Enables subclasses to perform operations before and after a call. | 320 // Enables subclasses to perform operations before and after a call. |
297 virtual void CallPrologue(); | 321 virtual void CallPrologue(); |
298 virtual void CallEpilogue(); | 322 virtual void CallEpilogue(); |
299 | 323 |
300 private: | 324 private: |
301 friend class CodeStubAssemblerTester; | 325 friend class CodeStubAssemblerTester; |
302 | 326 |
303 Node* CallN(CallDescriptor* descriptor, Node* code_target, Node** args); | 327 Node* CallN(CallDescriptor* descriptor, Node* code_target, Node** args); |
304 Node* TailCallN(CallDescriptor* descriptor, Node* code_target, Node** args); | 328 Node* TailCallN(CallDescriptor* descriptor, Node* code_target, Node** args); |
305 | 329 |
(...skipping 10 matching lines...) Expand all Loading... |
316 bool code_generated_; | 340 bool code_generated_; |
317 ZoneVector<Variable::Impl*> variables_; | 341 ZoneVector<Variable::Impl*> variables_; |
318 | 342 |
319 DISALLOW_COPY_AND_ASSIGN(CodeStubAssembler); | 343 DISALLOW_COPY_AND_ASSIGN(CodeStubAssembler); |
320 }; | 344 }; |
321 | 345 |
322 DEFINE_OPERATORS_FOR_FLAGS(CodeStubAssembler::AllocationFlags); | 346 DEFINE_OPERATORS_FOR_FLAGS(CodeStubAssembler::AllocationFlags); |
323 | 347 |
324 class CodeStubAssembler::Label { | 348 class CodeStubAssembler::Label { |
325 public: | 349 public: |
326 explicit Label(CodeStubAssembler* assembler); | 350 enum Type { kDeferred, kNonDeferred }; |
| 351 |
| 352 explicit Label(CodeStubAssembler* assembler, |
| 353 CodeStubAssembler::Label::Type type = |
| 354 CodeStubAssembler::Label::kNonDeferred) |
| 355 : CodeStubAssembler::Label(assembler, 0, nullptr, type) {} |
| 356 Label(CodeStubAssembler* assembler, |
| 357 CodeStubAssembler::Variable* merged_variable, |
| 358 CodeStubAssembler::Label::Type type = |
| 359 CodeStubAssembler::Label::kNonDeferred) |
| 360 : CodeStubAssembler::Label(assembler, 1, &merged_variable, type) {} |
327 Label(CodeStubAssembler* assembler, int merged_variable_count, | 361 Label(CodeStubAssembler* assembler, int merged_variable_count, |
328 CodeStubAssembler::Variable** merged_variables); | 362 CodeStubAssembler::Variable** merged_variables, |
329 Label(CodeStubAssembler* assembler, | 363 CodeStubAssembler::Label::Type type = |
330 CodeStubAssembler::Variable* merged_variable); | 364 CodeStubAssembler::Label::kNonDeferred); |
331 ~Label() {} | 365 ~Label() {} |
332 | 366 |
333 private: | 367 private: |
334 friend class CodeStubAssembler; | 368 friend class CodeStubAssembler; |
335 | 369 |
336 void Bind(); | 370 void Bind(); |
337 void MergeVariables(); | 371 void MergeVariables(); |
338 | 372 |
339 bool bound_; | 373 bool bound_; |
340 size_t merge_count_; | 374 size_t merge_count_; |
341 CodeStubAssembler* assembler_; | 375 CodeStubAssembler* assembler_; |
342 RawMachineLabel* label_; | 376 RawMachineLabel* label_; |
343 // Map of variables that need to be merged to their phi nodes (or placeholders | 377 // Map of variables that need to be merged to their phi nodes (or placeholders |
344 // for those phis). | 378 // for those phis). |
345 std::map<Variable::Impl*, Node*> variable_phis_; | 379 std::map<Variable::Impl*, Node*> variable_phis_; |
346 // Map of variables to the list of value nodes that have been added from each | 380 // Map of variables to the list of value nodes that have been added from each |
347 // merge path in their order of merging. | 381 // merge path in their order of merging. |
348 std::map<Variable::Impl*, std::vector<Node*>> variable_merges_; | 382 std::map<Variable::Impl*, std::vector<Node*>> variable_merges_; |
349 }; | 383 }; |
350 | 384 |
351 } // namespace compiler | 385 } // namespace compiler |
352 } // namespace internal | 386 } // namespace internal |
353 } // namespace v8 | 387 } // namespace v8 |
354 | 388 |
355 #endif // V8_COMPILER_CODE_STUB_ASSEMBLER_H_ | 389 #endif // V8_COMPILER_CODE_STUB_ASSEMBLER_H_ |
OLD | NEW |