| 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 #include "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "vm/ast_printer.h" | 7 #include "vm/ast_printer.h" |
| 8 #include "vm/code_descriptors.h" | 8 #include "vm/code_descriptors.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flags.h" | 10 #include "vm/flags.h" |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 ASSERT(is_open()); | 108 ASSERT(is_open()); |
| 109 if (is_empty()) { | 109 if (is_empty()) { |
| 110 entry_ = new GotoInstr(join); | 110 entry_ = new GotoInstr(join); |
| 111 } else { | 111 } else { |
| 112 exit()->Goto(join); | 112 exit()->Goto(join); |
| 113 } | 113 } |
| 114 exit_ = NULL; | 114 exit_ = NULL; |
| 115 } | 115 } |
| 116 | 116 |
| 117 | 117 |
| 118 MaterializeComp* EffectGraphVisitor::Constant(const Object& value) { | |
| 119 return new MaterializeComp(new ConstantVal(value)); | |
| 120 } | |
| 121 | |
| 122 | |
| 123 // Appends a graph fragment to a block entry instruction. Returns the entry | 118 // Appends a graph fragment to a block entry instruction. Returns the entry |
| 124 // instruction if the fragment was empty or else the exit of the fragment if | 119 // instruction if the fragment was empty or else the exit of the fragment if |
| 125 // it was non-empty (so NULL if the fragment is closed). | 120 // it was non-empty (so NULL if the fragment is closed). |
| 126 // | 121 // |
| 127 // Note that the fragment is no longer a valid fragment after calling this | 122 // Note that the fragment is no longer a valid fragment after calling this |
| 128 // function -- the fragment is closed at its entry because the entry has a | 123 // function -- the fragment is closed at its entry because the entry has a |
| 129 // predecessor in the graph. | 124 // predecessor in the graph. |
| 130 static Instruction* AppendFragment(BlockEntryInstr* entry, | 125 static Instruction* AppendFragment(BlockEntryInstr* entry, |
| 131 const EffectGraphVisitor& fragment) { | 126 const EffectGraphVisitor& fragment) { |
| 132 if (fragment.is_empty()) return entry; | 127 if (fragment.is_empty()) return entry; |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 } | 263 } |
| 269 | 264 |
| 270 | 265 |
| 271 void TestGraphVisitor::ReturnValue(Value* value) { | 266 void TestGraphVisitor::ReturnValue(Value* value) { |
| 272 if (FLAG_enable_type_checks) { | 267 if (FLAG_enable_type_checks) { |
| 273 value = Bind(new AssertBooleanComp(condition_token_pos(), | 268 value = Bind(new AssertBooleanComp(condition_token_pos(), |
| 274 owner()->try_index(), | 269 owner()->try_index(), |
| 275 value)); | 270 value)); |
| 276 } | 271 } |
| 277 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 272 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 278 Value* constant_true = Bind(Constant(bool_true)); | 273 Value* constant_true = Bind(new ConstantComp(bool_true)); |
| 279 StrictCompareAndBranchInstr* branch = | 274 StrictCompareAndBranchInstr* branch = |
| 280 new StrictCompareAndBranchInstr(value, constant_true, Token::kEQ_STRICT); | 275 new StrictCompareAndBranchInstr(value, constant_true, Token::kEQ_STRICT); |
| 281 AddInstruction(branch); | 276 AddInstruction(branch); |
| 282 CloseFragment(); | 277 CloseFragment(); |
| 283 true_successor_address_ = branch->true_successor_address(); | 278 true_successor_address_ = branch->true_successor_address(); |
| 284 false_successor_address_ = branch->false_successor_address(); | 279 false_successor_address_ = branch->false_successor_address(); |
| 285 } | 280 } |
| 286 | 281 |
| 287 | 282 |
| 288 void TestGraphVisitor::MergeBranchWithComparison(ComparisonComp* comp) { | 283 void TestGraphVisitor::MergeBranchWithComparison(ComparisonComp* comp) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 309 AddInstruction(branch); | 304 AddInstruction(branch); |
| 310 CloseFragment(); | 305 CloseFragment(); |
| 311 true_successor_address_ = branch->true_successor_address(); | 306 true_successor_address_ = branch->true_successor_address(); |
| 312 false_successor_address_ = branch->false_successor_address(); | 307 false_successor_address_ = branch->false_successor_address(); |
| 313 } | 308 } |
| 314 | 309 |
| 315 | 310 |
| 316 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateComp* comp) { | 311 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateComp* comp) { |
| 317 ASSERT(!FLAG_enable_type_checks); | 312 ASSERT(!FLAG_enable_type_checks); |
| 318 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 313 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 319 Value* constant_true = Bind(Constant(bool_true)); | 314 Value* constant_true = Bind(new ConstantComp(bool_true)); |
| 320 StrictCompareAndBranchInstr* branch = | 315 StrictCompareAndBranchInstr* branch = |
| 321 new StrictCompareAndBranchInstr(comp->value(), | 316 new StrictCompareAndBranchInstr(comp->value(), |
| 322 constant_true, | 317 constant_true, |
| 323 Token::kNE_STRICT); | 318 Token::kNE_STRICT); |
| 324 AddInstruction(branch); | 319 AddInstruction(branch); |
| 325 CloseFragment(); | 320 CloseFragment(); |
| 326 true_successor_address_ = branch->true_successor_address(); | 321 true_successor_address_ = branch->true_successor_address(); |
| 327 false_successor_address_ = branch->false_successor_address(); | 322 false_successor_address_ = branch->false_successor_address(); |
| 328 } | 323 } |
| 329 | 324 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 } | 398 } |
| 404 | 399 |
| 405 | 400 |
| 406 // <Expression> ::= Literal { literal: Instance } | 401 // <Expression> ::= Literal { literal: Instance } |
| 407 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) { | 402 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) { |
| 408 return; | 403 return; |
| 409 } | 404 } |
| 410 | 405 |
| 411 | 406 |
| 412 void ValueGraphVisitor::VisitLiteralNode(LiteralNode* node) { | 407 void ValueGraphVisitor::VisitLiteralNode(LiteralNode* node) { |
| 413 ReturnComputation(Constant(node->literal())); | 408 ReturnComputation(new ConstantComp(node->literal())); |
| 414 } | 409 } |
| 415 | 410 |
| 416 | 411 |
| 417 // Type nodes only occur as the right-hand side of instanceof comparisons, | 412 // Type nodes only occur as the right-hand side of instanceof comparisons, |
| 418 // and they are handled specially in that context. | 413 // and they are handled specially in that context. |
| 419 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } | 414 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } |
| 420 | 415 |
| 421 | 416 |
| 422 // Returns true if the type check can be skipped, for example, if the | 417 // Returns true if the type check can be skipped, for example, if the |
| 423 // destination type is Dynamic or if the compile type of the value is a subtype | 418 // destination type is Dynamic or if the compile type of the value is a subtype |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 | 550 |
| 556 ValueGraphVisitor for_right(owner(), temp_index()); | 551 ValueGraphVisitor for_right(owner(), temp_index()); |
| 557 node->right()->Visit(&for_right); | 552 node->right()->Visit(&for_right); |
| 558 Value* right_value = for_right.value(); | 553 Value* right_value = for_right.value(); |
| 559 if (FLAG_enable_type_checks) { | 554 if (FLAG_enable_type_checks) { |
| 560 right_value = | 555 right_value = |
| 561 for_right.Bind(new AssertBooleanComp(node->right()->token_pos(), | 556 for_right.Bind(new AssertBooleanComp(node->right()->token_pos(), |
| 562 owner()->try_index(), | 557 owner()->try_index(), |
| 563 right_value)); | 558 right_value)); |
| 564 } | 559 } |
| 565 Value* constant_true = for_right.Bind(Constant(bool_true)); | 560 Value* constant_true = for_right.Bind(new ConstantComp(bool_true)); |
| 566 Value* compare = | 561 Value* compare = |
| 567 for_right.Bind(new StrictCompareComp(Token::kEQ_STRICT, | 562 for_right.Bind(new StrictCompareComp(Token::kEQ_STRICT, |
| 568 right_value, | 563 right_value, |
| 569 constant_true)); | 564 constant_true)); |
| 570 for_right.Do(BuildStoreLocal( | 565 for_right.Do(BuildStoreLocal( |
| 571 *owner()->parsed_function().expression_temp_var(), | 566 *owner()->parsed_function().expression_temp_var(), |
| 572 compare)); | 567 compare)); |
| 573 | 568 |
| 574 if (node->kind() == Token::kAND) { | 569 if (node->kind() == Token::kAND) { |
| 575 ValueGraphVisitor for_false(owner(), temp_index()); | 570 ValueGraphVisitor for_false(owner(), temp_index()); |
| 576 Value* constant_false = for_false.Bind(Constant(bool_false)); | 571 Value* constant_false = for_false.Bind(new ConstantComp(bool_false)); |
| 577 for_false.Do(BuildStoreLocal( | 572 for_false.Do(BuildStoreLocal( |
| 578 *owner()->parsed_function().expression_temp_var(), | 573 *owner()->parsed_function().expression_temp_var(), |
| 579 constant_false)); | 574 constant_false)); |
| 580 Join(for_test, for_right, for_false); | 575 Join(for_test, for_right, for_false); |
| 581 } else { | 576 } else { |
| 582 ASSERT(node->kind() == Token::kOR); | 577 ASSERT(node->kind() == Token::kOR); |
| 583 ValueGraphVisitor for_true(owner(), temp_index()); | 578 ValueGraphVisitor for_true(owner(), temp_index()); |
| 584 Value* constant_true = for_true.Bind(Constant(bool_true)); | 579 Value* constant_true = for_true.Bind(new ConstantComp(bool_true)); |
| 585 for_true.Do(BuildStoreLocal( | 580 for_true.Do(BuildStoreLocal( |
| 586 *owner()->parsed_function().expression_temp_var(), | 581 *owner()->parsed_function().expression_temp_var(), |
| 587 constant_true)); | 582 constant_true)); |
| 588 Join(for_test, for_true, for_right); | 583 Join(for_test, for_true, for_right); |
| 589 } | 584 } |
| 590 ReturnComputation( | 585 ReturnComputation( |
| 591 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); | 586 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); |
| 592 return; | 587 return; |
| 593 } | 588 } |
| 594 EffectGraphVisitor::VisitBinaryOpNode(node); | 589 EffectGraphVisitor::VisitBinaryOpNode(node); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 619 Value* loaded = Bind(BuildLoadLocal(expr_temp)); | 614 Value* loaded = Bind(BuildLoadLocal(expr_temp)); |
| 620 instantiator_type_arguments = | 615 instantiator_type_arguments = |
| 621 BuildInstantiatorTypeArguments(token_pos, loaded); | 616 BuildInstantiatorTypeArguments(token_pos, loaded); |
| 622 } | 617 } |
| 623 *instantiator_result = instantiator; | 618 *instantiator_result = instantiator; |
| 624 *instantiator_type_arguments_result = instantiator_type_arguments; | 619 *instantiator_type_arguments_result = instantiator_type_arguments; |
| 625 } | 620 } |
| 626 | 621 |
| 627 | 622 |
| 628 Value* EffectGraphVisitor::BuildNullValue() { | 623 Value* EffectGraphVisitor::BuildNullValue() { |
| 629 return Bind(Constant(Object::ZoneHandle())); | 624 return Bind(new ConstantComp(Object::ZoneHandle())); |
| 630 } | 625 } |
| 631 | 626 |
| 632 | 627 |
| 633 // Used for testing incoming arguments. | 628 // Used for testing incoming arguments. |
| 634 AssertAssignableComp* EffectGraphVisitor::BuildAssertAssignable( | 629 AssertAssignableComp* EffectGraphVisitor::BuildAssertAssignable( |
| 635 intptr_t token_pos, | 630 intptr_t token_pos, |
| 636 Value* value, | 631 Value* value, |
| 637 const AbstractType& dst_type, | 632 const AbstractType& dst_type, |
| 638 const String& dst_name) { | 633 const String& dst_name) { |
| 639 // Build the type check computation. | 634 // Build the type check computation. |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 const AbstractType& type = node->right()->AsTypeNode()->type(); | 695 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 701 ASSERT(type.IsFinalized() && !type.IsMalformed()); | 696 ASSERT(type.IsFinalized() && !type.IsMalformed()); |
| 702 const bool negate_result = (node->kind() == Token::kISNOT); | 697 const bool negate_result = (node->kind() == Token::kISNOT); |
| 703 // All objects are instances of type T if Object type is a subtype of type T. | 698 // All objects are instances of type T if Object type is a subtype of type T. |
| 704 const Type& object_type = Type::Handle(Type::ObjectType()); | 699 const Type& object_type = Type::Handle(Type::ObjectType()); |
| 705 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { | 700 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { |
| 706 // Must evaluate left side. | 701 // Must evaluate left side. |
| 707 EffectGraphVisitor for_left_value(owner(), temp_index()); | 702 EffectGraphVisitor for_left_value(owner(), temp_index()); |
| 708 node->left()->Visit(&for_left_value); | 703 node->left()->Visit(&for_left_value); |
| 709 Append(for_left_value); | 704 Append(for_left_value); |
| 710 ReturnComputation(Constant(negate_result ? bool_false : bool_true)); | 705 ReturnComputation(new ConstantComp(negate_result ? bool_false : bool_true)); |
| 711 return; | 706 return; |
| 712 } | 707 } |
| 713 | 708 |
| 714 // Eliminate the test if it can be performed successfully at compile time. | 709 // Eliminate the test if it can be performed successfully at compile time. |
| 715 if ((node->left() != NULL) && | 710 if ((node->left() != NULL) && |
| 716 node->left()->IsLiteralNode() && | 711 node->left()->IsLiteralNode() && |
| 717 type.IsInstantiated()) { | 712 type.IsInstantiated()) { |
| 718 const Instance& literal_value = node->left()->AsLiteralNode()->literal(); | 713 const Instance& literal_value = node->left()->AsLiteralNode()->literal(); |
| 719 const Class& cls = Class::Handle(literal_value.clazz()); | 714 const Class& cls = Class::Handle(literal_value.clazz()); |
| 720 MaterializeComp* result = NULL; | 715 ConstantComp* result = NULL; |
| 721 if (cls.IsNullClass()) { | 716 if (cls.IsNullClass()) { |
| 722 // A null object is only an instance of Object and Dynamic, which has | 717 // A null object is only an instance of Object and Dynamic, which has |
| 723 // already been checked above (if the type is instantiated). So we can | 718 // already been checked above (if the type is instantiated). So we can |
| 724 // return false here if the instance is null (and if the type is | 719 // return false here if the instance is null (and if the type is |
| 725 // instantiated). | 720 // instantiated). |
| 726 result = Constant(negate_result ? bool_true : bool_false); | 721 result = new ConstantComp(negate_result ? bool_true : bool_false); |
| 727 } else { | 722 } else { |
| 728 if (literal_value.IsInstanceOf(type, TypeArguments::Handle(), NULL)) { | 723 if (literal_value.IsInstanceOf(type, TypeArguments::Handle(), NULL)) { |
| 729 result = Constant(negate_result ? bool_false : bool_true); | 724 result = new ConstantComp(negate_result ? bool_false : bool_true); |
| 730 } else { | 725 } else { |
| 731 result = Constant(negate_result ? bool_true : bool_false); | 726 result = new ConstantComp(negate_result ? bool_true : bool_false); |
| 732 } | 727 } |
| 733 } | 728 } |
| 734 ReturnComputation(result); | 729 ReturnComputation(result); |
| 735 return; | 730 return; |
| 736 } | 731 } |
| 737 | 732 |
| 738 ValueGraphVisitor for_left_value(owner(), temp_index()); | 733 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 739 node->left()->Visit(&for_left_value); | 734 node->left()->Visit(&for_left_value); |
| 740 Append(for_left_value); | 735 Append(for_left_value); |
| 741 Value* instantiator = NULL; | 736 Value* instantiator = NULL; |
| (...skipping 766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1508 allocate_arguments); | 1503 allocate_arguments); |
| 1509 } | 1504 } |
| 1510 return Bind(allocate_comp); | 1505 return Bind(allocate_comp); |
| 1511 } | 1506 } |
| 1512 | 1507 |
| 1513 | 1508 |
| 1514 void EffectGraphVisitor::BuildConstructorCall( | 1509 void EffectGraphVisitor::BuildConstructorCall( |
| 1515 ConstructorCallNode* node, | 1510 ConstructorCallNode* node, |
| 1516 PushArgumentInstr* push_alloc_value) { | 1511 PushArgumentInstr* push_alloc_value) { |
| 1517 Value* ctor_arg = Bind( | 1512 Value* ctor_arg = Bind( |
| 1518 Constant(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); | 1513 new ConstantComp(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); |
| 1519 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); | 1514 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); |
| 1520 | 1515 |
| 1521 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1516 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1522 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1517 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1523 arguments->Add(push_alloc_value); | 1518 arguments->Add(push_alloc_value); |
| 1524 arguments->Add(push_ctor_arg); | 1519 arguments->Add(push_ctor_arg); |
| 1525 | 1520 |
| 1526 BuildPushArguments(*node->arguments(), arguments); | 1521 BuildPushArguments(*node->arguments(), arguments); |
| 1527 Do(new StaticCallComp(node->token_pos(), | 1522 Do(new StaticCallComp(node->token_pos(), |
| 1528 owner()->try_index(), | 1523 owner()->try_index(), |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1596 // The type arguments are compile time constants. | 1591 // The type arguments are compile time constants. |
| 1597 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); | 1592 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); |
| 1598 // Type is temporary. Only its type arguments are preserved. | 1593 // Type is temporary. Only its type arguments are preserved. |
| 1599 Type& type = Type::Handle( | 1594 Type& type = Type::Handle( |
| 1600 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); | 1595 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); |
| 1601 type ^= ClassFinalizer::FinalizeType( | 1596 type ^= ClassFinalizer::FinalizeType( |
| 1602 instantiator_class, type, ClassFinalizer::kFinalize); | 1597 instantiator_class, type, ClassFinalizer::kFinalize); |
| 1603 ASSERT(!type.IsMalformed()); | 1598 ASSERT(!type.IsMalformed()); |
| 1604 type_arguments = type.arguments(); | 1599 type_arguments = type.arguments(); |
| 1605 type_arguments = type_arguments.Canonicalize(); | 1600 type_arguments = type_arguments.Canonicalize(); |
| 1606 return Bind(Constant(type_arguments)); | 1601 return Bind(new ConstantComp(type_arguments)); |
| 1607 } | 1602 } |
| 1608 Function& outer_function = | 1603 Function& outer_function = |
| 1609 Function::Handle(owner()->parsed_function().function().raw()); | 1604 Function::Handle(owner()->parsed_function().function().raw()); |
| 1610 while (outer_function.IsLocalFunction()) { | 1605 while (outer_function.IsLocalFunction()) { |
| 1611 outer_function = outer_function.parent_function(); | 1606 outer_function = outer_function.parent_function(); |
| 1612 } | 1607 } |
| 1613 if (outer_function.IsFactory()) { | 1608 if (outer_function.IsFactory()) { |
| 1614 // No instantiator for factories. | 1609 // No instantiator for factories. |
| 1615 ASSERT(instantiator == NULL); | 1610 ASSERT(instantiator == NULL); |
| 1616 ASSERT(owner()->parsed_function().instantiator() != NULL); | 1611 ASSERT(owner()->parsed_function().instantiator() != NULL); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1634 instantiator, | 1629 instantiator, |
| 1635 type_arguments_instance_field_offset, | 1630 type_arguments_instance_field_offset, |
| 1636 Type::ZoneHandle())); // Not an instance, no type. | 1631 Type::ZoneHandle())); // Not an instance, no type. |
| 1637 } | 1632 } |
| 1638 | 1633 |
| 1639 | 1634 |
| 1640 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( | 1635 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( |
| 1641 intptr_t token_pos, | 1636 intptr_t token_pos, |
| 1642 const AbstractTypeArguments& type_arguments) { | 1637 const AbstractTypeArguments& type_arguments) { |
| 1643 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { | 1638 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { |
| 1644 return Bind(Constant(type_arguments)); | 1639 return Bind(new ConstantComp(type_arguments)); |
| 1645 } | 1640 } |
| 1646 // The type arguments are uninstantiated. | 1641 // The type arguments are uninstantiated. |
| 1647 Value* instantiator_value = | 1642 Value* instantiator_value = |
| 1648 BuildInstantiatorTypeArguments(token_pos, NULL); | 1643 BuildInstantiatorTypeArguments(token_pos, NULL); |
| 1649 return Bind(new InstantiateTypeArgumentsComp(token_pos, | 1644 return Bind(new InstantiateTypeArgumentsComp(token_pos, |
| 1650 owner()->try_index(), | 1645 owner()->try_index(), |
| 1651 type_arguments, | 1646 type_arguments, |
| 1652 instantiator_value)); | 1647 instantiator_value)); |
| 1653 } | 1648 } |
| 1654 | 1649 |
| 1655 | 1650 |
| 1656 void EffectGraphVisitor::BuildConstructorTypeArguments( | 1651 void EffectGraphVisitor::BuildConstructorTypeArguments( |
| 1657 ConstructorCallNode* node, | 1652 ConstructorCallNode* node, |
| 1658 Value** type_arguments, | 1653 Value** type_arguments, |
| 1659 Value** instantiator, | 1654 Value** instantiator, |
| 1660 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) { | 1655 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) { |
| 1661 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); | 1656 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); |
| 1662 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); | 1657 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); |
| 1663 if (node->type_arguments().IsNull() || | 1658 if (node->type_arguments().IsNull() || |
| 1664 node->type_arguments().IsInstantiated()) { | 1659 node->type_arguments().IsInstantiated()) { |
| 1665 Value* type_arguments_val = Bind(Constant(node->type_arguments())); | 1660 Value* type_arguments_val = Bind(new ConstantComp(node->type_arguments())); |
| 1666 if (call_arguments != NULL) { | 1661 if (call_arguments != NULL) { |
| 1667 ASSERT(type_arguments == NULL); | 1662 ASSERT(type_arguments == NULL); |
| 1668 call_arguments->Add(PushArgument(type_arguments_val)); | 1663 call_arguments->Add(PushArgument(type_arguments_val)); |
| 1669 } else { | 1664 } else { |
| 1670 ASSERT(type_arguments != NULL); | 1665 ASSERT(type_arguments != NULL); |
| 1671 *type_arguments = type_arguments_val; | 1666 *type_arguments = type_arguments_val; |
| 1672 } | 1667 } |
| 1673 | 1668 |
| 1674 // No instantiator required. | 1669 // No instantiator required. |
| 1675 Value* instantiator_val = Bind( | 1670 Value* instantiator_val = Bind(new ConstantComp( |
| 1676 Constant(Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)))); | 1671 Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)))); |
| 1677 if (call_arguments != NULL) { | 1672 if (call_arguments != NULL) { |
| 1678 ASSERT(instantiator == NULL); | 1673 ASSERT(instantiator == NULL); |
| 1679 call_arguments->Add(PushArgument(instantiator_val)); | 1674 call_arguments->Add(PushArgument(instantiator_val)); |
| 1680 } else { | 1675 } else { |
| 1681 ASSERT(instantiator != NULL); | 1676 ASSERT(instantiator != NULL); |
| 1682 *instantiator = instantiator_val; | 1677 *instantiator = instantiator_val; |
| 1683 } | 1678 } |
| 1684 return; | 1679 return; |
| 1685 } | 1680 } |
| 1686 // The type arguments are uninstantiated. The generated pseudo code: | 1681 // The type arguments are uninstantiated. The generated pseudo code: |
| (...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2166 num_context_variables)); | 2161 num_context_variables)); |
| 2167 | 2162 |
| 2168 // If this node_sequence is the body of the function being compiled, and if | 2163 // If this node_sequence is the body of the function being compiled, and if |
| 2169 // this function is not a closure, do not link the current context as the | 2164 // this function is not a closure, do not link the current context as the |
| 2170 // parent of the newly allocated context, as it is not accessible. Instead, | 2165 // parent of the newly allocated context, as it is not accessible. Instead, |
| 2171 // save it in a pre-allocated variable and restore it on exit. | 2166 // save it in a pre-allocated variable and restore it on exit. |
| 2172 if (MustSaveRestoreContext(node)) { | 2167 if (MustSaveRestoreContext(node)) { |
| 2173 Value* current_context = Bind(new CurrentContextComp()); | 2168 Value* current_context = Bind(new CurrentContextComp()); |
| 2174 Do(BuildStoreLocal(*owner()->parsed_function().saved_context_var(), | 2169 Do(BuildStoreLocal(*owner()->parsed_function().saved_context_var(), |
| 2175 current_context)); | 2170 current_context)); |
| 2176 Value* null_context = Bind(Constant(Object::ZoneHandle())); | 2171 Value* null_context = Bind(new ConstantComp(Object::ZoneHandle())); |
| 2177 Do(new StoreContextComp(null_context)); | 2172 Do(new StoreContextComp(null_context)); |
| 2178 } | 2173 } |
| 2179 | 2174 |
| 2180 Do(new ChainContextComp(allocated_context)); | 2175 Do(new ChainContextComp(allocated_context)); |
| 2181 owner()->set_context_level(scope->context_level()); | 2176 owner()->set_context_level(scope->context_level()); |
| 2182 | 2177 |
| 2183 // If this node_sequence is the body of the function being compiled, copy | 2178 // If this node_sequence is the body of the function being compiled, copy |
| 2184 // the captured parameters from the frame into the context. | 2179 // the captured parameters from the frame into the context. |
| 2185 if (node == owner()->parsed_function().node_sequence()) { | 2180 if (node == owner()->parsed_function().node_sequence()) { |
| 2186 ASSERT(scope->context_level() == 1); | 2181 ASSERT(scope->context_level() == 1); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2200 temp_name, | 2195 temp_name, |
| 2201 Type::ZoneHandle(Type::DynamicType())); // Type. | 2196 Type::ZoneHandle(Type::DynamicType())); // Type. |
| 2202 temp_local->set_index(param_frame_index); | 2197 temp_local->set_index(param_frame_index); |
| 2203 | 2198 |
| 2204 // Copy parameter from local frame to current context. | 2199 // Copy parameter from local frame to current context. |
| 2205 Value* load = Bind(BuildLoadLocal(*temp_local)); | 2200 Value* load = Bind(BuildLoadLocal(*temp_local)); |
| 2206 Do(BuildStoreLocal(parameter, load)); | 2201 Do(BuildStoreLocal(parameter, load)); |
| 2207 // Write NULL to the source location to detect buggy accesses and | 2202 // Write NULL to the source location to detect buggy accesses and |
| 2208 // allow GC of passed value if it gets overwritten by a new value in | 2203 // allow GC of passed value if it gets overwritten by a new value in |
| 2209 // the function. | 2204 // the function. |
| 2210 Value* null_constant = Bind(Constant(Object::ZoneHandle())); | 2205 Value* null_constant = |
| 2206 Bind(new ConstantComp(Object::ZoneHandle())); |
| 2211 Do(BuildStoreLocal(*temp_local, null_constant)); | 2207 Do(BuildStoreLocal(*temp_local, null_constant)); |
| 2212 } | 2208 } |
| 2213 } | 2209 } |
| 2214 } | 2210 } |
| 2215 } | 2211 } |
| 2216 | 2212 |
| 2217 if (FLAG_enable_type_checks && | 2213 if (FLAG_enable_type_checks && |
| 2218 (node == owner()->parsed_function().node_sequence())) { | 2214 (node == owner()->parsed_function().node_sequence())) { |
| 2219 const Function& function = owner()->parsed_function().function(); | 2215 const Function& function = owner()->parsed_function().function(); |
| 2220 const int num_params = function.NumberOfParameters(); | 2216 const int num_params = function.NumberOfParameters(); |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2369 BuildThrowNode(node); | 2365 BuildThrowNode(node); |
| 2370 CloseFragment(); | 2366 CloseFragment(); |
| 2371 } | 2367 } |
| 2372 | 2368 |
| 2373 | 2369 |
| 2374 // A throw cannot be part of an expression, however, the parser may replace | 2370 // A throw cannot be part of an expression, however, the parser may replace |
| 2375 // certain expression nodes with a throw. In that case generate a literal null | 2371 // certain expression nodes with a throw. In that case generate a literal null |
| 2376 // so that the fragment is not closed in the middle of an expression. | 2372 // so that the fragment is not closed in the middle of an expression. |
| 2377 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { | 2373 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { |
| 2378 BuildThrowNode(node); | 2374 BuildThrowNode(node); |
| 2379 ReturnComputation(Constant(Instance::ZoneHandle())); | 2375 ReturnComputation(new ConstantComp(Instance::ZoneHandle())); |
| 2380 } | 2376 } |
| 2381 | 2377 |
| 2382 | 2378 |
| 2383 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { | 2379 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { |
| 2384 const intptr_t try_index = owner()->try_index(); | 2380 const intptr_t try_index = owner()->try_index(); |
| 2385 if (try_index >= 0) { | 2381 if (try_index >= 0) { |
| 2386 // We are about to generate code for an inlined finally block. Exceptions | 2382 // We are about to generate code for an inlined finally block. Exceptions |
| 2387 // thrown in this block of code should be treated as though they are | 2383 // thrown in this block of code should be treated as though they are |
| 2388 // thrown not from the current try block but the outer try block if any. | 2384 // thrown not from the current try block but the outer try block if any. |
| 2389 owner()->set_try_index((try_index - 1)); | 2385 owner()->set_try_index((try_index - 1)); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2426 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 2422 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 2427 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 2423 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 2428 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2424 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2429 const Error& error = Error::Handle( | 2425 const Error& error = Error::Handle( |
| 2430 LanguageError::New(String::Handle(String::New(chars)))); | 2426 LanguageError::New(String::Handle(String::New(chars)))); |
| 2431 Isolate::Current()->long_jump_base()->Jump(1, error); | 2427 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2432 } | 2428 } |
| 2433 | 2429 |
| 2434 | 2430 |
| 2435 } // namespace dart | 2431 } // namespace dart |
| OLD | NEW |