| 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 |