| 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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 ASSERT(is_open()); | 109 ASSERT(is_open()); |
| 110 if (is_empty()) { | 110 if (is_empty()) { |
| 111 entry_ = new GotoInstr(join); | 111 entry_ = new GotoInstr(join); |
| 112 } else { | 112 } else { |
| 113 exit()->Goto(join); | 113 exit()->Goto(join); |
| 114 } | 114 } |
| 115 exit_ = NULL; | 115 exit_ = NULL; |
| 116 } | 116 } |
| 117 | 117 |
| 118 | 118 |
| 119 MaterializeComp* EffectGraphVisitor::Constant(const Object& value) { |
| 120 return new MaterializeComp(new ConstantVal(value)); |
| 121 } |
| 122 |
| 123 |
| 119 // Appends a graph fragment to a block entry instruction. Returns the entry | 124 // Appends a graph fragment to a block entry instruction. Returns the entry |
| 120 // instruction if the fragment was empty or else the exit of the fragment if | 125 // instruction if the fragment was empty or else the exit of the fragment if |
| 121 // it was non-empty (so NULL if the fragment is closed). | 126 // it was non-empty (so NULL if the fragment is closed). |
| 122 // | 127 // |
| 123 // Note that the fragment is no longer a valid fragment after calling this | 128 // Note that the fragment is no longer a valid fragment after calling this |
| 124 // function -- the fragment is closed at its entry because the entry has a | 129 // function -- the fragment is closed at its entry because the entry has a |
| 125 // predecessor in the graph. | 130 // predecessor in the graph. |
| 126 static Instruction* AppendFragment(BlockEntryInstr* entry, | 131 static Instruction* AppendFragment(BlockEntryInstr* entry, |
| 127 const EffectGraphVisitor& fragment) { | 132 const EffectGraphVisitor& fragment) { |
| 128 if (fragment.is_empty()) return entry; | 133 if (fragment.is_empty()) return entry; |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 } | 269 } |
| 265 | 270 |
| 266 | 271 |
| 267 void TestGraphVisitor::ReturnValue(Value* value) { | 272 void TestGraphVisitor::ReturnValue(Value* value) { |
| 268 if (FLAG_enable_type_checks) { | 273 if (FLAG_enable_type_checks) { |
| 269 value = Bind(new AssertBooleanComp(condition_token_pos(), | 274 value = Bind(new AssertBooleanComp(condition_token_pos(), |
| 270 owner()->try_index(), | 275 owner()->try_index(), |
| 271 value)); | 276 value)); |
| 272 } | 277 } |
| 273 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 278 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 274 Value* constant_true = Bind(new ConstantVal(bool_true)); | 279 Value* constant_true = Bind(Constant(bool_true)); |
| 275 BranchInstr* branch = new BranchInstr(condition_token_pos(), | 280 BranchInstr* branch = new BranchInstr(condition_token_pos(), |
| 276 owner()->try_index(), | 281 owner()->try_index(), |
| 277 value, | 282 value, |
| 278 constant_true, | 283 constant_true, |
| 279 Token::kEQ_STRICT); | 284 Token::kEQ_STRICT); |
| 280 AddInstruction(branch); | 285 AddInstruction(branch); |
| 281 CloseFragment(); | 286 CloseFragment(); |
| 282 true_successor_address_ = branch->true_successor_address(); | 287 true_successor_address_ = branch->true_successor_address(); |
| 283 false_successor_address_ = branch->false_successor_address(); | 288 false_successor_address_ = branch->false_successor_address(); |
| 284 } | 289 } |
| 285 | 290 |
| 286 | 291 |
| 287 void TestGraphVisitor::MergeBranchWithComparison(ComparisonComp* comp) { | 292 void TestGraphVisitor::MergeBranchWithComparison(ComparisonComp* comp) { |
| 288 ASSERT(!FLAG_enable_type_checks); | 293 ASSERT(!FLAG_enable_type_checks); |
| 289 BranchInstr* branch = new BranchInstr(condition_token_pos(), | 294 BranchInstr* branch = new BranchInstr(condition_token_pos(), |
| 290 owner()->try_index(), | 295 owner()->try_index(), |
| 291 comp->left(), | 296 comp->left(), |
| 292 comp->right(), | 297 comp->right(), |
| 293 comp->kind()); | 298 comp->kind()); |
| 294 AddInstruction(branch); | 299 AddInstruction(branch); |
| 295 CloseFragment(); | 300 CloseFragment(); |
| 296 true_successor_address_ = branch->true_successor_address(); | 301 true_successor_address_ = branch->true_successor_address(); |
| 297 false_successor_address_ = branch->false_successor_address(); | 302 false_successor_address_ = branch->false_successor_address(); |
| 298 } | 303 } |
| 299 | 304 |
| 300 | 305 |
| 301 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateComp* comp) { | 306 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateComp* comp) { |
| 302 ASSERT(!FLAG_enable_type_checks); | 307 ASSERT(!FLAG_enable_type_checks); |
| 303 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 308 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 304 Value* constant_true = Bind(new ConstantVal(bool_true)); | 309 Value* constant_true = Bind(Constant(bool_true)); |
| 305 BranchInstr* branch = new BranchInstr(condition_token_pos(), | 310 BranchInstr* branch = new BranchInstr(condition_token_pos(), |
| 306 owner()->try_index(), | 311 owner()->try_index(), |
| 307 comp->value(), | 312 comp->value(), |
| 308 constant_true, | 313 constant_true, |
| 309 Token::kNE_STRICT); | 314 Token::kNE_STRICT); |
| 310 AddInstruction(branch); | 315 AddInstruction(branch); |
| 311 CloseFragment(); | 316 CloseFragment(); |
| 312 true_successor_address_ = branch->true_successor_address(); | 317 true_successor_address_ = branch->true_successor_address(); |
| 313 false_successor_address_ = branch->false_successor_address(); | 318 false_successor_address_ = branch->false_successor_address(); |
| 314 } | 319 } |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 } | 394 } |
| 390 | 395 |
| 391 | 396 |
| 392 // <Expression> ::= Literal { literal: Instance } | 397 // <Expression> ::= Literal { literal: Instance } |
| 393 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) { | 398 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) { |
| 394 return; | 399 return; |
| 395 } | 400 } |
| 396 | 401 |
| 397 | 402 |
| 398 void ValueGraphVisitor::VisitLiteralNode(LiteralNode* node) { | 403 void ValueGraphVisitor::VisitLiteralNode(LiteralNode* node) { |
| 399 ReturnComputation(new ConstantVal(node->literal())); | 404 ReturnComputation(Constant(node->literal())); |
| 400 } | 405 } |
| 401 | 406 |
| 402 | 407 |
| 403 // Type nodes only occur as the right-hand side of instanceof comparisons, | 408 // Type nodes only occur as the right-hand side of instanceof comparisons, |
| 404 // and they are handled specially in that context. | 409 // and they are handled specially in that context. |
| 405 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } | 410 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } |
| 406 | 411 |
| 407 | 412 |
| 408 // Returns true if the type check can be skipped, for example, if the | 413 // Returns true if the type check can be skipped, for example, if the |
| 409 // destination type is Dynamic or if the compile type of the value is a subtype | 414 // 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... |
| 541 | 546 |
| 542 ValueGraphVisitor for_right(owner(), temp_index()); | 547 ValueGraphVisitor for_right(owner(), temp_index()); |
| 543 node->right()->Visit(&for_right); | 548 node->right()->Visit(&for_right); |
| 544 Value* right_value = for_right.value(); | 549 Value* right_value = for_right.value(); |
| 545 if (FLAG_enable_type_checks) { | 550 if (FLAG_enable_type_checks) { |
| 546 right_value = | 551 right_value = |
| 547 for_right.Bind(new AssertBooleanComp(node->right()->token_pos(), | 552 for_right.Bind(new AssertBooleanComp(node->right()->token_pos(), |
| 548 owner()->try_index(), | 553 owner()->try_index(), |
| 549 right_value)); | 554 right_value)); |
| 550 } | 555 } |
| 551 Value* constant_true = for_right.Bind(new ConstantVal(bool_true)); | 556 Value* constant_true = for_right.Bind(Constant(bool_true)); |
| 552 Value* compare = | 557 Value* compare = |
| 553 for_right.Bind(new StrictCompareComp(Token::kEQ_STRICT, | 558 for_right.Bind(new StrictCompareComp(Token::kEQ_STRICT, |
| 554 right_value, | 559 right_value, |
| 555 constant_true)); | 560 constant_true)); |
| 556 for_right.Do(BuildStoreLocal( | 561 for_right.Do(BuildStoreLocal( |
| 557 *owner()->parsed_function().expression_temp_var(), | 562 *owner()->parsed_function().expression_temp_var(), |
| 558 compare)); | 563 compare)); |
| 559 | 564 |
| 560 if (node->kind() == Token::kAND) { | 565 if (node->kind() == Token::kAND) { |
| 561 ValueGraphVisitor for_false(owner(), temp_index()); | 566 ValueGraphVisitor for_false(owner(), temp_index()); |
| 562 Value* constant_false = for_false.Bind(new ConstantVal(bool_false)); | 567 Value* constant_false = for_false.Bind(Constant(bool_false)); |
| 563 for_false.Do(BuildStoreLocal( | 568 for_false.Do(BuildStoreLocal( |
| 564 *owner()->parsed_function().expression_temp_var(), | 569 *owner()->parsed_function().expression_temp_var(), |
| 565 constant_false)); | 570 constant_false)); |
| 566 Join(for_test, for_right, for_false); | 571 Join(for_test, for_right, for_false); |
| 567 } else { | 572 } else { |
| 568 ASSERT(node->kind() == Token::kOR); | 573 ASSERT(node->kind() == Token::kOR); |
| 569 ValueGraphVisitor for_true(owner(), temp_index()); | 574 ValueGraphVisitor for_true(owner(), temp_index()); |
| 570 Value* constant_true = for_true.Bind(new ConstantVal(bool_true)); | 575 Value* constant_true = for_true.Bind(Constant(bool_true)); |
| 571 for_true.Do(BuildStoreLocal( | 576 for_true.Do(BuildStoreLocal( |
| 572 *owner()->parsed_function().expression_temp_var(), | 577 *owner()->parsed_function().expression_temp_var(), |
| 573 constant_true)); | 578 constant_true)); |
| 574 Join(for_test, for_true, for_right); | 579 Join(for_test, for_true, for_right); |
| 575 } | 580 } |
| 576 ReturnComputation( | 581 ReturnComputation( |
| 577 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); | 582 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); |
| 578 return; | 583 return; |
| 579 } | 584 } |
| 580 EffectGraphVisitor::VisitBinaryOpNode(node); | 585 EffectGraphVisitor::VisitBinaryOpNode(node); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 605 Value* loaded = Bind(BuildLoadLocal(expr_temp)); | 610 Value* loaded = Bind(BuildLoadLocal(expr_temp)); |
| 606 instantiator_type_arguments = | 611 instantiator_type_arguments = |
| 607 BuildInstantiatorTypeArguments(token_pos, loaded); | 612 BuildInstantiatorTypeArguments(token_pos, loaded); |
| 608 } | 613 } |
| 609 *instantiator_result = instantiator; | 614 *instantiator_result = instantiator; |
| 610 *instantiator_type_arguments_result = instantiator_type_arguments; | 615 *instantiator_type_arguments_result = instantiator_type_arguments; |
| 611 } | 616 } |
| 612 | 617 |
| 613 | 618 |
| 614 Value* EffectGraphVisitor::BuildNullValue() { | 619 Value* EffectGraphVisitor::BuildNullValue() { |
| 615 return Bind(new ConstantVal(Object::ZoneHandle())); | 620 return Bind(Constant(Object::ZoneHandle())); |
| 616 } | 621 } |
| 617 | 622 |
| 618 | 623 |
| 619 // Used for testing incoming arguments. | 624 // Used for testing incoming arguments. |
| 620 AssertAssignableComp* EffectGraphVisitor::BuildAssertAssignable( | 625 AssertAssignableComp* EffectGraphVisitor::BuildAssertAssignable( |
| 621 intptr_t token_pos, | 626 intptr_t token_pos, |
| 622 Value* value, | 627 Value* value, |
| 623 const AbstractType& dst_type, | 628 const AbstractType& dst_type, |
| 624 const String& dst_name) { | 629 const String& dst_name) { |
| 625 // Build the type check computation. | 630 // Build the type check computation. |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 686 const AbstractType& type = node->right()->AsTypeNode()->type(); | 691 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 687 ASSERT(type.IsFinalized() && !type.IsMalformed()); | 692 ASSERT(type.IsFinalized() && !type.IsMalformed()); |
| 688 const bool negate_result = (node->kind() == Token::kISNOT); | 693 const bool negate_result = (node->kind() == Token::kISNOT); |
| 689 // All objects are instances of type T if Object type is a subtype of type T. | 694 // All objects are instances of type T if Object type is a subtype of type T. |
| 690 const Type& object_type = Type::Handle(Type::ObjectType()); | 695 const Type& object_type = Type::Handle(Type::ObjectType()); |
| 691 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { | 696 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { |
| 692 // Must evaluate left side. | 697 // Must evaluate left side. |
| 693 EffectGraphVisitor for_left_value(owner(), temp_index()); | 698 EffectGraphVisitor for_left_value(owner(), temp_index()); |
| 694 node->left()->Visit(&for_left_value); | 699 node->left()->Visit(&for_left_value); |
| 695 Append(for_left_value); | 700 Append(for_left_value); |
| 696 ReturnComputation(new ConstantVal(negate_result ? bool_false : bool_true)); | 701 ReturnComputation(Constant(negate_result ? bool_false : bool_true)); |
| 697 return; | 702 return; |
| 698 } | 703 } |
| 699 | 704 |
| 700 // Eliminate the test if it can be performed successfully at compile time. | 705 // Eliminate the test if it can be performed successfully at compile time. |
| 701 if ((node->left() != NULL) && | 706 if ((node->left() != NULL) && |
| 702 node->left()->IsLiteralNode() && | 707 node->left()->IsLiteralNode() && |
| 703 type.IsInstantiated()) { | 708 type.IsInstantiated()) { |
| 704 const Instance& literal_value = node->left()->AsLiteralNode()->literal(); | 709 const Instance& literal_value = node->left()->AsLiteralNode()->literal(); |
| 705 const Class& cls = Class::Handle(literal_value.clazz()); | 710 const Class& cls = Class::Handle(literal_value.clazz()); |
| 706 ConstantVal* result = NULL; | 711 MaterializeComp* result = NULL; |
| 707 if (cls.IsNullClass()) { | 712 if (cls.IsNullClass()) { |
| 708 // A null object is only an instance of Object and Dynamic, which has | 713 // A null object is only an instance of Object and Dynamic, which has |
| 709 // already been checked above (if the type is instantiated). So we can | 714 // already been checked above (if the type is instantiated). So we can |
| 710 // return false here if the instance is null (and if the type is | 715 // return false here if the instance is null (and if the type is |
| 711 // instantiated). | 716 // instantiated). |
| 712 result = new ConstantVal(negate_result ? bool_true : bool_false); | 717 result = Constant(negate_result ? bool_true : bool_false); |
| 713 } else { | 718 } else { |
| 714 if (literal_value.IsInstanceOf(type, TypeArguments::Handle(), NULL)) { | 719 if (literal_value.IsInstanceOf(type, TypeArguments::Handle(), NULL)) { |
| 715 result = new ConstantVal(negate_result ? bool_false : bool_true); | 720 result = Constant(negate_result ? bool_false : bool_true); |
| 716 } else { | 721 } else { |
| 717 result = new ConstantVal(negate_result ? bool_true : bool_false); | 722 result = Constant(negate_result ? bool_true : bool_false); |
| 718 } | 723 } |
| 719 } | 724 } |
| 720 ReturnComputation(result); | 725 ReturnComputation(result); |
| 721 return; | 726 return; |
| 722 } | 727 } |
| 723 | 728 |
| 724 ValueGraphVisitor for_left_value(owner(), temp_index()); | 729 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 725 node->left()->Visit(&for_left_value); | 730 node->left()->Visit(&for_left_value); |
| 726 Append(for_left_value); | 731 Append(for_left_value); |
| 727 Value* instantiator = NULL; | 732 Value* instantiator = NULL; |
| (...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1491 allocate_arguments); | 1496 allocate_arguments); |
| 1492 } | 1497 } |
| 1493 return Bind(allocate_comp); | 1498 return Bind(allocate_comp); |
| 1494 } | 1499 } |
| 1495 | 1500 |
| 1496 | 1501 |
| 1497 void EffectGraphVisitor::BuildConstructorCall( | 1502 void EffectGraphVisitor::BuildConstructorCall( |
| 1498 ConstructorCallNode* node, | 1503 ConstructorCallNode* node, |
| 1499 PushArgumentInstr* push_alloc_value) { | 1504 PushArgumentInstr* push_alloc_value) { |
| 1500 Value* ctor_arg = Bind( | 1505 Value* ctor_arg = Bind( |
| 1501 new ConstantVal(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); | 1506 Constant(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); |
| 1502 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); | 1507 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); |
| 1503 | 1508 |
| 1504 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1509 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1505 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1510 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1506 arguments->Add(push_alloc_value); | 1511 arguments->Add(push_alloc_value); |
| 1507 arguments->Add(push_ctor_arg); | 1512 arguments->Add(push_ctor_arg); |
| 1508 | 1513 |
| 1509 BuildPushArguments(*node->arguments(), arguments); | 1514 BuildPushArguments(*node->arguments(), arguments); |
| 1510 Do(new StaticCallComp(node->token_pos(), | 1515 Do(new StaticCallComp(node->token_pos(), |
| 1511 owner()->try_index(), | 1516 owner()->try_index(), |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1579 // The type arguments are compile time constants. | 1584 // The type arguments are compile time constants. |
| 1580 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); | 1585 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); |
| 1581 // Type is temporary. Only its type arguments are preserved. | 1586 // Type is temporary. Only its type arguments are preserved. |
| 1582 Type& type = Type::Handle( | 1587 Type& type = Type::Handle( |
| 1583 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); | 1588 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); |
| 1584 type ^= ClassFinalizer::FinalizeType( | 1589 type ^= ClassFinalizer::FinalizeType( |
| 1585 instantiator_class, type, ClassFinalizer::kFinalize); | 1590 instantiator_class, type, ClassFinalizer::kFinalize); |
| 1586 ASSERT(!type.IsMalformed()); | 1591 ASSERT(!type.IsMalformed()); |
| 1587 type_arguments = type.arguments(); | 1592 type_arguments = type.arguments(); |
| 1588 type_arguments = type_arguments.Canonicalize(); | 1593 type_arguments = type_arguments.Canonicalize(); |
| 1589 return Bind(new ConstantVal(type_arguments)); | 1594 return Bind(Constant(type_arguments)); |
| 1590 } | 1595 } |
| 1591 Function& outer_function = | 1596 Function& outer_function = |
| 1592 Function::Handle(owner()->parsed_function().function().raw()); | 1597 Function::Handle(owner()->parsed_function().function().raw()); |
| 1593 while (outer_function.IsLocalFunction()) { | 1598 while (outer_function.IsLocalFunction()) { |
| 1594 outer_function = outer_function.parent_function(); | 1599 outer_function = outer_function.parent_function(); |
| 1595 } | 1600 } |
| 1596 if (outer_function.IsFactory()) { | 1601 if (outer_function.IsFactory()) { |
| 1597 // No instantiator for factories. | 1602 // No instantiator for factories. |
| 1598 ASSERT(instantiator == NULL); | 1603 ASSERT(instantiator == NULL); |
| 1599 ASSERT(owner()->parsed_function().instantiator() != NULL); | 1604 ASSERT(owner()->parsed_function().instantiator() != NULL); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1617 instantiator, | 1622 instantiator, |
| 1618 type_arguments_instance_field_offset, | 1623 type_arguments_instance_field_offset, |
| 1619 Type::ZoneHandle())); // Not an instance, no type. | 1624 Type::ZoneHandle())); // Not an instance, no type. |
| 1620 } | 1625 } |
| 1621 | 1626 |
| 1622 | 1627 |
| 1623 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( | 1628 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( |
| 1624 intptr_t token_pos, | 1629 intptr_t token_pos, |
| 1625 const AbstractTypeArguments& type_arguments) { | 1630 const AbstractTypeArguments& type_arguments) { |
| 1626 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { | 1631 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { |
| 1627 return Bind(new ConstantVal(type_arguments)); | 1632 return Bind(Constant(type_arguments)); |
| 1628 } | 1633 } |
| 1629 // The type arguments are uninstantiated. | 1634 // The type arguments are uninstantiated. |
| 1630 Value* instantiator_value = | 1635 Value* instantiator_value = |
| 1631 BuildInstantiatorTypeArguments(token_pos, NULL); | 1636 BuildInstantiatorTypeArguments(token_pos, NULL); |
| 1632 return Bind(new InstantiateTypeArgumentsComp(token_pos, | 1637 return Bind(new InstantiateTypeArgumentsComp(token_pos, |
| 1633 owner()->try_index(), | 1638 owner()->try_index(), |
| 1634 type_arguments, | 1639 type_arguments, |
| 1635 instantiator_value)); | 1640 instantiator_value)); |
| 1636 } | 1641 } |
| 1637 | 1642 |
| 1638 | 1643 |
| 1639 void EffectGraphVisitor::BuildConstructorTypeArguments( | 1644 void EffectGraphVisitor::BuildConstructorTypeArguments( |
| 1640 ConstructorCallNode* node, | 1645 ConstructorCallNode* node, |
| 1641 Value** type_arguments, | 1646 Value** type_arguments, |
| 1642 Value** instantiator, | 1647 Value** instantiator, |
| 1643 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) { | 1648 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) { |
| 1644 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); | 1649 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); |
| 1645 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); | 1650 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); |
| 1646 if (node->type_arguments().IsNull() || | 1651 if (node->type_arguments().IsNull() || |
| 1647 node->type_arguments().IsInstantiated()) { | 1652 node->type_arguments().IsInstantiated()) { |
| 1648 Value* type_arguments_val = Bind(new ConstantVal(node->type_arguments())); | 1653 Value* type_arguments_val = Bind(Constant(node->type_arguments())); |
| 1649 if (call_arguments != NULL) { | 1654 if (call_arguments != NULL) { |
| 1650 ASSERT(type_arguments == NULL); | 1655 ASSERT(type_arguments == NULL); |
| 1651 call_arguments->Add(PushArgument(type_arguments_val)); | 1656 call_arguments->Add(PushArgument(type_arguments_val)); |
| 1652 } else { | 1657 } else { |
| 1653 ASSERT(type_arguments != NULL); | 1658 ASSERT(type_arguments != NULL); |
| 1654 *type_arguments = type_arguments_val; | 1659 *type_arguments = type_arguments_val; |
| 1655 } | 1660 } |
| 1656 | 1661 |
| 1657 // No instantiator required. | 1662 // No instantiator required. |
| 1658 Value* instantiator_val = Bind( | 1663 Value* instantiator_val = Bind( |
| 1659 new ConstantVal(Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)))); | 1664 Constant(Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)))); |
| 1660 if (call_arguments != NULL) { | 1665 if (call_arguments != NULL) { |
| 1661 ASSERT(instantiator == NULL); | 1666 ASSERT(instantiator == NULL); |
| 1662 call_arguments->Add(PushArgument(instantiator_val)); | 1667 call_arguments->Add(PushArgument(instantiator_val)); |
| 1663 } else { | 1668 } else { |
| 1664 ASSERT(instantiator != NULL); | 1669 ASSERT(instantiator != NULL); |
| 1665 *instantiator = instantiator_val; | 1670 *instantiator = instantiator_val; |
| 1666 } | 1671 } |
| 1667 return; | 1672 return; |
| 1668 } | 1673 } |
| 1669 // The type arguments are uninstantiated. The generated pseudo code: | 1674 // The type arguments are uninstantiated. The generated pseudo code: |
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2150 num_context_variables)); | 2155 num_context_variables)); |
| 2151 | 2156 |
| 2152 // If this node_sequence is the body of the function being compiled, and if | 2157 // If this node_sequence is the body of the function being compiled, and if |
| 2153 // this function is not a closure, do not link the current context as the | 2158 // this function is not a closure, do not link the current context as the |
| 2154 // parent of the newly allocated context, as it is not accessible. Instead, | 2159 // parent of the newly allocated context, as it is not accessible. Instead, |
| 2155 // save it in a pre-allocated variable and restore it on exit. | 2160 // save it in a pre-allocated variable and restore it on exit. |
| 2156 if (MustSaveRestoreContext(node)) { | 2161 if (MustSaveRestoreContext(node)) { |
| 2157 Value* current_context = Bind(new CurrentContextComp()); | 2162 Value* current_context = Bind(new CurrentContextComp()); |
| 2158 Do(BuildStoreLocal(*owner()->parsed_function().saved_context_var(), | 2163 Do(BuildStoreLocal(*owner()->parsed_function().saved_context_var(), |
| 2159 current_context)); | 2164 current_context)); |
| 2160 Value* null_context = Bind(new ConstantVal(Object::ZoneHandle())); | 2165 Value* null_context = Bind(Constant(Object::ZoneHandle())); |
| 2161 Do(new StoreContextComp(null_context)); | 2166 Do(new StoreContextComp(null_context)); |
| 2162 } | 2167 } |
| 2163 | 2168 |
| 2164 Do(new ChainContextComp(allocated_context)); | 2169 Do(new ChainContextComp(allocated_context)); |
| 2165 owner()->set_context_level(scope->context_level()); | 2170 owner()->set_context_level(scope->context_level()); |
| 2166 | 2171 |
| 2167 // If this node_sequence is the body of the function being compiled, copy | 2172 // If this node_sequence is the body of the function being compiled, copy |
| 2168 // the captured parameters from the frame into the context. | 2173 // the captured parameters from the frame into the context. |
| 2169 if (node == owner()->parsed_function().node_sequence()) { | 2174 if (node == owner()->parsed_function().node_sequence()) { |
| 2170 ASSERT(scope->context_level() == 1); | 2175 ASSERT(scope->context_level() == 1); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2184 temp_name, | 2189 temp_name, |
| 2185 Type::ZoneHandle(Type::DynamicType())); // Type. | 2190 Type::ZoneHandle(Type::DynamicType())); // Type. |
| 2186 temp_local->set_index(param_frame_index); | 2191 temp_local->set_index(param_frame_index); |
| 2187 | 2192 |
| 2188 // Copy parameter from local frame to current context. | 2193 // Copy parameter from local frame to current context. |
| 2189 Value* load = Bind(BuildLoadLocal(*temp_local)); | 2194 Value* load = Bind(BuildLoadLocal(*temp_local)); |
| 2190 Do(BuildStoreLocal(parameter, load)); | 2195 Do(BuildStoreLocal(parameter, load)); |
| 2191 // Write NULL to the source location to detect buggy accesses and | 2196 // Write NULL to the source location to detect buggy accesses and |
| 2192 // allow GC of passed value if it gets overwritten by a new value in | 2197 // allow GC of passed value if it gets overwritten by a new value in |
| 2193 // the function. | 2198 // the function. |
| 2194 Value* null_constant = Bind(new ConstantVal(Object::ZoneHandle())); | 2199 Value* null_constant = Bind(Constant(Object::ZoneHandle())); |
| 2195 Do(BuildStoreLocal(*temp_local, null_constant)); | 2200 Do(BuildStoreLocal(*temp_local, null_constant)); |
| 2196 } | 2201 } |
| 2197 } | 2202 } |
| 2198 } | 2203 } |
| 2199 } | 2204 } |
| 2200 | 2205 |
| 2201 if (FLAG_enable_type_checks && | 2206 if (FLAG_enable_type_checks && |
| 2202 (node == owner()->parsed_function().node_sequence())) { | 2207 (node == owner()->parsed_function().node_sequence())) { |
| 2203 const Function& function = owner()->parsed_function().function(); | 2208 const Function& function = owner()->parsed_function().function(); |
| 2204 const int num_params = function.NumberOfParameters(); | 2209 const int num_params = function.NumberOfParameters(); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2358 BuildThrowNode(node); | 2363 BuildThrowNode(node); |
| 2359 CloseFragment(); | 2364 CloseFragment(); |
| 2360 } | 2365 } |
| 2361 | 2366 |
| 2362 | 2367 |
| 2363 // A throw cannot be part of an expression, however, the parser may replace | 2368 // A throw cannot be part of an expression, however, the parser may replace |
| 2364 // certain expression nodes with a throw. In that case generate a literal null | 2369 // certain expression nodes with a throw. In that case generate a literal null |
| 2365 // so that the fragment is not closed in the middle of an expression. | 2370 // so that the fragment is not closed in the middle of an expression. |
| 2366 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { | 2371 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { |
| 2367 BuildThrowNode(node); | 2372 BuildThrowNode(node); |
| 2368 ReturnComputation(new ConstantVal(Instance::ZoneHandle())); | 2373 ReturnComputation(Constant(Instance::ZoneHandle())); |
| 2369 } | 2374 } |
| 2370 | 2375 |
| 2371 | 2376 |
| 2372 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { | 2377 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { |
| 2373 const intptr_t try_index = owner()->try_index(); | 2378 const intptr_t try_index = owner()->try_index(); |
| 2374 if (try_index >= 0) { | 2379 if (try_index >= 0) { |
| 2375 // We are about to generate code for an inlined finally block. Exceptions | 2380 // We are about to generate code for an inlined finally block. Exceptions |
| 2376 // thrown in this block of code should be treated as though they are | 2381 // thrown in this block of code should be treated as though they are |
| 2377 // thrown not from the current try block but the outer try block if any. | 2382 // thrown not from the current try block but the outer try block if any. |
| 2378 owner()->set_try_index((try_index - 1)); | 2383 owner()->set_try_index((try_index - 1)); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2415 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 2420 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 2416 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 2421 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 2417 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2422 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2418 const Error& error = Error::Handle( | 2423 const Error& error = Error::Handle( |
| 2419 LanguageError::New(String::Handle(String::New(chars)))); | 2424 LanguageError::New(String::Handle(String::New(chars)))); |
| 2420 Isolate::Current()->long_jump_base()->Jump(1, error); | 2425 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2421 } | 2426 } |
| 2422 | 2427 |
| 2423 | 2428 |
| 2424 } // namespace dart | 2429 } // namespace dart |
| OLD | NEW |