| 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" |
| 9 #include "platform/globals.h" |
| 8 #include "vm/allocation.h" | 10 #include "vm/allocation.h" |
| 9 #include "vm/ast.h" | 11 #include "vm/ast.h" |
| 10 #include "vm/growable_array.h" | 12 #include "vm/growable_array.h" |
| 11 #include "vm/intermediate_language.h" | 13 #include "vm/intermediate_language.h" |
| 14 #include "vm/raw_object.h" |
| 12 | 15 |
| 13 namespace dart { | 16 namespace dart { |
| 14 | 17 |
| 18 class AbstractType; |
| 19 class AbstractTypeArguments; |
| 20 class Array; |
| 21 class Class; |
| 22 class Field; |
| 15 class FlowGraph; | 23 class FlowGraph; |
| 16 class Instruction; | 24 class LocalVariable; |
| 17 class ParsedFunction; | 25 class ParsedFunction; |
| 26 class String; |
| 18 | 27 |
| 19 // List of recognized list factories: | 28 // List of recognized list factories: |
| 20 // (factory-name-symbol, result-cid, fingerprint). | 29 // (factory-name-symbol, result-cid, fingerprint). |
| 21 // TODO(srdjan): Store the values in the snapshot instead. | 30 // TODO(srdjan): Store the values in the snapshot instead. |
| 22 #define RECOGNIZED_LIST_FACTORY_LIST(V) \ | 31 #define RECOGNIZED_LIST_FACTORY_LIST(V) \ |
| 23 V(_ListFactory, kArrayCid, 1436567945) \ | 32 V(_ListFactory, kArrayCid, 1436567945) \ |
| 24 V(_GrowableListWithData, kGrowableObjectArrayCid, 461305701) \ | 33 V(_GrowableListWithData, kGrowableObjectArrayCid, 461305701) \ |
| 25 V(_GrowableListFactory, kGrowableObjectArrayCid, 910639199) \ | 34 V(_GrowableListFactory, kGrowableObjectArrayCid, 910639199) \ |
| 26 V(_Int8ArrayFactory, kTypedDataInt8ArrayCid, 810750844) \ | 35 V(_Int8ArrayFactory, kTypedDataInt8ArrayCid, 810750844) \ |
| 27 V(_Uint8ArrayFactory, kTypedDataUint8ArrayCid, 1246070930) \ | 36 V(_Uint8ArrayFactory, kTypedDataUint8ArrayCid, 1246070930) \ |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 return num_stack_locals_; | 153 return num_stack_locals_; |
| 145 } | 154 } |
| 146 | 155 |
| 147 bool IsInlining() const { return (exit_collector_ != NULL); } | 156 bool IsInlining() const { return (exit_collector_ != NULL); } |
| 148 InlineExitCollector* exit_collector() const { return exit_collector_; } | 157 InlineExitCollector* exit_collector() const { return exit_collector_; } |
| 149 | 158 |
| 150 ZoneGrowableArray<const Field*>* guarded_fields() const { | 159 ZoneGrowableArray<const Field*>* guarded_fields() const { |
| 151 return guarded_fields_; | 160 return guarded_fields_; |
| 152 } | 161 } |
| 153 | 162 |
| 163 intptr_t temp_count() const { return temp_count_; } |
| 164 intptr_t AllocateTemp() { return ++temp_count_; } |
| 165 void DeallocateTemps(intptr_t count) { |
| 166 ASSERT(temp_count_ >= count); |
| 167 temp_count_ -= count; |
| 168 } |
| 169 |
| 154 intptr_t args_pushed() const { return args_pushed_; } | 170 intptr_t args_pushed() const { return args_pushed_; } |
| 155 void add_args_pushed(intptr_t n) { args_pushed_ += n; } | 171 void add_args_pushed(intptr_t n) { args_pushed_ += n; } |
| 156 | 172 |
| 157 // When compiling for OSR, remove blocks that are not reachable from the | 173 // When compiling for OSR, remove blocks that are not reachable from the |
| 158 // OSR entry point. | 174 // OSR entry point. |
| 159 void PruneUnreachable(); | 175 void PruneUnreachable(); |
| 160 | 176 |
| 161 private: | 177 private: |
| 162 intptr_t parameter_count() const { | 178 intptr_t parameter_count() const { |
| 163 return num_copied_params_ + num_non_copied_params_; | 179 return num_copied_params_ + num_non_copied_params_; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 175 InlineExitCollector* const exit_collector_; | 191 InlineExitCollector* const exit_collector_; |
| 176 ZoneGrowableArray<const Field*>* guarded_fields_; | 192 ZoneGrowableArray<const Field*>* guarded_fields_; |
| 177 | 193 |
| 178 intptr_t last_used_block_id_; | 194 intptr_t last_used_block_id_; |
| 179 intptr_t context_level_; | 195 intptr_t context_level_; |
| 180 intptr_t try_index_; | 196 intptr_t try_index_; |
| 181 intptr_t catch_try_index_; | 197 intptr_t catch_try_index_; |
| 182 intptr_t loop_depth_; | 198 intptr_t loop_depth_; |
| 183 GraphEntryInstr* graph_entry_; | 199 GraphEntryInstr* graph_entry_; |
| 184 | 200 |
| 201 // The expression stack height. |
| 202 intptr_t temp_count_; |
| 203 |
| 185 // Outgoing argument stack height. | 204 // Outgoing argument stack height. |
| 186 intptr_t args_pushed_; | 205 intptr_t args_pushed_; |
| 187 | 206 |
| 188 // The deopt id of the OSR entry or Isolate::kNoDeoptId if not compiling | 207 // The deopt id of the OSR entry or Isolate::kNoDeoptId if not compiling |
| 189 // for OSR. | 208 // for OSR. |
| 190 const intptr_t osr_id_; | 209 const intptr_t osr_id_; |
| 191 | 210 |
| 192 DISALLOW_IMPLICIT_CONSTRUCTORS(FlowGraphBuilder); | 211 DISALLOW_IMPLICIT_CONSTRUCTORS(FlowGraphBuilder); |
| 193 }; | 212 }; |
| 194 | 213 |
| 195 | 214 |
| 196 class TestGraphVisitor; | 215 class TestGraphVisitor; |
| 197 | 216 |
| 198 // Translate an AstNode to a control-flow graph fragment for its effects | 217 // Translate an AstNode to a control-flow graph fragment for its effects |
| 199 // (e.g., a statement or an expression in an effect context). Implements a | 218 // (e.g., a statement or an expression in an effect context). Implements a |
| 200 // function from an AstNode and next temporary index to a graph fragment | 219 // function from an AstNode and next temporary index to a graph fragment |
| 201 // with a single entry and at most one exit. The fragment is represented by | 220 // with a single entry and at most one exit. The fragment is represented by |
| 202 // an (entry, exit) pair of Instruction pointers: | 221 // an (entry, exit) pair of Instruction pointers: |
| 203 // | 222 // |
| 204 // - (NULL, NULL): an empty and open graph fragment | 223 // - (NULL, NULL): an empty and open graph fragment |
| 205 // - (i0, NULL): a closed graph fragment which has only non-local exits | 224 // - (i0, NULL): a closed graph fragment which has only non-local exits |
| 206 // - (i0, i1): an open graph fragment | 225 // - (i0, i1): an open graph fragment |
| 207 class EffectGraphVisitor : public AstNodeVisitor { | 226 class EffectGraphVisitor : public AstNodeVisitor { |
| 208 public: | 227 public: |
| 209 EffectGraphVisitor(FlowGraphBuilder* owner, | 228 explicit EffectGraphVisitor(FlowGraphBuilder* owner) |
| 210 intptr_t temp_index) | |
| 211 : owner_(owner), | 229 : owner_(owner), |
| 212 temp_index_(temp_index), | |
| 213 entry_(NULL), | 230 entry_(NULL), |
| 214 exit_(NULL) { } | 231 exit_(NULL) { } |
| 215 | 232 |
| 216 #define DECLARE_VISIT(BaseName) \ | 233 #define DECLARE_VISIT(BaseName) \ |
| 217 virtual void Visit##BaseName##Node(BaseName##Node* node); | 234 virtual void Visit##BaseName##Node(BaseName##Node* node); |
| 218 | 235 |
| 219 FOR_EACH_NODE(DECLARE_VISIT) | 236 FOR_EACH_NODE(DECLARE_VISIT) |
| 220 #undef DECLARE_VISIT | 237 #undef DECLARE_VISIT |
| 221 | 238 |
| 222 FlowGraphBuilder* owner() const { return owner_; } | 239 FlowGraphBuilder* owner() const { return owner_; } |
| 223 intptr_t temp_index() const { return temp_index_; } | |
| 224 Instruction* entry() const { return entry_; } | 240 Instruction* entry() const { return entry_; } |
| 225 Instruction* exit() const { return exit_; } | 241 Instruction* exit() const { return exit_; } |
| 226 | 242 |
| 227 bool is_empty() const { return entry_ == NULL; } | 243 bool is_empty() const { return entry_ == NULL; } |
| 228 bool is_open() const { return is_empty() || exit_ != NULL; } | 244 bool is_open() const { return is_empty() || exit_ != NULL; } |
| 229 | 245 |
| 230 void Bailout(const char* reason); | 246 void Bailout(const char* reason); |
| 231 void InlineBailout(const char* reason); | 247 void InlineBailout(const char* reason); |
| 232 | 248 |
| 233 // Append a graph fragment to this graph. Assumes this graph is open. | 249 // Append a graph fragment to this graph. Assumes this graph is open. |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 | 349 |
| 334 virtual void BuildTypeTest(ComparisonNode* node); | 350 virtual void BuildTypeTest(ComparisonNode* node); |
| 335 virtual void BuildTypeCast(ComparisonNode* node); | 351 virtual void BuildTypeCast(ComparisonNode* node); |
| 336 | 352 |
| 337 bool MustSaveRestoreContext(SequenceNode* node) const; | 353 bool MustSaveRestoreContext(SequenceNode* node) const; |
| 338 | 354 |
| 339 // Moves parent context into the context register. | 355 // Moves parent context into the context register. |
| 340 void UnchainContext(); | 356 void UnchainContext(); |
| 341 | 357 |
| 342 void CloseFragment() { exit_ = NULL; } | 358 void CloseFragment() { exit_ = NULL; } |
| 343 intptr_t AllocateTempIndex() { return temp_index_++; } | |
| 344 void DeallocateTempIndex(intptr_t n) { | |
| 345 ASSERT(temp_index_ >= n); | |
| 346 temp_index_ -= n; | |
| 347 } | |
| 348 | 359 |
| 349 // Returns a local variable index for a temporary local that is | 360 // Returns a local variable index for a temporary local that is |
| 350 // on top of the current expression stack. | 361 // on top of the current expression stack. |
| 351 intptr_t GetCurrentTempLocalIndex() const; | 362 intptr_t GetCurrentTempLocalIndex() const; |
| 352 | 363 |
| 353 Value* BuildObjectAllocation(ConstructorCallNode* node); | 364 Value* BuildObjectAllocation(ConstructorCallNode* node); |
| 354 void BuildConstructorCall(ConstructorCallNode* node, | 365 void BuildConstructorCall(ConstructorCallNode* node, |
| 355 PushArgumentInstr* alloc_value); | 366 PushArgumentInstr* alloc_value); |
| 356 | 367 |
| 357 void BuildSaveContext(const LocalVariable& variable); | 368 void BuildSaveContext(const LocalVariable& variable); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 | 411 |
| 401 // Specify a definition of the final result. Adds the definition to | 412 // Specify a definition of the final result. Adds the definition to |
| 402 // the graph, but normally overridden in subclasses. | 413 // the graph, but normally overridden in subclasses. |
| 403 virtual void ReturnDefinition(Definition* definition) { | 414 virtual void ReturnDefinition(Definition* definition) { |
| 404 Do(definition); | 415 Do(definition); |
| 405 } | 416 } |
| 406 | 417 |
| 407 // Shared global state. | 418 // Shared global state. |
| 408 FlowGraphBuilder* owner_; | 419 FlowGraphBuilder* owner_; |
| 409 | 420 |
| 410 // Input parameters. | |
| 411 intptr_t temp_index_; | |
| 412 | |
| 413 // Output parameters. | 421 // Output parameters. |
| 414 Instruction* entry_; | 422 Instruction* entry_; |
| 415 Instruction* exit_; | 423 Instruction* exit_; |
| 416 }; | 424 }; |
| 417 | 425 |
| 418 | 426 |
| 419 // Translate an AstNode to a control-flow graph fragment for both its effects | 427 // Translate an AstNode to a control-flow graph fragment for both its effects |
| 420 // and value (e.g., for an expression in a value context). Implements a | 428 // and value (e.g., for an expression in a value context). Implements a |
| 421 // function from an AstNode and next temporary index to a graph fragment (as | 429 // function from an AstNode and next temporary index to a graph fragment (as |
| 422 // in the EffectGraphVisitor), a next temporary index, and an intermediate | 430 // in the EffectGraphVisitor), a next temporary index, and an intermediate |
| 423 // language Value. | 431 // language Value. |
| 424 class ValueGraphVisitor : public EffectGraphVisitor { | 432 class ValueGraphVisitor : public EffectGraphVisitor { |
| 425 public: | 433 public: |
| 426 ValueGraphVisitor(FlowGraphBuilder* owner, | 434 explicit ValueGraphVisitor(FlowGraphBuilder* owner) |
| 427 intptr_t temp_index) | 435 : EffectGraphVisitor(owner), value_(NULL) { } |
| 428 : EffectGraphVisitor(owner, temp_index), value_(NULL) { } | |
| 429 | 436 |
| 430 // Visit functions overridden by this class. | 437 // Visit functions overridden by this class. |
| 431 virtual void VisitLiteralNode(LiteralNode* node); | 438 virtual void VisitLiteralNode(LiteralNode* node); |
| 432 virtual void VisitAssignableNode(AssignableNode* node); | 439 virtual void VisitAssignableNode(AssignableNode* node); |
| 433 virtual void VisitConstructorCallNode(ConstructorCallNode* node); | 440 virtual void VisitConstructorCallNode(ConstructorCallNode* node); |
| 434 virtual void VisitBinaryOpNode(BinaryOpNode* node); | 441 virtual void VisitBinaryOpNode(BinaryOpNode* node); |
| 435 virtual void VisitConditionalExprNode(ConditionalExprNode* node); | 442 virtual void VisitConditionalExprNode(ConditionalExprNode* node); |
| 436 virtual void VisitLoadLocalNode(LoadLocalNode* node); | 443 virtual void VisitLoadLocalNode(LoadLocalNode* node); |
| 437 virtual void VisitStoreLocalNode(StoreLocalNode* node); | 444 virtual void VisitStoreLocalNode(StoreLocalNode* node); |
| 438 virtual void VisitStoreIndexedNode(StoreIndexedNode* node); | 445 virtual void VisitStoreIndexedNode(StoreIndexedNode* node); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 // - Neither NULL: true and false successors at the given addresses | 487 // - Neither NULL: true and false successors at the given addresses |
| 481 // | 488 // |
| 482 // We expect that AstNode in test contexts either have only nonlocal exits | 489 // We expect that AstNode in test contexts either have only nonlocal exits |
| 483 // or else control flow has both true and false successors. | 490 // or else control flow has both true and false successors. |
| 484 // | 491 // |
| 485 // The cis and token_pos are used in checked mode to verify that the | 492 // The cis and token_pos are used in checked mode to verify that the |
| 486 // condition of the test is of type bool. | 493 // condition of the test is of type bool. |
| 487 class TestGraphVisitor : public ValueGraphVisitor { | 494 class TestGraphVisitor : public ValueGraphVisitor { |
| 488 public: | 495 public: |
| 489 TestGraphVisitor(FlowGraphBuilder* owner, | 496 TestGraphVisitor(FlowGraphBuilder* owner, |
| 490 intptr_t temp_index, | |
| 491 intptr_t condition_token_pos) | 497 intptr_t condition_token_pos) |
| 492 : ValueGraphVisitor(owner, temp_index), | 498 : ValueGraphVisitor(owner), |
| 493 true_successor_addresses_(1), | 499 true_successor_addresses_(1), |
| 494 false_successor_addresses_(1), | 500 false_successor_addresses_(1), |
| 495 condition_token_pos_(condition_token_pos) { } | 501 condition_token_pos_(condition_token_pos) { } |
| 496 | 502 |
| 497 void IfFalseGoto(JoinEntryInstr* join) const; | 503 void IfFalseGoto(JoinEntryInstr* join) const; |
| 498 void IfTrueGoto(JoinEntryInstr* join) const; | 504 void IfTrueGoto(JoinEntryInstr* join) const; |
| 499 | 505 |
| 500 BlockEntryInstr* CreateTrueSuccessor() const; | 506 BlockEntryInstr* CreateTrueSuccessor() const; |
| 501 BlockEntryInstr* CreateFalseSuccessor() const; | 507 BlockEntryInstr* CreateFalseSuccessor() const; |
| 502 | 508 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 526 // Output parameters. | 532 // Output parameters. |
| 527 GrowableArray<TargetEntryInstr**> true_successor_addresses_; | 533 GrowableArray<TargetEntryInstr**> true_successor_addresses_; |
| 528 GrowableArray<TargetEntryInstr**> false_successor_addresses_; | 534 GrowableArray<TargetEntryInstr**> false_successor_addresses_; |
| 529 | 535 |
| 530 intptr_t condition_token_pos_; | 536 intptr_t condition_token_pos_; |
| 531 }; | 537 }; |
| 532 | 538 |
| 533 } // namespace dart | 539 } // namespace dart |
| 534 | 540 |
| 535 #endif // VM_FLOW_GRAPH_BUILDER_H_ | 541 #endif // VM_FLOW_GRAPH_BUILDER_H_ |
| OLD | NEW |