| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_FLOW_GRAPH_COMPILER_X64_H_ | 5 #ifndef VM_FLOW_GRAPH_COMPILER_X64_H_ |
| 6 #define VM_FLOW_GRAPH_COMPILER_X64_H_ | 6 #define VM_FLOW_GRAPH_COMPILER_X64_H_ |
| 7 | 7 |
| 8 #ifndef VM_FLOW_GRAPH_COMPILER_H_ | 8 #ifndef VM_FLOW_GRAPH_COMPILER_H_ |
| 9 #error Include flow_graph_compiler.h instead of flow_graph_compiler_x64.h. | 9 #error Include flow_graph_compiler.h instead of flow_graph_compiler_x64.h. |
| 10 #endif | 10 #endif |
| 11 | 11 |
| 12 #include "vm/assembler.h" | |
| 13 #include "vm/assembler_macros.h" | |
| 14 #include "vm/code_descriptors.h" | |
| 15 #include "vm/code_generator.h" | |
| 16 #include "vm/intermediate_language.h" | |
| 17 | |
| 18 namespace dart { | 12 namespace dart { |
| 19 | 13 |
| 20 class Code; | 14 class Code; |
| 21 class DeoptimizationStub; | 15 class DeoptimizationStub; |
| 22 class ExceptionHandlerList; | 16 class ExceptionHandlerList; |
| 23 template <typename T> class GrowableArray; | 17 template <typename T> class GrowableArray; |
| 24 class ParsedFunction; | 18 class ParsedFunction; |
| 25 | 19 |
| 26 class FlowGraphCompiler : public ValueObject { | 20 class FlowGraphCompiler : public ValueObject { |
| 27 private: | 21 private: |
| 28 struct BlockInfo : public ZoneAllocated { | 22 struct BlockInfo : public ZoneAllocated { |
| 29 public: | 23 public: |
| 30 BlockInfo() : label() { } | 24 BlockInfo() : label() { } |
| 31 Label label; | 25 Label label; |
| 32 }; | 26 }; |
| 33 | 27 |
| 34 public: | 28 public: |
| 35 FlowGraphCompiler(Assembler* assembler, | 29 FlowGraphCompiler(Assembler* assembler, |
| 36 const ParsedFunction& parsed_function, | 30 const ParsedFunction& parsed_function, |
| 37 const GrowableArray<BlockEntryInstr*>& block_order, | 31 const GrowableArray<BlockEntryInstr*>& block_order, |
| 38 bool is_optimizing); | 32 bool is_optimizing); |
| 39 | 33 |
| 40 virtual ~FlowGraphCompiler(); | 34 ~FlowGraphCompiler(); |
| 41 | 35 |
| 42 // Accessors. | 36 // Accessors. |
| 43 Assembler* assembler() const { return assembler_; } | 37 Assembler* assembler() const { return assembler_; } |
| 44 const ParsedFunction& parsed_function() const { return parsed_function_; } | 38 const ParsedFunction& parsed_function() const { return parsed_function_; } |
| 45 const GrowableArray<BlockEntryInstr*>& block_order() const { | 39 const GrowableArray<BlockEntryInstr*>& block_order() const { |
| 46 return block_order_; | 40 return block_order_; |
| 47 } | 41 } |
| 48 DescriptorList* pc_descriptors_list() const { | 42 DescriptorList* pc_descriptors_list() const { |
| 49 return pc_descriptors_list_; | 43 return pc_descriptors_list_; |
| 50 } | 44 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 68 | 62 |
| 69 void LoadDoubleOrSmiToXmm(XmmRegister result, | 63 void LoadDoubleOrSmiToXmm(XmmRegister result, |
| 70 Register reg, | 64 Register reg, |
| 71 Register temp, | 65 Register temp, |
| 72 Label* not_double_or_smi); | 66 Label* not_double_or_smi); |
| 73 | 67 |
| 74 // Returns 'true' if code generation for this function is complete, i.e., | 68 // Returns 'true' if code generation for this function is complete, i.e., |
| 75 // no fall-through to regular code is needed. | 69 // no fall-through to regular code is needed. |
| 76 bool TryIntrinsify(); | 70 bool TryIntrinsify(); |
| 77 | 71 |
| 78 virtual void GenerateCallRuntime(intptr_t cid, | 72 void GenerateCallRuntime(intptr_t cid, |
| 79 intptr_t token_index, | 73 intptr_t token_index, |
| 80 intptr_t try_index, | 74 intptr_t try_index, |
| 81 const RuntimeEntry& entry); | 75 const RuntimeEntry& entry); |
| 82 | 76 |
| 83 // Infrastructure copied from class CodeGenerator. | 77 // Infrastructure copied from class CodeGenerator. |
| 84 void GenerateCall(intptr_t token_index, | 78 void GenerateCall(intptr_t token_index, |
| 85 intptr_t try_index, | 79 intptr_t try_index, |
| 86 const ExternalLabel* label, | 80 const ExternalLabel* label, |
| 87 PcDescriptors::Kind kind); | 81 PcDescriptors::Kind kind); |
| 88 | 82 |
| 89 void GenerateAssertAssignable(intptr_t cid, | 83 void GenerateAssertAssignable(intptr_t cid, |
| 90 intptr_t token_index, | 84 intptr_t token_index, |
| 91 intptr_t try_index, | 85 intptr_t try_index, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 106 const Array& argument_names, | 100 const Array& argument_names, |
| 107 intptr_t checked_argument_count); | 101 intptr_t checked_argument_count); |
| 108 | 102 |
| 109 void GenerateStaticCall(intptr_t cid, | 103 void GenerateStaticCall(intptr_t cid, |
| 110 intptr_t token_index, | 104 intptr_t token_index, |
| 111 intptr_t try_index, | 105 intptr_t try_index, |
| 112 const Function& function, | 106 const Function& function, |
| 113 intptr_t argument_count, | 107 intptr_t argument_count, |
| 114 const Array& argument_names); | 108 const Array& argument_names); |
| 115 | 109 |
| 116 virtual void GenerateInlinedMathSqrt(Label* done); | 110 void GenerateInlinedMathSqrt(Label* done); |
| 117 | 111 |
| 118 void GenerateNumberTypeCheck(Register kClassIdReg, | 112 void GenerateNumberTypeCheck(Register kClassIdReg, |
| 119 const AbstractType& type, | 113 const AbstractType& type, |
| 120 Label* is_instance_lbl, | 114 Label* is_instance_lbl, |
| 121 Label* is_not_instance_lbl); | 115 Label* is_not_instance_lbl); |
| 122 void GenerateStringTypeCheck(Register kClassIdReg, | 116 void GenerateStringTypeCheck(Register kClassIdReg, |
| 123 Label* is_instance_lbl, | 117 Label* is_instance_lbl, |
| 124 Label* is_not_instance_lbl); | 118 Label* is_not_instance_lbl); |
| 125 void GenerateListTypeCheck(Register kClassIdReg, | 119 void GenerateListTypeCheck(Register kClassIdReg, |
| 126 Label* is_instance_lbl); | 120 Label* is_instance_lbl); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 void FinalizeExceptionHandlers(const Code& code); | 160 void FinalizeExceptionHandlers(const Code& code); |
| 167 void FinalizePcDescriptors(const Code& code); | 161 void FinalizePcDescriptors(const Code& code); |
| 168 void FinalizeStackmaps(const Code& code); | 162 void FinalizeStackmaps(const Code& code); |
| 169 void FinalizeVarDescriptors(const Code& code); | 163 void FinalizeVarDescriptors(const Code& code); |
| 170 void FinalizeComments(const Code& code); | 164 void FinalizeComments(const Code& code); |
| 171 | 165 |
| 172 const Bool& bool_true() const { return bool_true_; } | 166 const Bool& bool_true() const { return bool_true_; } |
| 173 const Bool& bool_false() const { return bool_false_; } | 167 const Bool& bool_false() const { return bool_false_; } |
| 174 const Class& double_class() const { return double_class_; } | 168 const Class& double_class() const { return double_class_; } |
| 175 | 169 |
| 170 FrameRegisterAllocator* frame_register_allocator() { |
| 171 return &frame_register_allocator_; |
| 172 } |
| 173 |
| 176 static const int kLocalsOffsetFromFP = (-1 * kWordSize); | 174 static const int kLocalsOffsetFromFP = (-1 * kWordSize); |
| 177 | 175 |
| 178 private: | 176 private: |
| 179 friend class DeoptimizationStub; | 177 friend class DeoptimizationStub; |
| 180 | 178 |
| 181 void GenerateDeferredCode(); | 179 void GenerateDeferredCode(); |
| 182 | 180 |
| 183 virtual void EmitInstructionPrologue(Instruction* instr); | 181 void EmitInstructionPrologue(Instruction* instr); |
| 184 | 182 |
| 185 // Emit code to load a Value into register 'dst'. | 183 // Emit code to load a Value into register 'dst'. |
| 186 void LoadValue(Register dst, Value* value); | 184 void LoadValue(Register dst, Value* value); |
| 187 | 185 |
| 188 // Returns pc-offset (in bytes) of the pc after the call, can be used to emit | 186 // Returns pc-offset (in bytes) of the pc after the call, can be used to emit |
| 189 // pc-descriptor information. | 187 // pc-descriptor information. |
| 190 virtual intptr_t EmitStaticCall(const Function& function, | 188 intptr_t EmitStaticCall(const Function& function, |
| 191 const Array& arguments_descriptor, | 189 const Array& arguments_descriptor, |
| 192 intptr_t argument_count); | 190 intptr_t argument_count); |
| 193 | 191 |
| 194 // Type checking helper methods. | 192 // Type checking helper methods. |
| 195 virtual void CheckClassIds(Register class_id_reg, | 193 void CheckClassIds(Register class_id_reg, |
| 196 const GrowableArray<intptr_t>& class_ids, | 194 const GrowableArray<intptr_t>& class_ids, |
| 197 Label* is_instance_lbl, | 195 Label* is_instance_lbl, |
| 198 Label* is_not_instance_lbl); | 196 Label* is_not_instance_lbl); |
| 199 | 197 |
| 200 RawSubtypeTestCache* GenerateInlineInstanceof(intptr_t cid, | 198 RawSubtypeTestCache* GenerateInlineInstanceof(intptr_t cid, |
| 201 intptr_t token_index, | 199 intptr_t token_index, |
| 202 const AbstractType& type, | 200 const AbstractType& type, |
| 203 Label* is_instance_lbl, | 201 Label* is_instance_lbl, |
| 204 Label* is_not_instance_lbl); | 202 Label* is_not_instance_lbl); |
| 205 | 203 |
| 206 RawSubtypeTestCache* GenerateInstantiatedTypeWithArgumentsTest( | 204 RawSubtypeTestCache* GenerateInstantiatedTypeWithArgumentsTest( |
| 207 intptr_t cid, | 205 intptr_t cid, |
| 208 intptr_t token_index, | 206 intptr_t token_index, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 Register instance_reg, | 238 Register instance_reg, |
| 241 Register type_arguments_reg, | 239 Register type_arguments_reg, |
| 242 Register temp_reg, | 240 Register temp_reg, |
| 243 Label* is_instance_lbl, | 241 Label* is_instance_lbl, |
| 244 Label* is_not_instance_lbl); | 242 Label* is_not_instance_lbl); |
| 245 | 243 |
| 246 void GenerateBoolToJump(Register bool_reg, Label* is_true, Label* is_false); | 244 void GenerateBoolToJump(Register bool_reg, Label* is_true, Label* is_false); |
| 247 | 245 |
| 248 void CopyParameters(); | 246 void CopyParameters(); |
| 249 | 247 |
| 250 virtual void GenerateInlinedGetter(intptr_t offset); | 248 void GenerateInlinedGetter(intptr_t offset); |
| 251 virtual void GenerateInlinedSetter(intptr_t offset); | 249 void GenerateInlinedSetter(intptr_t offset); |
| 252 | 250 |
| 253 // Map a block number in a forward iteration into the block number in the | 251 // Map a block number in a forward iteration into the block number in the |
| 254 // corresponding reverse iteration. Used to obtain an index into | 252 // corresponding reverse iteration. Used to obtain an index into |
| 255 // block_order for reverse iterations. | 253 // block_order for reverse iterations. |
| 256 intptr_t reverse_index(intptr_t index) const { | 254 intptr_t reverse_index(intptr_t index) const { |
| 257 return block_order_.length() - index - 1; | 255 return block_order_.length() - index - 1; |
| 258 } | 256 } |
| 259 | 257 |
| 260 class Assembler* assembler_; | 258 class Assembler* assembler_; |
| 261 const ParsedFunction& parsed_function_; | 259 const ParsedFunction& parsed_function_; |
| 262 const GrowableArray<BlockEntryInstr*>& block_order_; | 260 const GrowableArray<BlockEntryInstr*>& block_order_; |
| 263 | 261 |
| 264 // Compiler specific per-block state. Indexed by postorder block number | 262 // Compiler specific per-block state. Indexed by postorder block number |
| 265 // for convenience. This is not the block's index in the block order, | 263 // for convenience. This is not the block's index in the block order, |
| 266 // which is reverse postorder. | 264 // which is reverse postorder. |
| 267 BlockEntryInstr* current_block_; | 265 BlockEntryInstr* current_block_; |
| 268 ExceptionHandlerList* exception_handlers_list_; | 266 ExceptionHandlerList* exception_handlers_list_; |
| 269 DescriptorList* pc_descriptors_list_; | 267 DescriptorList* pc_descriptors_list_; |
| 270 StackmapBuilder* stackmap_builder_; | 268 StackmapBuilder* stackmap_builder_; |
| 271 GrowableArray<BlockInfo*> block_info_; | 269 GrowableArray<BlockInfo*> block_info_; |
| 272 GrowableArray<DeoptimizationStub*> deopt_stubs_; | 270 GrowableArray<DeoptimizationStub*> deopt_stubs_; |
| 273 const bool is_optimizing_; | 271 const bool is_optimizing_; |
| 274 | 272 |
| 275 const Bool& bool_true_; | 273 const Bool& bool_true_; |
| 276 const Bool& bool_false_; | 274 const Bool& bool_false_; |
| 277 const Class& double_class_; | 275 const Class& double_class_; |
| 278 | 276 |
| 277 FrameRegisterAllocator frame_register_allocator_; |
| 278 |
| 279 DISALLOW_COPY_AND_ASSIGN(FlowGraphCompiler); | 279 DISALLOW_COPY_AND_ASSIGN(FlowGraphCompiler); |
| 280 }; | 280 }; |
| 281 | 281 |
| 282 | 282 |
| 283 class DeoptimizationStub : public ZoneAllocated { | 283 class DeoptimizationStub : public ZoneAllocated { |
| 284 public: | 284 public: |
| 285 DeoptimizationStub(intptr_t deopt_id, | 285 DeoptimizationStub(intptr_t deopt_id, |
| 286 intptr_t deopt_token_index, | 286 intptr_t deopt_token_index, |
| 287 intptr_t try_index, | 287 intptr_t try_index, |
| 288 DeoptReasonId reason) | 288 DeoptReasonId reason) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 306 const DeoptReasonId reason_; | 306 const DeoptReasonId reason_; |
| 307 GrowableArray<Register> registers_; | 307 GrowableArray<Register> registers_; |
| 308 Label entry_label_; | 308 Label entry_label_; |
| 309 | 309 |
| 310 DISALLOW_COPY_AND_ASSIGN(DeoptimizationStub); | 310 DISALLOW_COPY_AND_ASSIGN(DeoptimizationStub); |
| 311 }; | 311 }; |
| 312 | 312 |
| 313 } // namespace dart | 313 } // namespace dart |
| 314 | 314 |
| 315 #endif // VM_FLOW_GRAPH_COMPILER_X64_H_ | 315 #endif // VM_FLOW_GRAPH_COMPILER_X64_H_ |
| OLD | NEW |