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_ASSEMBLER_H_ | 5 #ifndef V8_COMPILER_CODE_ASSEMBLER_H_ |
6 #define V8_COMPILER_CODE_ASSEMBLER_H_ | 6 #define V8_COMPILER_CODE_ASSEMBLER_H_ |
7 | 7 |
8 #include <map> | 8 #include <map> |
9 #include <memory> | 9 #include <memory> |
10 | 10 |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
166 // V8 components that need to generate low-level code using this interface | 166 // V8 components that need to generate low-level code using this interface |
167 // should include this header--and this header only--from the compiler directory | 167 // should include this header--and this header only--from the compiler directory |
168 // (this is actually enforced). Since all interesting data structures are | 168 // (this is actually enforced). Since all interesting data structures are |
169 // forward declared, it's not possible for clients to peek inside the compiler | 169 // forward declared, it's not possible for clients to peek inside the compiler |
170 // internals. | 170 // internals. |
171 // | 171 // |
172 // In addition to providing isolation between TurboFan and code generation | 172 // In addition to providing isolation between TurboFan and code generation |
173 // clients, CodeAssembler also provides an abstraction for creating variables | 173 // clients, CodeAssembler also provides an abstraction for creating variables |
174 // and enhanced Label functionality to merge variable values along paths where | 174 // and enhanced Label functionality to merge variable values along paths where |
175 // they have differing values, including loops. | 175 // they have differing values, including loops. |
176 // | |
177 // The CodeAssembler itself is stateless (and instances are expected to be | |
178 // temporary-scoped and short-lived); all its state is encapsulated into | |
179 // a CodeAssemblerState instance. | |
180 | |
181 class CodeAssemblerState; | |
Michael Starzinger
2016/11/15 11:45:20
nit: Please move this forward declaration up to th
Jakob Kummerow
2016/11/15 13:40:32
Done.
| |
182 | |
176 class V8_EXPORT_PRIVATE CodeAssembler { | 183 class V8_EXPORT_PRIVATE CodeAssembler { |
177 public: | 184 public: |
178 // Create with CallStub linkage. | 185 explicit CodeAssembler(CodeAssemblerState* state) : state_(state) {} |
179 // |result_size| specifies the number of results returned by the stub. | |
180 // TODO(rmcilroy): move result_size to the CallInterfaceDescriptor. | |
181 CodeAssembler(Isolate* isolate, Zone* zone, | |
182 const CallInterfaceDescriptor& descriptor, Code::Flags flags, | |
183 const char* name, size_t result_size = 1); | |
184 | |
185 // Create with JSCall linkage. | |
186 CodeAssembler(Isolate* isolate, Zone* zone, int parameter_count, | |
187 Code::Flags flags, const char* name); | |
188 | 186 |
189 virtual ~CodeAssembler(); | 187 virtual ~CodeAssembler(); |
190 | 188 |
191 Handle<Code> GenerateCode(); | 189 Handle<Code> GenerateCode(); |
192 | 190 |
193 bool Is64() const; | 191 bool Is64() const; |
194 bool IsFloat64RoundUpSupported() const; | 192 bool IsFloat64RoundUpSupported() const; |
195 bool IsFloat64RoundDownSupported() const; | 193 bool IsFloat64RoundDownSupported() const; |
196 bool IsFloat64RoundTruncateSupported() const; | 194 bool IsFloat64RoundTruncateSupported() const; |
197 | 195 |
198 class Label; | 196 class Label; |
199 class Variable { | 197 class Variable { |
200 public: | 198 public: |
201 explicit Variable(CodeAssembler* assembler, MachineRepresentation rep); | 199 explicit Variable(CodeAssembler* assembler, MachineRepresentation rep); |
202 ~Variable(); | 200 ~Variable(); |
203 void Bind(Node* value); | 201 void Bind(Node* value); |
204 Node* value() const; | 202 Node* value() const; |
205 MachineRepresentation rep() const; | 203 MachineRepresentation rep() const; |
206 bool IsBound() const; | 204 bool IsBound() const; |
207 | 205 |
208 private: | 206 private: |
209 friend class CodeAssembler; | 207 friend class CodeAssembler; |
208 friend class CodeAssemblerState; | |
210 class Impl; | 209 class Impl; |
211 Impl* impl_; | 210 Impl* impl_; |
212 CodeAssembler* assembler_; | 211 CodeAssembler* assembler_; |
213 }; | 212 }; |
214 | 213 |
215 typedef ZoneList<Variable*> VariableList; | 214 typedef ZoneList<Variable*> VariableList; |
216 | 215 |
217 // =========================================================================== | 216 // =========================================================================== |
218 // Base Assembler | 217 // Base Assembler |
219 // =========================================================================== | 218 // =========================================================================== |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
464 Factory* factory() const; | 463 Factory* factory() const; |
465 Isolate* isolate() const; | 464 Isolate* isolate() const; |
466 Zone* zone() const; | 465 Zone* zone() const; |
467 | 466 |
468 protected: | 467 protected: |
469 // Enables subclasses to perform operations before and after a call. | 468 // Enables subclasses to perform operations before and after a call. |
470 virtual void CallPrologue(); | 469 virtual void CallPrologue(); |
471 virtual void CallEpilogue(); | 470 virtual void CallEpilogue(); |
472 | 471 |
473 private: | 472 private: |
474 CodeAssembler(Isolate* isolate, Zone* zone, CallDescriptor* call_descriptor, | |
475 Code::Flags flags, const char* name); | |
476 | |
477 Node* CallN(CallDescriptor* descriptor, Node* code_target, Node** args); | 473 Node* CallN(CallDescriptor* descriptor, Node* code_target, Node** args); |
478 Node* TailCallN(CallDescriptor* descriptor, Node* code_target, Node** args); | 474 Node* TailCallN(CallDescriptor* descriptor, Node* code_target, Node** args); |
479 | 475 |
480 std::unique_ptr<RawMachineAssembler> raw_assembler_; | 476 RawMachineAssembler* raw_assembler() const; |
481 Code::Flags flags_; | 477 |
482 const char* name_; | 478 CodeAssemblerState* state_; |
483 bool code_generated_; | |
484 ZoneSet<Variable::Impl*> variables_; | |
485 | 479 |
486 DISALLOW_COPY_AND_ASSIGN(CodeAssembler); | 480 DISALLOW_COPY_AND_ASSIGN(CodeAssembler); |
487 }; | 481 }; |
488 | 482 |
489 class CodeAssembler::Label { | 483 class CodeAssembler::Label { |
490 public: | 484 public: |
491 enum Type { kDeferred, kNonDeferred }; | 485 enum Type { kDeferred, kNonDeferred }; |
492 | 486 |
493 explicit Label( | 487 explicit Label( |
494 CodeAssembler* assembler, | 488 CodeAssembler* assembler, |
(...skipping 21 matching lines...) Expand all Loading... | |
516 CodeAssembler* assembler_; | 510 CodeAssembler* assembler_; |
517 RawMachineLabel* label_; | 511 RawMachineLabel* label_; |
518 // Map of variables that need to be merged to their phi nodes (or placeholders | 512 // Map of variables that need to be merged to their phi nodes (or placeholders |
519 // for those phis). | 513 // for those phis). |
520 std::map<Variable::Impl*, Node*> variable_phis_; | 514 std::map<Variable::Impl*, Node*> variable_phis_; |
521 // Map of variables to the list of value nodes that have been added from each | 515 // Map of variables to the list of value nodes that have been added from each |
522 // merge path in their order of merging. | 516 // merge path in their order of merging. |
523 std::map<Variable::Impl*, std::vector<Node*>> variable_merges_; | 517 std::map<Variable::Impl*, std::vector<Node*>> variable_merges_; |
524 }; | 518 }; |
525 | 519 |
520 class V8_EXPORT_PRIVATE CodeAssemblerState { | |
Michael Starzinger
2016/11/15 11:45:20
nit: Can we make this final?
Igor Sheludko
2016/11/15 13:06:35
Thinking out loud: we could even hide this class i
Jakob Kummerow
2016/11/15 13:40:32
We could do that. But then we can't heap-allocate
Jakob Kummerow
2016/11/15 13:40:32
I'd love to; but see comment on unit test.
Igor Sheludko
2016/11/15 14:02:53
Ah, I missed the DISALLOW_COPY_AND_ASSIGN thing.
| |
521 public: | |
522 // Create with CallStub linkage. | |
523 // |result_size| specifies the number of results returned by the stub. | |
524 // TODO(rmcilroy): move result_size to the CallInterfaceDescriptor. | |
525 CodeAssemblerState(Isolate* isolate, Zone* zone, | |
526 const CallInterfaceDescriptor& descriptor, | |
527 Code::Flags flags, const char* name, | |
528 size_t result_size = 1); | |
529 | |
530 // Create with JSCall linkage. | |
531 CodeAssemblerState(Isolate* isolate, Zone* zone, int parameter_count, | |
532 Code::Flags flags, const char* name); | |
533 | |
534 ~CodeAssemblerState(); | |
535 | |
536 Handle<Code> GenerateCode(); | |
Michael Starzinger
2016/11/15 11:45:20
Can we move this back to the {CodeAssembler} class
Igor Sheludko
2016/11/15 13:06:35
If we do that then we will not be able to generate
Jakob Kummerow
2016/11/15 13:40:32
Summarizing offline discussion:
- The argument in
Igor Sheludko
2016/11/15 14:02:53
Awesome!
| |
537 | |
538 private: | |
539 friend class CodeAssembler; | |
540 | |
541 CodeAssemblerState(Isolate* isolate, Zone* zone, | |
542 CallDescriptor* call_descriptor, Code::Flags flags, | |
543 const char* name); | |
544 | |
545 std::unique_ptr<RawMachineAssembler> raw_assembler_; | |
546 Code::Flags flags_; | |
547 const char* name_; | |
548 bool code_generated_; | |
549 ZoneSet<CodeAssembler::Variable::Impl*> variables_; | |
550 | |
551 DISALLOW_COPY_AND_ASSIGN(CodeAssemblerState); | |
552 }; | |
553 | |
526 } // namespace compiler | 554 } // namespace compiler |
527 } // namespace internal | 555 } // namespace internal |
528 } // namespace v8 | 556 } // namespace v8 |
529 | 557 |
530 #endif // V8_COMPILER_CODE_ASSEMBLER_H_ | 558 #endif // V8_COMPILER_CODE_ASSEMBLER_H_ |
OLD | NEW |