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_BUILDER_H_ | 5 #ifndef VM_FLOW_GRAPH_BUILDER_H_ |
6 #define VM_FLOW_GRAPH_BUILDER_H_ | 6 #define VM_FLOW_GRAPH_BUILDER_H_ |
7 | 7 |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "platform/globals.h" | 9 #include "platform/globals.h" |
10 #include "vm/allocation.h" | 10 #include "vm/allocation.h" |
11 #include "vm/ast.h" | 11 #include "vm/ast.h" |
12 #include "vm/growable_array.h" | 12 #include "vm/growable_array.h" |
13 #include "vm/intermediate_language.h" | 13 #include "vm/intermediate_language.h" |
14 #include "vm/raw_object.h" | 14 #include "vm/raw_object.h" |
15 | 15 |
16 namespace dart { | 16 namespace dart { |
17 | 17 |
18 class AbstractType; | 18 class AbstractType; |
19 class AbstractTypeArguments; | 19 class AbstractTypeArguments; |
20 class Array; | 20 class Array; |
21 class Class; | 21 class Class; |
22 class Field; | 22 class Field; |
23 class FlowGraph; | 23 class FlowGraph; |
24 class LocalVariable; | 24 class LocalVariable; |
25 class ParsedFunction; | 25 class ParsedFunction; |
26 class String; | 26 class String; |
27 | 27 |
| 28 class NestedStatement; |
| 29 class TestGraphVisitor; |
| 30 |
28 // List of recognized list factories: | 31 // List of recognized list factories: |
29 // (factory-name-symbol, result-cid, fingerprint). | 32 // (factory-name-symbol, result-cid, fingerprint). |
30 // TODO(srdjan): Store the values in the snapshot instead. | 33 // TODO(srdjan): Store the values in the snapshot instead. |
31 #define RECOGNIZED_LIST_FACTORY_LIST(V) \ | 34 #define RECOGNIZED_LIST_FACTORY_LIST(V) \ |
32 V(_ListFactory, kArrayCid, 176587978) \ | 35 V(_ListFactory, kArrayCid, 176587978) \ |
33 V(_GrowableListWithData, kGrowableObjectArrayCid, 264792196) \ | 36 V(_GrowableListWithData, kGrowableObjectArrayCid, 264792196) \ |
34 V(_GrowableListFactory, kGrowableObjectArrayCid, 1720763678) \ | 37 V(_GrowableListFactory, kGrowableObjectArrayCid, 1720763678) \ |
35 V(_Int8ArrayFactory, kTypedDataInt8ArrayCid, 545976988) \ | 38 V(_Int8ArrayFactory, kTypedDataInt8ArrayCid, 545976988) \ |
36 V(_Uint8ArrayFactory, kTypedDataUint8ArrayCid, 981297074) \ | 39 V(_Uint8ArrayFactory, kTypedDataUint8ArrayCid, 981297074) \ |
37 V(_Uint8ClampedArrayFactory, kTypedDataUint8ClampedArrayCid, 1617830104) \ | 40 V(_Uint8ClampedArrayFactory, kTypedDataUint8ClampedArrayCid, 1617830104) \ |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 | 102 |
100 Definition* JoinReturns(BlockEntryInstr** exit_block, | 103 Definition* JoinReturns(BlockEntryInstr** exit_block, |
101 Instruction** last_instruction); | 104 Instruction** last_instruction); |
102 | 105 |
103 FlowGraph* caller_graph_; | 106 FlowGraph* caller_graph_; |
104 Definition* call_; | 107 Definition* call_; |
105 GrowableArray<Data> exits_; | 108 GrowableArray<Data> exits_; |
106 }; | 109 }; |
107 | 110 |
108 | 111 |
109 class NestedStatement; | |
110 | |
111 // Build a flow graph from a parsed function's AST. | 112 // Build a flow graph from a parsed function's AST. |
112 class FlowGraphBuilder: public ValueObject { | 113 class FlowGraphBuilder: public ValueObject { |
113 public: | 114 public: |
114 // The inlining context is NULL if not inlining. The osr_id is the deopt | 115 // The inlining context is NULL if not inlining. The osr_id is the deopt |
115 // id of the OSR entry or Isolate::kNoDeoptId if not compiling for OSR. | 116 // id of the OSR entry or Isolate::kNoDeoptId if not compiling for OSR. |
116 FlowGraphBuilder(ParsedFunction* parsed_function, | 117 FlowGraphBuilder(ParsedFunction* parsed_function, |
117 const Array& ic_data_array, | 118 const Array& ic_data_array, |
118 InlineExitCollector* exit_collector, | 119 InlineExitCollector* exit_collector, |
119 intptr_t osr_id); | 120 intptr_t osr_id); |
120 | 121 |
121 FlowGraph* BuildGraph(); | 122 FlowGraph* BuildGraph(); |
122 | 123 |
123 ParsedFunction* parsed_function() const { return parsed_function_; } | 124 ParsedFunction* parsed_function() const { return parsed_function_; } |
124 const Array& ic_data_array() const { return ic_data_array_; } | 125 const Array& ic_data_array() const { return ic_data_array_; } |
125 | 126 |
126 void Bailout(const char* reason); | 127 void Bailout(const char* reason); |
127 | 128 |
128 intptr_t AllocateBlockId() { return ++last_used_block_id_; } | 129 intptr_t AllocateBlockId() { return ++last_used_block_id_; } |
129 void SetInitialBlockId(intptr_t id) { last_used_block_id_ = id; } | 130 void SetInitialBlockId(intptr_t id) { last_used_block_id_ = id; } |
130 | 131 |
131 void set_context_level(intptr_t value) { context_level_ = value; } | 132 intptr_t context_level() const; |
132 intptr_t context_level() const { return context_level_; } | |
133 | 133 |
134 void IncrementLoopDepth() { ++loop_depth_; } | 134 void IncrementLoopDepth() { ++loop_depth_; } |
135 void DecrementLoopDepth() { --loop_depth_; } | 135 void DecrementLoopDepth() { --loop_depth_; } |
136 intptr_t loop_depth() const { return loop_depth_; } | 136 intptr_t loop_depth() const { return loop_depth_; } |
137 | 137 |
138 // Manage the currently active try index. | 138 // Manage the currently active try index. |
139 void set_try_index(intptr_t value) { try_index_ = value; } | 139 void set_try_index(intptr_t value) { try_index_ = value; } |
140 intptr_t try_index() const { return try_index_; } | 140 intptr_t try_index() const { return try_index_; } |
141 | 141 |
142 // Manage the currently active catch-handler try index. | 142 // Manage the currently active catch-handler try index. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 ParsedFunction* parsed_function_; | 191 ParsedFunction* parsed_function_; |
192 const Array& ic_data_array_; | 192 const Array& ic_data_array_; |
193 | 193 |
194 const intptr_t num_copied_params_; | 194 const intptr_t num_copied_params_; |
195 const intptr_t num_non_copied_params_; | 195 const intptr_t num_non_copied_params_; |
196 const intptr_t num_stack_locals_; // Does not include any parameters. | 196 const intptr_t num_stack_locals_; // Does not include any parameters. |
197 InlineExitCollector* const exit_collector_; | 197 InlineExitCollector* const exit_collector_; |
198 ZoneGrowableArray<const Field*>* guarded_fields_; | 198 ZoneGrowableArray<const Field*>* guarded_fields_; |
199 | 199 |
200 intptr_t last_used_block_id_; | 200 intptr_t last_used_block_id_; |
201 intptr_t context_level_; | |
202 intptr_t try_index_; | 201 intptr_t try_index_; |
203 intptr_t catch_try_index_; | 202 intptr_t catch_try_index_; |
204 intptr_t loop_depth_; | 203 intptr_t loop_depth_; |
205 GraphEntryInstr* graph_entry_; | 204 GraphEntryInstr* graph_entry_; |
206 | 205 |
207 // The expression stack height. | 206 // The expression stack height. |
208 intptr_t temp_count_; | 207 intptr_t temp_count_; |
209 | 208 |
210 // Outgoing argument stack height. | 209 // Outgoing argument stack height. |
211 intptr_t args_pushed_; | 210 intptr_t args_pushed_; |
212 | 211 |
213 // A stack of enclosing nested statements. | 212 // A stack of enclosing nested statements. |
214 NestedStatement* nesting_stack_; | 213 NestedStatement* nesting_stack_; |
215 | 214 |
216 // The deopt id of the OSR entry or Isolate::kNoDeoptId if not compiling | 215 // The deopt id of the OSR entry or Isolate::kNoDeoptId if not compiling |
217 // for OSR. | 216 // for OSR. |
218 const intptr_t osr_id_; | 217 const intptr_t osr_id_; |
219 | 218 |
220 DISALLOW_IMPLICIT_CONSTRUCTORS(FlowGraphBuilder); | 219 DISALLOW_IMPLICIT_CONSTRUCTORS(FlowGraphBuilder); |
221 }; | 220 }; |
222 | 221 |
223 | 222 |
224 // Base class for a stack of enclosing statements of interest (e.g., | |
225 // blocks (breakable) and loops (continuable)). | |
226 class NestedStatement : public ValueObject { | |
227 public: | |
228 NestedStatement(FlowGraphBuilder* owner, const SourceLabel* label) | |
229 : owner_(owner), | |
230 label_(label), | |
231 outer_(owner->nesting_stack_), | |
232 break_target_(NULL) { | |
233 // Push on the owner's nesting stack. | |
234 owner->nesting_stack_ = this; | |
235 } | |
236 | |
237 virtual ~NestedStatement() { | |
238 // Pop from the owner's nesting stack. | |
239 ASSERT(owner_->nesting_stack_ == this); | |
240 owner_->nesting_stack_ = outer_; | |
241 } | |
242 | |
243 FlowGraphBuilder* owner() const { return owner_; } | |
244 const SourceLabel* label() const { return label_; } | |
245 NestedStatement* outer() const { return outer_; } | |
246 JoinEntryInstr* break_target() const { return break_target_; } | |
247 | |
248 virtual JoinEntryInstr* BreakTargetFor(SourceLabel* label); | |
249 virtual JoinEntryInstr* ContinueTargetFor(SourceLabel* label); | |
250 | |
251 private: | |
252 FlowGraphBuilder* owner_; | |
253 const SourceLabel* label_; | |
254 NestedStatement* outer_; | |
255 | |
256 JoinEntryInstr* break_target_; | |
257 }; | |
258 | |
259 | |
260 class TestGraphVisitor; | |
261 | |
262 // Translate an AstNode to a control-flow graph fragment for its effects | 223 // Translate an AstNode to a control-flow graph fragment for its effects |
263 // (e.g., a statement or an expression in an effect context). Implements a | 224 // (e.g., a statement or an expression in an effect context). Implements a |
264 // function from an AstNode and next temporary index to a graph fragment | 225 // function from an AstNode and next temporary index to a graph fragment |
265 // with a single entry and at most one exit. The fragment is represented by | 226 // with a single entry and at most one exit. The fragment is represented by |
266 // an (entry, exit) pair of Instruction pointers: | 227 // an (entry, exit) pair of Instruction pointers: |
267 // | 228 // |
268 // - (NULL, NULL): an empty and open graph fragment | 229 // - (NULL, NULL): an empty and open graph fragment |
269 // - (i0, NULL): a closed graph fragment which has only non-local exits | 230 // - (i0, NULL): a closed graph fragment which has only non-local exits |
270 // - (i0, i1): an open graph fragment | 231 // - (i0, i1): an open graph fragment |
271 class EffectGraphVisitor : public AstNodeVisitor { | 232 class EffectGraphVisitor : public AstNodeVisitor { |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 StrictCompareInstr* BuildStrictCompare(AstNode* left, | 356 StrictCompareInstr* BuildStrictCompare(AstNode* left, |
396 AstNode* right, | 357 AstNode* right, |
397 Token::Kind kind, | 358 Token::Kind kind, |
398 intptr_t token_pos); | 359 intptr_t token_pos); |
399 | 360 |
400 virtual void BuildTypeTest(ComparisonNode* node); | 361 virtual void BuildTypeTest(ComparisonNode* node); |
401 virtual void BuildTypeCast(ComparisonNode* node); | 362 virtual void BuildTypeCast(ComparisonNode* node); |
402 | 363 |
403 bool MustSaveRestoreContext(SequenceNode* node) const; | 364 bool MustSaveRestoreContext(SequenceNode* node) const; |
404 | 365 |
405 // Moves parent context into the context register. | 366 // Moves the nth parent context into the context register. |
406 void UnchainContext(); | 367 void UnchainContexts(intptr_t n); |
407 | 368 |
408 void CloseFragment() { exit_ = NULL; } | 369 void CloseFragment() { exit_ = NULL; } |
409 | 370 |
410 // Returns a local variable index for a temporary local that is | 371 // Returns a local variable index for a temporary local that is |
411 // on top of the current expression stack. | 372 // on top of the current expression stack. |
412 intptr_t GetCurrentTempLocalIndex() const; | 373 intptr_t GetCurrentTempLocalIndex() const; |
413 | 374 |
414 Value* BuildObjectAllocation(ConstructorCallNode* node); | 375 Value* BuildObjectAllocation(ConstructorCallNode* node); |
415 void BuildConstructorCall(ConstructorCallNode* node, | 376 void BuildConstructorCall(ConstructorCallNode* node, |
416 PushArgumentInstr* alloc_value); | 377 PushArgumentInstr* alloc_value); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 // Output parameters. | 543 // Output parameters. |
583 GrowableArray<TargetEntryInstr**> true_successor_addresses_; | 544 GrowableArray<TargetEntryInstr**> true_successor_addresses_; |
584 GrowableArray<TargetEntryInstr**> false_successor_addresses_; | 545 GrowableArray<TargetEntryInstr**> false_successor_addresses_; |
585 | 546 |
586 intptr_t condition_token_pos_; | 547 intptr_t condition_token_pos_; |
587 }; | 548 }; |
588 | 549 |
589 } // namespace dart | 550 } // namespace dart |
590 | 551 |
591 #endif // VM_FLOW_GRAPH_BUILDER_H_ | 552 #endif // VM_FLOW_GRAPH_BUILDER_H_ |
OLD | NEW |