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_IA32_H_ | 5 #ifndef VM_FLOW_GRAPH_COMPILER_IA32_H_ |
6 #define VM_FLOW_GRAPH_COMPILER_IA32_H_ | 6 #define VM_FLOW_GRAPH_COMPILER_IA32_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_ia32.h. | 9 #error Include flow_graph_compiler.h instead of flow_graph_compiler_ia32.h. |
10 #endif | 10 #endif |
11 | 11 |
12 #include "vm/assembler.h" | 12 #include "vm/assembler.h" |
13 #include "vm/assembler_macros.h" | 13 #include "vm/assembler_macros.h" |
14 #include "vm/code_descriptors.h" | 14 #include "vm/code_descriptors.h" |
15 #include "vm/code_generator.h" | 15 #include "vm/code_generator.h" |
16 #include "vm/flow_graph_compiler_shared.h" | |
17 #include "vm/intermediate_language.h" | 16 #include "vm/intermediate_language.h" |
18 | 17 |
19 namespace dart { | 18 namespace dart { |
20 | 19 |
21 class AbstractType; | 20 class AbstractType; |
22 class Assembler; | 21 class Assembler; |
23 class Code; | 22 class Code; |
24 class DeoptimizationStub; | 23 class DeoptimizationStub; |
25 template <typename T> class GrowableArray; | 24 template <typename T> class GrowableArray; |
26 class ParsedFunction; | 25 class ParsedFunction; |
27 class StackMapBuilder; | 26 class StackMapBuilder; |
28 | 27 |
29 // Stubbed out implementation of graph compiler, bails out immediately if | 28 // Stubbed out implementation of graph compiler, bails out immediately if |
30 // CompileGraph is called. The rest of the public API is UNIMPLEMENTED. | 29 // CompileGraph is called. The rest of the public API is UNIMPLEMENTED. |
31 class FlowGraphCompiler : public FlowGraphCompilerShared { | 30 class FlowGraphCompiler : public ValueObject { |
| 31 private: |
| 32 struct BlockInfo : public ZoneAllocated { |
| 33 public: |
| 34 BlockInfo() : label() { } |
| 35 Label label; |
| 36 }; |
| 37 |
32 public: | 38 public: |
33 FlowGraphCompiler(Assembler* assembler, | 39 FlowGraphCompiler(Assembler* assembler, |
34 const ParsedFunction& parsed_function, | 40 const ParsedFunction& parsed_function, |
35 const GrowableArray<BlockEntryInstr*>& block_order, | 41 const GrowableArray<BlockEntryInstr*>& block_order, |
36 bool is_optimizing); | 42 bool is_optimizing); |
37 | 43 |
| 44 virtual ~FlowGraphCompiler(); |
| 45 |
| 46 // Accessors. |
| 47 Assembler* assembler() const { return assembler_; } |
| 48 const ParsedFunction& parsed_function() const { return parsed_function_; } |
| 49 const GrowableArray<BlockEntryInstr*>& block_order() const { |
| 50 return block_order_; |
| 51 } |
| 52 DescriptorList* pc_descriptors_list() const { |
| 53 return pc_descriptors_list_; |
| 54 } |
| 55 BlockEntryInstr* current_block() const { return current_block_; } |
| 56 void set_current_block(BlockEntryInstr* value) { |
| 57 current_block_ = value; |
| 58 } |
| 59 bool is_optimizing() const { return is_optimizing_; } |
| 60 const GrowableArray<BlockInfo*>& block_info() const { return block_info_; } |
| 61 |
| 62 // Constructor is lighweight, major initialization work should occur here. |
| 63 // This makes it easier to measure time spent in the compiler. |
| 64 void InitCompiler(); |
| 65 |
38 void CompileGraph(); | 66 void CompileGraph(); |
39 | 67 |
40 void GenerateCallRuntime(intptr_t cid, | 68 void VisitBlocks(); |
41 intptr_t token_index, | |
42 intptr_t try_index, | |
43 const RuntimeEntry& entry); | |
44 | 69 |
45 // Returns pc-offset (in bytes) of the pc after the call, can be used to emit | 70 // Bail out of the flow graph compiler. Does not return to the caller. |
46 // pc-descriptor information. | 71 void Bailout(const char* reason); |
47 virtual intptr_t EmitInstanceCall(ExternalLabel* target_label, | 72 |
48 const ICData& ic_data, | 73 // Returns 'true' if code generation for this function is complete, i.e., |
49 const Array& arguments_descriptor, | 74 // no fall-through to regular code is needed. |
50 intptr_t argument_count); | 75 bool TryIntrinsify(); |
| 76 |
| 77 virtual void GenerateCallRuntime(intptr_t cid, |
| 78 intptr_t token_index, |
| 79 intptr_t try_index, |
| 80 const RuntimeEntry& entry); |
51 | 81 |
52 // Returns pc-offset (in bytes) of the pc after the call, can be used to emit | 82 // Returns pc-offset (in bytes) of the pc after the call, can be used to emit |
53 // pc-descriptor information. | 83 // pc-descriptor information. |
54 virtual intptr_t EmitStaticCall(const Function& function, | 84 virtual intptr_t EmitStaticCall(const Function& function, |
55 const Array& arguments_descriptor, | 85 const Array& arguments_descriptor, |
56 intptr_t argument_count); | 86 intptr_t argument_count); |
57 | 87 |
58 void GenerateCall(intptr_t token_index, | 88 virtual void GenerateCall(intptr_t token_index, |
59 intptr_t try_index, | 89 intptr_t try_index, |
60 const ExternalLabel* label, | 90 const ExternalLabel* label, |
61 PcDescriptors::Kind kind); | 91 PcDescriptors::Kind kind); |
62 void GenerateInstanceOf(intptr_t cid, | 92 virtual void GenerateInstanceOf(intptr_t cid, |
| 93 intptr_t token_index, |
| 94 intptr_t try_index, |
| 95 const AbstractType& type, |
| 96 bool negate_result); |
| 97 virtual void GenerateAssertAssignable(intptr_t cid, |
| 98 intptr_t token_index, |
| 99 intptr_t try_index, |
| 100 const AbstractType& dst_type, |
| 101 const String& dst_name); |
| 102 |
| 103 void GenerateInstanceCall(intptr_t cid, |
| 104 intptr_t token_index, |
| 105 intptr_t try_index, |
| 106 const String& function_name, |
| 107 intptr_t argument_count, |
| 108 const Array& argument_names, |
| 109 intptr_t checked_argument_count); |
| 110 |
| 111 void GenerateStaticCall(intptr_t cid, |
63 intptr_t token_index, | 112 intptr_t token_index, |
64 intptr_t try_index, | 113 intptr_t try_index, |
65 const AbstractType& type, | 114 const Function& function, |
66 bool negate_result); | 115 intptr_t argument_count, |
67 void GenerateAssertAssignable(intptr_t cid, | 116 const Array& argument_names); |
68 intptr_t token_index, | 117 |
69 intptr_t try_index, | 118 void GenerateNumberTypeCheck(Register kClassIdReg, |
70 const AbstractType& dst_type, | 119 const AbstractType& type, |
71 const String& dst_name); | 120 Label* is_instance_lbl, |
| 121 Label* is_not_instance_lbl); |
| 122 void GenerateStringTypeCheck(Register kClassIdReg, |
| 123 Label* is_instance_lbl, |
| 124 Label* is_not_instance_lbl); |
| 125 void GenerateListTypeCheck(Register kClassIdReg, |
| 126 Label* is_instance_lbl); |
| 127 |
| 128 // Returns pc-offset (in bytes) of the pc after the call, can be used to emit |
| 129 // pc-descriptor information. |
| 130 intptr_t EmitInstanceCall(ExternalLabel* target_label, |
| 131 const ICData& ic_data, |
| 132 const Array& arguments_descriptor, |
| 133 intptr_t argument_count); |
| 134 |
| 135 void EmitComment(Instruction* instr); |
| 136 |
| 137 intptr_t StackSize() const; |
| 138 |
| 139 // Returns assembler label associated with the given block entry. |
| 140 Label* GetBlockLabel(BlockEntryInstr* block_entry) const; |
| 141 |
| 142 // Returns true if the next block after current in the current block order |
| 143 // is the given block. |
| 144 bool IsNextBlock(TargetEntryInstr* block_entry) const; |
| 145 |
| 146 void AddExceptionHandler(intptr_t try_index, intptr_t pc_offset); |
| 147 void AddCurrentDescriptor(PcDescriptors::Kind kind, |
| 148 intptr_t cid, |
| 149 intptr_t token_index, |
| 150 intptr_t try_index); |
| 151 Label* AddDeoptStub(intptr_t deopt_id, |
| 152 intptr_t deopt_token_index, |
| 153 intptr_t try_index_, |
| 154 DeoptReasonId reason, |
| 155 Register reg1, |
| 156 Register reg2); |
| 157 |
| 158 void FinalizeExceptionHandlers(const Code& code); |
| 159 void FinalizePcDescriptors(const Code& code); |
| 160 void FinalizeStackmaps(const Code& code); |
| 161 void FinalizeVarDescriptors(const Code& code); |
| 162 void FinalizeComments(const Code& code); |
| 163 |
| 164 static const int kLocalsOffsetFromFP = (-1 * kWordSize); |
72 | 165 |
73 private: | 166 private: |
74 friend class DeoptimizationStub; | 167 friend class DeoptimizationStub; |
75 | 168 |
76 virtual void VisitBlocks(); | 169 void GenerateDeferredCode(); |
77 | 170 |
78 void CopyParameters(); | 171 void CopyParameters(); |
79 void EmitInstructionPrologue(Instruction* instr); | 172 virtual void EmitInstructionPrologue(Instruction* instr); |
80 | 173 |
81 virtual void GenerateInlinedGetter(intptr_t offset); | 174 virtual void GenerateInlinedGetter(intptr_t offset); |
82 virtual void GenerateInlinedSetter(intptr_t offset); | 175 virtual void GenerateInlinedSetter(intptr_t offset); |
83 | 176 |
84 RawSubtypeTestCache* GenerateInlineInstanceof(intptr_t cid, | 177 RawSubtypeTestCache* GenerateInlineInstanceof(intptr_t cid, |
85 intptr_t token_index, | 178 intptr_t token_index, |
86 const AbstractType& type, | 179 const AbstractType& type, |
87 Label* is_instance_lbl, | 180 Label* is_instance_lbl, |
88 Label* is_not_instance_lbl); | 181 Label* is_not_instance_lbl); |
89 | 182 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 Label* is_instance_lbl, | 220 Label* is_instance_lbl, |
128 Label* is_not_instance_lbl); | 221 Label* is_not_instance_lbl); |
129 | 222 |
130 void GenerateBoolToJump(Register bool_reg, Label* is_true, Label* is_false); | 223 void GenerateBoolToJump(Register bool_reg, Label* is_true, Label* is_false); |
131 | 224 |
132 virtual void CheckClassIds(Register class_id_reg, | 225 virtual void CheckClassIds(Register class_id_reg, |
133 const GrowableArray<intptr_t>& class_ids, | 226 const GrowableArray<intptr_t>& class_ids, |
134 Label* is_equal_lbl, | 227 Label* is_equal_lbl, |
135 Label* is_not_equal_lbl); | 228 Label* is_not_equal_lbl); |
136 | 229 |
137 void EmitComment(Instruction* instr); | 230 |
138 void BailoutOnInstruction(Instruction* instr); | 231 // Map a block number in a forward iteration into the block number in the |
| 232 // corresponding reverse iteration. Used to obtain an index into |
| 233 // block_order for reverse iterations. |
| 234 intptr_t reverse_index(intptr_t index) const { |
| 235 return block_order_.length() - index - 1; |
| 236 } |
| 237 |
| 238 class Assembler* assembler_; |
| 239 const ParsedFunction& parsed_function_; |
| 240 const GrowableArray<BlockEntryInstr*>& block_order_; |
| 241 |
| 242 // Compiler specific per-block state. Indexed by postorder block number |
| 243 // for convenience. This is not the block's index in the block order, |
| 244 // which is reverse postorder. |
| 245 BlockEntryInstr* current_block_; |
| 246 ExceptionHandlerList* exception_handlers_list_; |
| 247 DescriptorList* pc_descriptors_list_; |
| 248 StackmapBuilder* stackmap_builder_; |
| 249 GrowableArray<BlockInfo*> block_info_; |
| 250 GrowableArray<DeoptimizationStub*> deopt_stubs_; |
| 251 const bool is_optimizing_; |
139 | 252 |
140 DISALLOW_COPY_AND_ASSIGN(FlowGraphCompiler); | 253 DISALLOW_COPY_AND_ASSIGN(FlowGraphCompiler); |
141 }; | 254 }; |
142 | 255 |
| 256 |
| 257 class DeoptimizationStub : public ZoneAllocated { |
| 258 public: |
| 259 DeoptimizationStub(intptr_t deopt_id, |
| 260 intptr_t deopt_token_index, |
| 261 intptr_t try_index, |
| 262 DeoptReasonId reason) |
| 263 : deopt_id_(deopt_id), |
| 264 deopt_token_index_(deopt_token_index), |
| 265 try_index_(try_index), |
| 266 reason_(reason), |
| 267 registers_(2), |
| 268 entry_label_() {} |
| 269 |
| 270 void Push(Register reg) { registers_.Add(reg); } |
| 271 Label* entry_label() { return &entry_label_; } |
| 272 |
| 273 // Implementation is in architecture specific file. |
| 274 void GenerateCode(FlowGraphCompiler* compiler); |
| 275 |
| 276 private: |
| 277 const intptr_t deopt_id_; |
| 278 const intptr_t deopt_token_index_; |
| 279 const intptr_t try_index_; |
| 280 const DeoptReasonId reason_; |
| 281 GrowableArray<Register> registers_; |
| 282 Label entry_label_; |
| 283 |
| 284 DISALLOW_COPY_AND_ASSIGN(DeoptimizationStub); |
| 285 }; |
| 286 |
| 287 |
143 } // namespace dart | 288 } // namespace dart |
144 | 289 |
145 #endif // VM_FLOW_GRAPH_COMPILER_IA32_H_ | 290 #endif // VM_FLOW_GRAPH_COMPILER_IA32_H_ |
OLD | NEW |