| 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 } else { | 59 } else { |
| 60 exit()->set_next(other_fragment.entry()); | 60 exit()->set_next(other_fragment.entry()); |
| 61 exit_ = other_fragment.exit(); | 61 exit_ = other_fragment.exit(); |
| 62 } | 62 } |
| 63 temp_index_ = other_fragment.temp_index(); | 63 temp_index_ = other_fragment.temp_index(); |
| 64 } | 64 } |
| 65 | 65 |
| 66 | 66 |
| 67 Value* EffectGraphVisitor::Bind(Definition* definition) { | 67 Value* EffectGraphVisitor::Bind(Definition* definition) { |
| 68 ASSERT(is_open()); | 68 ASSERT(is_open()); |
| 69 ASSERT(!owner()->InInliningContext() || !definition->CanDeoptimize()); |
| 69 DeallocateTempIndex(definition->InputCount()); | 70 DeallocateTempIndex(definition->InputCount()); |
| 70 definition->set_use_kind(Definition::kValue); | 71 definition->set_use_kind(Definition::kValue); |
| 71 definition->set_temp_index(AllocateTempIndex()); | 72 definition->set_temp_index(AllocateTempIndex()); |
| 72 if (is_empty()) { | 73 if (is_empty()) { |
| 73 entry_ = definition; | 74 entry_ = definition; |
| 74 } else { | 75 } else { |
| 75 exit()->set_next(definition); | 76 exit()->set_next(definition); |
| 76 } | 77 } |
| 77 exit_ = definition; | 78 exit_ = definition; |
| 78 return new Value(definition); | 79 return new Value(definition); |
| 79 } | 80 } |
| 80 | 81 |
| 81 | 82 |
| 82 void EffectGraphVisitor::Do(Definition* definition) { | 83 void EffectGraphVisitor::Do(Definition* definition) { |
| 83 ASSERT(is_open()); | 84 ASSERT(is_open()); |
| 85 ASSERT(!owner()->InInliningContext() || !definition->CanDeoptimize()); |
| 84 DeallocateTempIndex(definition->InputCount()); | 86 DeallocateTempIndex(definition->InputCount()); |
| 85 definition->set_use_kind(Definition::kEffect); | 87 definition->set_use_kind(Definition::kEffect); |
| 86 if (is_empty()) { | 88 if (is_empty()) { |
| 87 entry_ = definition; | 89 entry_ = definition; |
| 88 } else { | 90 } else { |
| 89 exit()->set_next(definition); | 91 exit()->set_next(definition); |
| 90 } | 92 } |
| 91 exit_ = definition; | 93 exit_ = definition; |
| 92 } | 94 } |
| 93 | 95 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 | 224 |
| 223 | 225 |
| 224 Definition* EffectGraphVisitor::BuildLoadExprTemp() { | 226 Definition* EffectGraphVisitor::BuildLoadExprTemp() { |
| 225 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var()); | 227 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var()); |
| 226 } | 228 } |
| 227 | 229 |
| 228 | 230 |
| 229 Definition* EffectGraphVisitor::BuildStoreLocal( | 231 Definition* EffectGraphVisitor::BuildStoreLocal( |
| 230 const LocalVariable& local, Value* value, bool result_is_needed) { | 232 const LocalVariable& local, Value* value, bool result_is_needed) { |
| 231 if (local.is_captured()) { | 233 if (local.is_captured()) { |
| 234 InlineBailout("EffectGraphVisitor::BuildStoreLocal (context)"); |
| 232 if (result_is_needed) { | 235 if (result_is_needed) { |
| 233 value = Bind(BuildStoreExprTemp(value)); | 236 value = Bind(BuildStoreExprTemp(value)); |
| 234 } | 237 } |
| 235 | 238 |
| 236 intptr_t delta = | 239 intptr_t delta = |
| 237 owner()->context_level() - local.owner()->context_level(); | 240 owner()->context_level() - local.owner()->context_level(); |
| 238 ASSERT(delta >= 0); | 241 ASSERT(delta >= 0); |
| 239 Value* context = Bind(new CurrentContextInstr()); | 242 Value* context = Bind(new CurrentContextInstr()); |
| 240 while (delta-- > 0) { | 243 while (delta-- > 0) { |
| 241 context = Bind(new LoadVMFieldInstr( | 244 context = Bind(new LoadVMFieldInstr( |
| (...skipping 12 matching lines...) Expand all Loading... |
| 254 return store; | 257 return store; |
| 255 } | 258 } |
| 256 } else { | 259 } else { |
| 257 return new StoreLocalInstr(local, value, owner()->context_level()); | 260 return new StoreLocalInstr(local, value, owner()->context_level()); |
| 258 } | 261 } |
| 259 } | 262 } |
| 260 | 263 |
| 261 | 264 |
| 262 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) { | 265 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) { |
| 263 if (local.is_captured()) { | 266 if (local.is_captured()) { |
| 267 InlineBailout("EffectGraphVisitor::BuildLoadLocal (context)"); |
| 264 intptr_t delta = | 268 intptr_t delta = |
| 265 owner()->context_level() - local.owner()->context_level(); | 269 owner()->context_level() - local.owner()->context_level(); |
| 266 ASSERT(delta >= 0); | 270 ASSERT(delta >= 0); |
| 267 Value* context = Bind(new CurrentContextInstr()); | 271 Value* context = Bind(new CurrentContextInstr()); |
| 268 while (delta-- > 0) { | 272 while (delta-- > 0) { |
| 269 context = Bind(new LoadVMFieldInstr( | 273 context = Bind(new LoadVMFieldInstr( |
| 270 context, Context::parent_offset(), Type::ZoneHandle())); | 274 context, Context::parent_offset(), Type::ZoneHandle())); |
| 271 } | 275 } |
| 272 return new LoadVMFieldInstr(context, | 276 return new LoadVMFieldInstr(context, |
| 273 Context::variable_offset(local.index()), | 277 Context::variable_offset(local.index()), |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { | 473 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { |
| 470 InlineBailout("EffectGraphVisitor::VisitReturnNode (finally)"); | 474 InlineBailout("EffectGraphVisitor::VisitReturnNode (finally)"); |
| 471 EffectGraphVisitor for_effect(owner(), temp_index()); | 475 EffectGraphVisitor for_effect(owner(), temp_index()); |
| 472 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); | 476 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
| 473 Append(for_effect); | 477 Append(for_effect); |
| 474 if (!is_open()) return; | 478 if (!is_open()) return; |
| 475 } | 479 } |
| 476 | 480 |
| 477 Value* return_value = for_value.value(); | 481 Value* return_value = for_value.value(); |
| 478 if (FLAG_enable_type_checks) { | 482 if (FLAG_enable_type_checks) { |
| 479 InlineBailout("EffectGraphVisitor::VisitReturnNode (type check)"); | |
| 480 const Function& function = owner()->parsed_function().function(); | 483 const Function& function = owner()->parsed_function().function(); |
| 481 const bool is_implicit_dynamic_getter = | 484 const bool is_implicit_dynamic_getter = |
| 482 (!function.is_static() && | 485 (!function.is_static() && |
| 483 ((function.kind() == RawFunction::kImplicitGetter) || | 486 ((function.kind() == RawFunction::kImplicitGetter) || |
| 484 (function.kind() == RawFunction::kConstImplicitGetter))); | 487 (function.kind() == RawFunction::kConstImplicitGetter))); |
| 485 // Implicit getters do not need a type check at return, unless they compute | 488 // Implicit getters do not need a type check at return, unless they compute |
| 486 // the initial value of a static field. | 489 // the initial value of a static field. |
| 487 // The body of a constructor cannot modify the type of the | 490 // The body of a constructor cannot modify the type of the |
| 488 // constructed instance, which is passed in as an implicit parameter. | 491 // constructed instance, which is passed in as an implicit parameter. |
| 489 // However, factories may create an instance of the wrong type. | 492 // However, factories may create an instance of the wrong type. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } | 537 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } |
| 535 | 538 |
| 536 | 539 |
| 537 // Returns true if the type check can be skipped, for example, if the | 540 // Returns true if the type check can be skipped, for example, if the |
| 538 // destination type is Dynamic or if the compile type of the value is a subtype | 541 // destination type is Dynamic or if the compile type of the value is a subtype |
| 539 // of the destination type. | 542 // of the destination type. |
| 540 bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos, | 543 bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos, |
| 541 Value* value, | 544 Value* value, |
| 542 const AbstractType& dst_type, | 545 const AbstractType& dst_type, |
| 543 const String& dst_name) { | 546 const String& dst_name) { |
| 544 InlineBailout("EffectGraphVisitor::CanSkipTypeCheck"); | |
| 545 ASSERT(!dst_type.IsNull()); | 547 ASSERT(!dst_type.IsNull()); |
| 546 ASSERT(dst_type.IsFinalized()); | 548 ASSERT(dst_type.IsFinalized()); |
| 547 | 549 |
| 548 // If the destination type is malformed, a dynamic type error must be thrown | 550 // If the destination type is malformed, a dynamic type error must be thrown |
| 549 // at run time. | 551 // at run time. |
| 550 if (dst_type.IsMalformed()) { | 552 if (dst_type.IsMalformed()) { |
| 551 return false; | 553 return false; |
| 552 } | 554 } |
| 553 | 555 |
| 554 // Any type is more specific than the Dynamic type and than the Object type. | 556 // Any type is more specific than the Dynamic type and than the Object type. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 582 eliminated); | 584 eliminated); |
| 583 } | 585 } |
| 584 return eliminated; | 586 return eliminated; |
| 585 } | 587 } |
| 586 | 588 |
| 587 | 589 |
| 588 // <Expression> :: Assignable { expr: <Expression> | 590 // <Expression> :: Assignable { expr: <Expression> |
| 589 // type: AbstractType | 591 // type: AbstractType |
| 590 // dst_name: String } | 592 // dst_name: String } |
| 591 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { | 593 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 592 InlineBailout("EffectGraphVisitor::VisitAssignableNode"); | |
| 593 UNREACHABLE(); | 594 UNREACHABLE(); |
| 594 } | 595 } |
| 595 | 596 |
| 596 | 597 |
| 597 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { | 598 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 598 InlineBailout("ValueGraphVisitor::VisitAssignableNode"); | |
| 599 ValueGraphVisitor for_value(owner(), temp_index()); | 599 ValueGraphVisitor for_value(owner(), temp_index()); |
| 600 node->expr()->Visit(&for_value); | 600 node->expr()->Visit(&for_value); |
| 601 Append(for_value); | 601 Append(for_value); |
| 602 ReturnValue(BuildAssignableValue(node->expr()->token_pos(), | 602 ReturnValue(BuildAssignableValue(node->expr()->token_pos(), |
| 603 for_value.value(), | 603 for_value.value(), |
| 604 node->type(), | 604 node->type(), |
| 605 node->dst_name())); | 605 node->dst_name())); |
| 606 } | 606 } |
| 607 | 607 |
| 608 | 608 |
| 609 // <Expression> :: BinaryOp { kind: Token::Kind | 609 // <Expression> :: BinaryOp { kind: Token::Kind |
| 610 // left: <Expression> | 610 // left: <Expression> |
| 611 // right: <Expression> } | 611 // right: <Expression> } |
| 612 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 612 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 613 InlineBailout("EffectGraphVisitor::VisitBinaryOpNode"); | |
| 614 // Operators "&&" and "||" cannot be overloaded therefore do not call | 613 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 615 // operator. | 614 // operator. |
| 616 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 615 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 617 // See ValueGraphVisitor::VisitBinaryOpNode. | 616 // See ValueGraphVisitor::VisitBinaryOpNode. |
| 618 TestGraphVisitor for_left(owner(), | 617 TestGraphVisitor for_left(owner(), |
| 619 temp_index(), | 618 temp_index(), |
| 620 node->left()->token_pos()); | 619 node->left()->token_pos()); |
| 621 node->left()->Visit(&for_left); | 620 node->left()->Visit(&for_left); |
| 622 EffectGraphVisitor for_right(owner(), temp_index()); | 621 EffectGraphVisitor for_right(owner(), temp_index()); |
| 623 node->right()->Visit(&for_right); | 622 node->right()->Visit(&for_right); |
| 624 EffectGraphVisitor empty(owner(), temp_index()); | 623 EffectGraphVisitor empty(owner(), temp_index()); |
| 625 if (node->kind() == Token::kAND) { | 624 if (node->kind() == Token::kAND) { |
| 626 Join(for_left, for_right, empty); | 625 Join(for_left, for_right, empty); |
| 627 } else { | 626 } else { |
| 628 Join(for_left, empty, for_right); | 627 Join(for_left, empty, for_right); |
| 629 } | 628 } |
| 630 return; | 629 return; |
| 631 } | 630 } |
| 631 InlineBailout("EffectGraphVisitor::VisitBinaryOpNode (deopt)"); |
| 632 ValueGraphVisitor for_left_value(owner(), temp_index()); | 632 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 633 node->left()->Visit(&for_left_value); | 633 node->left()->Visit(&for_left_value); |
| 634 Append(for_left_value); | 634 Append(for_left_value); |
| 635 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); | 635 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); |
| 636 | 636 |
| 637 ValueGraphVisitor for_right_value(owner(), temp_index()); | 637 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 638 node->right()->Visit(&for_right_value); | 638 node->right()->Visit(&for_right_value); |
| 639 Append(for_right_value); | 639 Append(for_right_value); |
| 640 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); | 640 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); |
| 641 | 641 |
| 642 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 642 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 643 new ZoneGrowableArray<PushArgumentInstr*>(2); | 643 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 644 arguments->Add(push_left); | 644 arguments->Add(push_left); |
| 645 arguments->Add(push_right); | 645 arguments->Add(push_right); |
| 646 const String& name = String::ZoneHandle(Symbols::New(node->Name())); | 646 const String& name = String::ZoneHandle(Symbols::New(node->Name())); |
| 647 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), | 647 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), |
| 648 name, | 648 name, |
| 649 node->kind(), | 649 node->kind(), |
| 650 arguments, | 650 arguments, |
| 651 Array::ZoneHandle(), | 651 Array::ZoneHandle(), |
| 652 2); | 652 2); |
| 653 ReturnDefinition(call); | 653 ReturnDefinition(call); |
| 654 } | 654 } |
| 655 | 655 |
| 656 | 656 |
| 657 // Special handling for AND/OR. | 657 // Special handling for AND/OR. |
| 658 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 658 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 659 InlineBailout("ValueGraphVisitor::VisitBinaryOpNode"); | |
| 660 // Operators "&&" and "||" cannot be overloaded therefore do not call | 659 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 661 // operator. | 660 // operator. |
| 662 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 661 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 663 // Implement short-circuit logic: do not evaluate right if evaluation | 662 // Implement short-circuit logic: do not evaluate right if evaluation |
| 664 // of left is sufficient. | 663 // of left is sufficient. |
| 665 // AND: left ? right === true : false; | 664 // AND: left ? right === true : false; |
| 666 // OR: left ? true : right === true; | 665 // OR: left ? true : right === true; |
| 667 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 666 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 668 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 667 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| 669 | 668 |
| 670 TestGraphVisitor for_test(owner(), | 669 TestGraphVisitor for_test(owner(), |
| 671 temp_index(), | 670 temp_index(), |
| 672 node->left()->token_pos()); | 671 node->left()->token_pos()); |
| 673 node->left()->Visit(&for_test); | 672 node->left()->Visit(&for_test); |
| 674 | 673 |
| 675 ValueGraphVisitor for_right(owner(), temp_index()); | 674 ValueGraphVisitor for_right(owner(), temp_index()); |
| 676 node->right()->Visit(&for_right); | 675 node->right()->Visit(&for_right); |
| 677 Value* right_value = for_right.value(); | 676 Value* right_value = for_right.value(); |
| 678 if (FLAG_enable_type_checks) { | 677 if (FLAG_enable_type_checks) { |
| 678 InlineBailout("ValueGraphVisitor::VisitBinaryOpNode (type check)"); |
| 679 right_value = | 679 right_value = |
| 680 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(), | 680 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(), |
| 681 right_value)); | 681 right_value)); |
| 682 } | 682 } |
| 683 Value* constant_true = for_right.Bind(new ConstantInstr(bool_true)); | 683 Value* constant_true = for_right.Bind(new ConstantInstr(bool_true)); |
| 684 Value* compare = | 684 Value* compare = |
| 685 for_right.Bind(new StrictCompareInstr(Token::kEQ_STRICT, | 685 for_right.Bind(new StrictCompareInstr(Token::kEQ_STRICT, |
| 686 right_value, | 686 right_value, |
| 687 constant_true)); | 687 constant_true)); |
| 688 for_right.Do(BuildStoreExprTemp(compare)); | 688 for_right.Do(BuildStoreExprTemp(compare)); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 703 return; | 703 return; |
| 704 } | 704 } |
| 705 EffectGraphVisitor::VisitBinaryOpNode(node); | 705 EffectGraphVisitor::VisitBinaryOpNode(node); |
| 706 } | 706 } |
| 707 | 707 |
| 708 | 708 |
| 709 void EffectGraphVisitor::BuildTypecheckArguments( | 709 void EffectGraphVisitor::BuildTypecheckArguments( |
| 710 intptr_t token_pos, | 710 intptr_t token_pos, |
| 711 Value** instantiator_result, | 711 Value** instantiator_result, |
| 712 Value** instantiator_type_arguments_result) { | 712 Value** instantiator_type_arguments_result) { |
| 713 InlineBailout("EffectGraphVisitor::VisitBinaryOpNode"); | |
| 714 Value* instantiator = NULL; | 713 Value* instantiator = NULL; |
| 715 Value* instantiator_type_arguments = NULL; | 714 Value* instantiator_type_arguments = NULL; |
| 716 const Class& instantiator_class = Class::Handle( | 715 const Class& instantiator_class = Class::Handle( |
| 717 owner()->parsed_function().function().Owner()); | 716 owner()->parsed_function().function().Owner()); |
| 718 // Since called only when type tested against is not instantiated. | 717 // Since called only when type tested against is not instantiated. |
| 719 ASSERT(instantiator_class.NumTypeParameters() > 0); | 718 ASSERT(instantiator_class.NumTypeParameters() > 0); |
| 720 instantiator = BuildInstantiator(); | 719 instantiator = BuildInstantiator(); |
| 721 if (instantiator == NULL) { | 720 if (instantiator == NULL) { |
| 722 // No instantiator when inside factory. | 721 // No instantiator when inside factory. |
| 723 instantiator = BuildNullValue(); | 722 instantiator = BuildNullValue(); |
| 724 instantiator_type_arguments = | 723 instantiator_type_arguments = |
| 725 BuildInstantiatorTypeArguments(token_pos, NULL); | 724 BuildInstantiatorTypeArguments(token_pos, NULL); |
| 726 } else { | 725 } else { |
| 727 // Preserve instantiator. | 726 // Preserve instantiator. |
| 728 instantiator = Bind(BuildStoreExprTemp(instantiator)); | 727 instantiator = Bind(BuildStoreExprTemp(instantiator)); |
| 729 Value* loaded = Bind(BuildLoadExprTemp()); | 728 Value* loaded = Bind(BuildLoadExprTemp()); |
| 730 instantiator_type_arguments = | 729 instantiator_type_arguments = |
| 731 BuildInstantiatorTypeArguments(token_pos, loaded); | 730 BuildInstantiatorTypeArguments(token_pos, loaded); |
| 732 } | 731 } |
| 733 *instantiator_result = instantiator; | 732 *instantiator_result = instantiator; |
| 734 *instantiator_type_arguments_result = instantiator_type_arguments; | 733 *instantiator_type_arguments_result = instantiator_type_arguments; |
| 735 } | 734 } |
| 736 | 735 |
| 737 | 736 |
| 738 Value* EffectGraphVisitor::BuildNullValue() { | 737 Value* EffectGraphVisitor::BuildNullValue() { |
| 739 InlineBailout("EffectGraphVisitor::BuildNullValue"); | |
| 740 return Bind(new ConstantInstr(Object::ZoneHandle())); | 738 return Bind(new ConstantInstr(Object::ZoneHandle())); |
| 741 } | 739 } |
| 742 | 740 |
| 743 | 741 |
| 744 // Used for testing incoming arguments. | 742 // Used for testing incoming arguments. |
| 745 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( | 743 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( |
| 746 intptr_t token_pos, | 744 intptr_t token_pos, |
| 747 Value* value, | 745 Value* value, |
| 748 const AbstractType& dst_type, | 746 const AbstractType& dst_type, |
| 749 const String& dst_name) { | 747 const String& dst_name) { |
| 750 InlineBailout("EffectGraphVisitor::BuildAssertAssignable"); | 748 InlineBailout("EffectGraphVisitor::BuildAssertAssignable (deopt)"); |
| 751 // Build the type check computation. | 749 // Build the type check computation. |
| 752 Value* instantiator = NULL; | 750 Value* instantiator = NULL; |
| 753 Value* instantiator_type_arguments = NULL; | 751 Value* instantiator_type_arguments = NULL; |
| 754 if (dst_type.IsInstantiated()) { | 752 if (dst_type.IsInstantiated()) { |
| 755 instantiator = BuildNullValue(); | 753 instantiator = BuildNullValue(); |
| 756 instantiator_type_arguments = BuildNullValue(); | 754 instantiator_type_arguments = BuildNullValue(); |
| 757 } else { | 755 } else { |
| 758 BuildTypecheckArguments(token_pos, | 756 BuildTypecheckArguments(token_pos, |
| 759 &instantiator, | 757 &instantiator, |
| 760 &instantiator_type_arguments); | 758 &instantiator_type_arguments); |
| 761 } | 759 } |
| 762 return new AssertAssignableInstr(token_pos, | 760 return new AssertAssignableInstr(token_pos, |
| 763 value, | 761 value, |
| 764 instantiator, | 762 instantiator, |
| 765 instantiator_type_arguments, | 763 instantiator_type_arguments, |
| 766 dst_type, | 764 dst_type, |
| 767 dst_name); | 765 dst_name); |
| 768 } | 766 } |
| 769 | 767 |
| 770 | 768 |
| 771 // Used for type casts and to test assignments. | 769 // Used for type casts and to test assignments. |
| 772 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos, | 770 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos, |
| 773 Value* value, | 771 Value* value, |
| 774 const AbstractType& dst_type, | 772 const AbstractType& dst_type, |
| 775 const String& dst_name) { | 773 const String& dst_name) { |
| 776 InlineBailout("EffectGraphVisitor::BuildAssignableValue"); | |
| 777 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { | 774 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { |
| 778 return value; | 775 return value; |
| 779 } | 776 } |
| 780 return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name)); | 777 return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name)); |
| 781 } | 778 } |
| 782 | 779 |
| 783 | 780 |
| 784 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { | 781 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
| 785 InlineBailout("EffectGraphVisitor::BuildTypeTest"); | |
| 786 ASSERT(Token::IsTypeTestOperator(node->kind())); | 782 ASSERT(Token::IsTypeTestOperator(node->kind())); |
| 787 EffectGraphVisitor for_left_value(owner(), temp_index()); | 783 EffectGraphVisitor for_left_value(owner(), temp_index()); |
| 788 node->left()->Visit(&for_left_value); | 784 node->left()->Visit(&for_left_value); |
| 789 Append(for_left_value); | 785 Append(for_left_value); |
| 790 } | 786 } |
| 791 | 787 |
| 792 | 788 |
| 793 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { | 789 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { |
| 794 InlineBailout("EffectGraphVisitor::BuildTypeCast"); | |
| 795 ASSERT(Token::IsTypeCastOperator(node->kind())); | 790 ASSERT(Token::IsTypeCastOperator(node->kind())); |
| 796 const AbstractType& type = node->right()->AsTypeNode()->type(); | 791 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 797 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. | 792 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. |
| 798 ValueGraphVisitor for_value(owner(), temp_index()); | 793 ValueGraphVisitor for_value(owner(), temp_index()); |
| 799 node->left()->Visit(&for_value); | 794 node->left()->Visit(&for_value); |
| 800 const String& dst_name = String::ZoneHandle( | 795 const String& dst_name = String::ZoneHandle( |
| 801 Symbols::New(Exceptions::kCastExceptionDstName)); | 796 Symbols::New(Exceptions::kCastExceptionDstName)); |
| 802 if (!CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) { | 797 if (!CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) { |
| 803 Append(for_value); | 798 Append(for_value); |
| 804 Do(BuildAssertAssignable( | 799 Do(BuildAssertAssignable( |
| 805 node->token_pos(), for_value.value(), type, dst_name)); | 800 node->token_pos(), for_value.value(), type, dst_name)); |
| 806 } | 801 } |
| 807 } | 802 } |
| 808 | 803 |
| 809 | 804 |
| 810 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { | 805 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
| 811 InlineBailout("ValueGraphVisitor::BuildTypeTest"); | |
| 812 ASSERT(Token::IsTypeTestOperator(node->kind())); | 806 ASSERT(Token::IsTypeTestOperator(node->kind())); |
| 813 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 807 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 814 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 808 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| 815 const AbstractType& type = node->right()->AsTypeNode()->type(); | 809 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 816 ASSERT(type.IsFinalized() && !type.IsMalformed()); | 810 ASSERT(type.IsFinalized() && !type.IsMalformed()); |
| 817 const bool negate_result = (node->kind() == Token::kISNOT); | 811 const bool negate_result = (node->kind() == Token::kISNOT); |
| 818 // All objects are instances of type T if Object type is a subtype of type T. | 812 // All objects are instances of type T if Object type is a subtype of type T. |
| 819 const Type& object_type = Type::Handle(Type::ObjectType()); | 813 const Type& object_type = Type::Handle(Type::ObjectType()); |
| 820 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { | 814 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { |
| 821 // Must evaluate left side. | 815 // Must evaluate left side. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 842 } else { | 836 } else { |
| 843 if (literal_value.IsInstanceOf(type, TypeArguments::Handle(), NULL)) { | 837 if (literal_value.IsInstanceOf(type, TypeArguments::Handle(), NULL)) { |
| 844 result = new ConstantInstr(negate_result ? bool_false : bool_true); | 838 result = new ConstantInstr(negate_result ? bool_false : bool_true); |
| 845 } else { | 839 } else { |
| 846 result = new ConstantInstr(negate_result ? bool_true : bool_false); | 840 result = new ConstantInstr(negate_result ? bool_true : bool_false); |
| 847 } | 841 } |
| 848 } | 842 } |
| 849 ReturnDefinition(result); | 843 ReturnDefinition(result); |
| 850 return; | 844 return; |
| 851 } | 845 } |
| 846 InlineBailout("ValueGraphVisitor::BuildTypeTest (deopt)"); |
| 852 | 847 |
| 853 ValueGraphVisitor for_left_value(owner(), temp_index()); | 848 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 854 node->left()->Visit(&for_left_value); | 849 node->left()->Visit(&for_left_value); |
| 855 Append(for_left_value); | 850 Append(for_left_value); |
| 856 Value* instantiator = NULL; | 851 Value* instantiator = NULL; |
| 857 Value* instantiator_type_arguments = NULL; | 852 Value* instantiator_type_arguments = NULL; |
| 858 if (type.IsInstantiated()) { | 853 if (type.IsInstantiated()) { |
| 859 instantiator = BuildNullValue(); | 854 instantiator = BuildNullValue(); |
| 860 instantiator_type_arguments = BuildNullValue(); | 855 instantiator_type_arguments = BuildNullValue(); |
| 861 } else { | 856 } else { |
| 862 BuildTypecheckArguments(node->token_pos(), | 857 BuildTypecheckArguments(node->token_pos(), |
| 863 &instantiator, | 858 &instantiator, |
| 864 &instantiator_type_arguments); | 859 &instantiator_type_arguments); |
| 865 } | 860 } |
| 866 InstanceOfInstr* instance_of = | 861 InstanceOfInstr* instance_of = |
| 867 new InstanceOfInstr(node->token_pos(), | 862 new InstanceOfInstr(node->token_pos(), |
| 868 for_left_value.value(), | 863 for_left_value.value(), |
| 869 instantiator, | 864 instantiator, |
| 870 instantiator_type_arguments, | 865 instantiator_type_arguments, |
| 871 node->right()->AsTypeNode()->type(), | 866 node->right()->AsTypeNode()->type(), |
| 872 (node->kind() == Token::kISNOT)); | 867 (node->kind() == Token::kISNOT)); |
| 873 ReturnDefinition(instance_of); | 868 ReturnDefinition(instance_of); |
| 874 } | 869 } |
| 875 | 870 |
| 876 | 871 |
| 877 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { | 872 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { |
| 878 InlineBailout("ValueGraphVisitor::BuildTypeCast"); | |
| 879 ASSERT(Token::IsTypeCastOperator(node->kind())); | 873 ASSERT(Token::IsTypeCastOperator(node->kind())); |
| 880 const AbstractType& type = node->right()->AsTypeNode()->type(); | 874 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 881 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. | 875 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. |
| 882 ValueGraphVisitor for_value(owner(), temp_index()); | 876 ValueGraphVisitor for_value(owner(), temp_index()); |
| 883 node->left()->Visit(&for_value); | 877 node->left()->Visit(&for_value); |
| 884 Append(for_value); | 878 Append(for_value); |
| 885 const String& dst_name = String::ZoneHandle( | 879 const String& dst_name = String::ZoneHandle( |
| 886 Symbols::New(Exceptions::kCastExceptionDstName)); | 880 Symbols::New(Exceptions::kCastExceptionDstName)); |
| 887 ReturnValue(BuildAssignableValue(node->token_pos(), | 881 ReturnValue(BuildAssignableValue(node->token_pos(), |
| 888 for_value.value(), | 882 for_value.value(), |
| 889 type, | 883 type, |
| 890 dst_name)); | 884 dst_name)); |
| 891 } | 885 } |
| 892 | 886 |
| 893 | 887 |
| 894 // <Expression> :: Comparison { kind: Token::Kind | 888 // <Expression> :: Comparison { kind: Token::Kind |
| 895 // left: <Expression> | 889 // left: <Expression> |
| 896 // right: <Expression> } | 890 // right: <Expression> } |
| 897 // TODO(srdjan): Implement new equality. | 891 // TODO(srdjan): Implement new equality. |
| 898 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { | 892 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { |
| 899 InlineBailout("EffectGraphVisitor::VisitComparisonNode"); | |
| 900 if (Token::IsTypeTestOperator(node->kind())) { | 893 if (Token::IsTypeTestOperator(node->kind())) { |
| 901 BuildTypeTest(node); | 894 BuildTypeTest(node); |
| 902 return; | 895 return; |
| 903 } | 896 } |
| 904 if (Token::IsTypeCastOperator(node->kind())) { | 897 if (Token::IsTypeCastOperator(node->kind())) { |
| 905 BuildTypeCast(node); | 898 BuildTypeCast(node); |
| 906 return; | 899 return; |
| 907 } | 900 } |
| 908 if ((node->kind() == Token::kEQ_STRICT) || | 901 if ((node->kind() == Token::kEQ_STRICT) || |
| 909 (node->kind() == Token::kNE_STRICT)) { | 902 (node->kind() == Token::kNE_STRICT)) { |
| 910 ValueGraphVisitor for_left_value(owner(), temp_index()); | 903 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 911 node->left()->Visit(&for_left_value); | 904 node->left()->Visit(&for_left_value); |
| 912 Append(for_left_value); | 905 Append(for_left_value); |
| 913 ValueGraphVisitor for_right_value(owner(), temp_index()); | 906 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 914 node->right()->Visit(&for_right_value); | 907 node->right()->Visit(&for_right_value); |
| 915 Append(for_right_value); | 908 Append(for_right_value); |
| 916 StrictCompareInstr* comp = new StrictCompareInstr( | 909 StrictCompareInstr* comp = new StrictCompareInstr( |
| 917 node->kind(), for_left_value.value(), for_right_value.value()); | 910 node->kind(), for_left_value.value(), for_right_value.value()); |
| 918 ReturnDefinition(comp); | 911 ReturnDefinition(comp); |
| 919 return; | 912 return; |
| 920 } | 913 } |
| 914 InlineBailout("EffectGraphVisitor::VisitComparisonNode (deopt)"); |
| 921 | 915 |
| 922 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { | 916 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { |
| 923 ValueGraphVisitor for_left_value(owner(), temp_index()); | 917 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 924 node->left()->Visit(&for_left_value); | 918 node->left()->Visit(&for_left_value); |
| 925 Append(for_left_value); | 919 Append(for_left_value); |
| 926 ValueGraphVisitor for_right_value(owner(), temp_index()); | 920 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 927 node->right()->Visit(&for_right_value); | 921 node->right()->Visit(&for_right_value); |
| 928 Append(for_right_value); | 922 Append(for_right_value); |
| 929 if (FLAG_enable_type_checks) { | 923 if (FLAG_enable_type_checks) { |
| 930 EqualityCompareInstr* comp = new EqualityCompareInstr( | 924 EqualityCompareInstr* comp = new EqualityCompareInstr( |
| (...skipping 27 matching lines...) Expand all Loading... |
| 958 Append(for_right_value); | 952 Append(for_right_value); |
| 959 RelationalOpInstr* comp = new RelationalOpInstr(node->token_pos(), | 953 RelationalOpInstr* comp = new RelationalOpInstr(node->token_pos(), |
| 960 node->kind(), | 954 node->kind(), |
| 961 for_left_value.value(), | 955 for_left_value.value(), |
| 962 for_right_value.value()); | 956 for_right_value.value()); |
| 963 ReturnDefinition(comp); | 957 ReturnDefinition(comp); |
| 964 } | 958 } |
| 965 | 959 |
| 966 | 960 |
| 967 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { | 961 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { |
| 968 InlineBailout("EffectGraphVisitor::VisitUnaryOpNode"); | |
| 969 // "!" cannot be overloaded, therefore do not call operator. | 962 // "!" cannot be overloaded, therefore do not call operator. |
| 970 if (node->kind() == Token::kNOT) { | 963 if (node->kind() == Token::kNOT) { |
| 971 ValueGraphVisitor for_value(owner(), temp_index()); | 964 ValueGraphVisitor for_value(owner(), temp_index()); |
| 972 node->operand()->Visit(&for_value); | 965 node->operand()->Visit(&for_value); |
| 973 Append(for_value); | 966 Append(for_value); |
| 974 Value* value = for_value.value(); | 967 Value* value = for_value.value(); |
| 975 if (FLAG_enable_type_checks) { | 968 if (FLAG_enable_type_checks) { |
| 976 value = | 969 value = |
| 977 Bind(new AssertBooleanInstr(node->operand()->token_pos(), value)); | 970 Bind(new AssertBooleanInstr(node->operand()->token_pos(), value)); |
| 978 } | 971 } |
| 979 BooleanNegateInstr* negate = new BooleanNegateInstr(value); | 972 BooleanNegateInstr* negate = new BooleanNegateInstr(value); |
| 980 ReturnDefinition(negate); | 973 ReturnDefinition(negate); |
| 981 return; | 974 return; |
| 982 } | 975 } |
| 976 InlineBailout("EffectGraphVisitor::VisitUnaryOpNode (deopt)"); |
| 977 |
| 983 ValueGraphVisitor for_value(owner(), temp_index()); | 978 ValueGraphVisitor for_value(owner(), temp_index()); |
| 984 node->operand()->Visit(&for_value); | 979 node->operand()->Visit(&for_value); |
| 985 Append(for_value); | 980 Append(for_value); |
| 986 PushArgumentInstr* push_value = PushArgument(for_value.value()); | 981 PushArgumentInstr* push_value = PushArgument(for_value.value()); |
| 987 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 982 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 988 new ZoneGrowableArray<PushArgumentInstr*>(1); | 983 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 989 arguments->Add(push_value); | 984 arguments->Add(push_value); |
| 990 String& name = String::ZoneHandle(); | 985 String& name = String::ZoneHandle(); |
| 991 if (node->kind() == Token::kSUB) { | 986 if (node->kind() == Token::kSUB) { |
| 992 name = Symbols::New("unary-"); | 987 name = Symbols::New("unary-"); |
| 993 } else { | 988 } else { |
| 994 name = Symbols::New(Token::Str(node->kind())); | 989 name = Symbols::New(Token::Str(node->kind())); |
| 995 } | 990 } |
| 996 InstanceCallInstr* call = new InstanceCallInstr( | 991 InstanceCallInstr* call = new InstanceCallInstr( |
| 997 node->token_pos(), name, node->kind(), | 992 node->token_pos(), name, node->kind(), |
| 998 arguments, Array::ZoneHandle(), 1); | 993 arguments, Array::ZoneHandle(), 1); |
| 999 ReturnDefinition(call); | 994 ReturnDefinition(call); |
| 1000 } | 995 } |
| 1001 | 996 |
| 1002 | 997 |
| 1003 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 998 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| 1004 InlineBailout("EffectGraphVisitor::VisitConditionalExprNode"); | |
| 1005 TestGraphVisitor for_test(owner(), | 999 TestGraphVisitor for_test(owner(), |
| 1006 temp_index(), | 1000 temp_index(), |
| 1007 node->condition()->token_pos()); | 1001 node->condition()->token_pos()); |
| 1008 node->condition()->Visit(&for_test); | 1002 node->condition()->Visit(&for_test); |
| 1009 | 1003 |
| 1010 // Translate the subexpressions for their effects. | 1004 // Translate the subexpressions for their effects. |
| 1011 EffectGraphVisitor for_true(owner(), temp_index()); | 1005 EffectGraphVisitor for_true(owner(), temp_index()); |
| 1012 node->true_expr()->Visit(&for_true); | 1006 node->true_expr()->Visit(&for_true); |
| 1013 EffectGraphVisitor for_false(owner(), temp_index()); | 1007 EffectGraphVisitor for_false(owner(), temp_index()); |
| 1014 node->false_expr()->Visit(&for_false); | 1008 node->false_expr()->Visit(&for_false); |
| 1015 | 1009 |
| 1016 Join(for_test, for_true, for_false); | 1010 Join(for_test, for_true, for_false); |
| 1017 } | 1011 } |
| 1018 | 1012 |
| 1019 | 1013 |
| 1020 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 1014 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| 1021 InlineBailout("ValueGraphVisitor::VisitConditionalExprNode"); | |
| 1022 TestGraphVisitor for_test(owner(), | 1015 TestGraphVisitor for_test(owner(), |
| 1023 temp_index(), | 1016 temp_index(), |
| 1024 node->condition()->token_pos()); | 1017 node->condition()->token_pos()); |
| 1025 node->condition()->Visit(&for_test); | 1018 node->condition()->Visit(&for_test); |
| 1026 | 1019 |
| 1027 ValueGraphVisitor for_true(owner(), temp_index()); | 1020 ValueGraphVisitor for_true(owner(), temp_index()); |
| 1028 node->true_expr()->Visit(&for_true); | 1021 node->true_expr()->Visit(&for_true); |
| 1029 ASSERT(for_true.is_open()); | 1022 ASSERT(for_true.is_open()); |
| 1030 for_true.Do(BuildStoreExprTemp(for_true.value())); | 1023 for_true.Do(BuildStoreExprTemp(for_true.value())); |
| 1031 | 1024 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1053 | 1046 |
| 1054 node->true_branch()->Visit(&for_true); | 1047 node->true_branch()->Visit(&for_true); |
| 1055 // The for_false graph fragment will be empty (default graph fragment) if | 1048 // The for_false graph fragment will be empty (default graph fragment) if |
| 1056 // we do not call Visit. | 1049 // we do not call Visit. |
| 1057 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false); | 1050 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false); |
| 1058 Join(for_test, for_true, for_false); | 1051 Join(for_test, for_true, for_false); |
| 1059 } | 1052 } |
| 1060 | 1053 |
| 1061 | 1054 |
| 1062 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) { | 1055 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) { |
| 1063 InlineBailout("EffectGraphVisitor::VisitSwitchNode"); | |
| 1064 EffectGraphVisitor switch_body(owner(), temp_index()); | 1056 EffectGraphVisitor switch_body(owner(), temp_index()); |
| 1065 node->body()->Visit(&switch_body); | 1057 node->body()->Visit(&switch_body); |
| 1066 Append(switch_body); | 1058 Append(switch_body); |
| 1067 if ((node->label() != NULL) && (node->label()->join_for_break() != NULL)) { | 1059 if ((node->label() != NULL) && (node->label()->join_for_break() != NULL)) { |
| 1068 if (is_open()) Goto(node->label()->join_for_break()); | 1060 if (is_open()) Goto(node->label()->join_for_break()); |
| 1069 exit_ = node->label()->join_for_break(); | 1061 exit_ = node->label()->join_for_break(); |
| 1070 } | 1062 } |
| 1071 // No continue label allowed. | 1063 // No continue label allowed. |
| 1072 ASSERT((node->label() == NULL) || | 1064 ASSERT((node->label() == NULL) || |
| 1073 (node->label()->join_for_continue() == NULL)); | 1065 (node->label()->join_for_continue() == NULL)); |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1398 node->label()->set_join_for_continue( | 1390 node->label()->set_join_for_continue( |
| 1399 new JoinEntryInstr(owner()->try_index())); | 1391 new JoinEntryInstr(owner()->try_index())); |
| 1400 } | 1392 } |
| 1401 jump_target = node->label()->join_for_continue(); | 1393 jump_target = node->label()->join_for_continue(); |
| 1402 } | 1394 } |
| 1403 Goto(jump_target); | 1395 Goto(jump_target); |
| 1404 } | 1396 } |
| 1405 | 1397 |
| 1406 | 1398 |
| 1407 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { | 1399 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { |
| 1408 InlineBailout("EffectGraphVisitor::VisitArgumentListNode"); | |
| 1409 UNREACHABLE(); | 1400 UNREACHABLE(); |
| 1410 } | 1401 } |
| 1411 | 1402 |
| 1412 | 1403 |
| 1413 void EffectGraphVisitor::VisitArgumentDefinitionTestNode( | 1404 void EffectGraphVisitor::VisitArgumentDefinitionTestNode( |
| 1414 ArgumentDefinitionTestNode* node) { | 1405 ArgumentDefinitionTestNode* node) { |
| 1415 Definition* load = BuildLoadLocal(node->saved_arguments_descriptor()); | 1406 Definition* load = BuildLoadLocal(node->saved_arguments_descriptor()); |
| 1416 Value* arguments_descriptor = Bind(load); | 1407 Value* arguments_descriptor = Bind(load); |
| 1417 ArgumentDefinitionTestInstr* arg_def_test = | 1408 ArgumentDefinitionTestInstr* arg_def_test = |
| 1418 new ArgumentDefinitionTestInstr(node, arguments_descriptor); | 1409 new ArgumentDefinitionTestInstr(node, arguments_descriptor); |
| 1419 ReturnDefinition(arg_def_test); | 1410 ReturnDefinition(arg_def_test); |
| 1420 } | 1411 } |
| 1421 | 1412 |
| 1422 | 1413 |
| 1423 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { | 1414 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { |
| 1424 InlineBailout("EffectGraphVisitor::VisitArrayNode"); | |
| 1425 // Translate the array elements and collect their values. | 1415 // Translate the array elements and collect their values. |
| 1426 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1416 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1427 new ZoneGrowableArray<PushArgumentInstr*>(node->length()); | 1417 new ZoneGrowableArray<PushArgumentInstr*>(node->length()); |
| 1428 for (int i = 0; i < node->length(); ++i) { | 1418 for (int i = 0; i < node->length(); ++i) { |
| 1429 ValueGraphVisitor for_value(owner(), temp_index()); | 1419 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1430 node->ElementAt(i)->Visit(&for_value); | 1420 node->ElementAt(i)->Visit(&for_value); |
| 1431 Append(for_value); | 1421 Append(for_value); |
| 1432 arguments->Add(PushArgument(for_value.value())); | 1422 arguments->Add(PushArgument(for_value.value())); |
| 1433 } | 1423 } |
| 1434 const AbstractTypeArguments& type_args = | 1424 const AbstractTypeArguments& type_args = |
| 1435 AbstractTypeArguments::ZoneHandle(node->type().arguments()); | 1425 AbstractTypeArguments::ZoneHandle(node->type().arguments()); |
| 1436 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), | 1426 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), |
| 1437 type_args); | 1427 type_args); |
| 1438 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), | 1428 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), |
| 1439 arguments, | 1429 arguments, |
| 1440 node->type(), | 1430 node->type(), |
| 1441 element_type); | 1431 element_type); |
| 1442 ReturnDefinition(create); | 1432 ReturnDefinition(create); |
| 1443 } | 1433 } |
| 1444 | 1434 |
| 1445 | 1435 |
| 1446 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { | 1436 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { |
| 1447 InlineBailout("EffectGraphVisitor::VisitClosureNode"); | |
| 1448 const Function& function = node->function(); | 1437 const Function& function = node->function(); |
| 1449 | 1438 |
| 1450 Value* receiver = NULL; | 1439 Value* receiver = NULL; |
| 1451 if (function.IsNonImplicitClosureFunction()) { | 1440 if (function.IsNonImplicitClosureFunction()) { |
| 1452 // The context scope may have already been set by the non-optimizing | 1441 // The context scope may have already been set by the non-optimizing |
| 1453 // compiler. If it was not, set it here. | 1442 // compiler. If it was not, set it here. |
| 1454 if (function.context_scope() == ContextScope::null()) { | 1443 if (function.context_scope() == ContextScope::null()) { |
| 1455 // TODO(regis): Why are we not doing this in the parser? | 1444 // TODO(regis): Why are we not doing this in the parser? |
| 1456 const ContextScope& context_scope = ContextScope::ZoneHandle( | 1445 const ContextScope& context_scope = ContextScope::ZoneHandle( |
| 1457 node->scope()->PreserveOuterScope(owner()->context_level())); | 1446 node->scope()->PreserveOuterScope(owner()->context_level())); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1488 } | 1477 } |
| 1489 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments); | 1478 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments); |
| 1490 arguments->Add(push_type_arguments); | 1479 arguments->Add(push_type_arguments); |
| 1491 ReturnDefinition(new CreateClosureInstr(node, arguments)); | 1480 ReturnDefinition(new CreateClosureInstr(node, arguments)); |
| 1492 } | 1481 } |
| 1493 | 1482 |
| 1494 | 1483 |
| 1495 void EffectGraphVisitor::TranslateArgumentList( | 1484 void EffectGraphVisitor::TranslateArgumentList( |
| 1496 const ArgumentListNode& node, | 1485 const ArgumentListNode& node, |
| 1497 ZoneGrowableArray<Value*>* values) { | 1486 ZoneGrowableArray<Value*>* values) { |
| 1498 InlineBailout("EffectGraphVisitor::TranslateArgumentList"); | |
| 1499 for (intptr_t i = 0; i < node.length(); ++i) { | 1487 for (intptr_t i = 0; i < node.length(); ++i) { |
| 1500 ValueGraphVisitor for_argument(owner(), temp_index()); | 1488 ValueGraphVisitor for_argument(owner(), temp_index()); |
| 1501 node.NodeAt(i)->Visit(&for_argument); | 1489 node.NodeAt(i)->Visit(&for_argument); |
| 1502 Append(for_argument); | 1490 Append(for_argument); |
| 1503 values->Add(for_argument.value()); | 1491 values->Add(for_argument.value()); |
| 1504 } | 1492 } |
| 1505 } | 1493 } |
| 1506 | 1494 |
| 1507 | 1495 |
| 1508 void EffectGraphVisitor::BuildPushArguments( | 1496 void EffectGraphVisitor::BuildPushArguments( |
| 1509 const ArgumentListNode& node, | 1497 const ArgumentListNode& node, |
| 1510 ZoneGrowableArray<PushArgumentInstr*>* values) { | 1498 ZoneGrowableArray<PushArgumentInstr*>* values) { |
| 1511 InlineBailout("EffectGraphVisitor::BuildPushArguments"); | |
| 1512 for (intptr_t i = 0; i < node.length(); ++i) { | 1499 for (intptr_t i = 0; i < node.length(); ++i) { |
| 1513 ValueGraphVisitor for_argument(owner(), temp_index()); | 1500 ValueGraphVisitor for_argument(owner(), temp_index()); |
| 1514 node.NodeAt(i)->Visit(&for_argument); | 1501 node.NodeAt(i)->Visit(&for_argument); |
| 1515 Append(for_argument); | 1502 Append(for_argument); |
| 1516 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); | 1503 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); |
| 1517 values->Add(push_arg); | 1504 values->Add(push_arg); |
| 1518 } | 1505 } |
| 1519 } | 1506 } |
| 1520 | 1507 |
| 1521 | 1508 |
| 1522 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { | 1509 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { |
| 1523 InlineBailout("EffectGraphVisitor::VisitInstanceCallNode"); | 1510 InlineBailout("EffectGraphVisitor::VisitInstanceCallNode (deopt)"); |
| 1524 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1511 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1525 node->receiver()->Visit(&for_receiver); | 1512 node->receiver()->Visit(&for_receiver); |
| 1526 Append(for_receiver); | 1513 Append(for_receiver); |
| 1527 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 1514 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 1528 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1515 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1529 new ZoneGrowableArray<PushArgumentInstr*>( | 1516 new ZoneGrowableArray<PushArgumentInstr*>( |
| 1530 node->arguments()->length() + 1); | 1517 node->arguments()->length() + 1); |
| 1531 arguments->Add(push_receiver); | 1518 arguments->Add(push_receiver); |
| 1532 | 1519 |
| 1533 BuildPushArguments(*node->arguments(), arguments); | 1520 BuildPushArguments(*node->arguments(), arguments); |
| 1534 InstanceCallInstr* call = new InstanceCallInstr( | 1521 InstanceCallInstr* call = new InstanceCallInstr( |
| 1535 node->token_pos(), | 1522 node->token_pos(), |
| 1536 node->function_name(), Token::kILLEGAL, arguments, | 1523 node->function_name(), Token::kILLEGAL, arguments, |
| 1537 node->arguments()->names(), 1); | 1524 node->arguments()->names(), 1); |
| 1538 ReturnDefinition(call); | 1525 ReturnDefinition(call); |
| 1539 } | 1526 } |
| 1540 | 1527 |
| 1541 | 1528 |
| 1542 // <Expression> ::= StaticCall { function: Function | 1529 // <Expression> ::= StaticCall { function: Function |
| 1543 // arguments: <ArgumentList> } | 1530 // arguments: <ArgumentList> } |
| 1544 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { | 1531 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { |
| 1545 InlineBailout("EffectGraphVisitor::VisitStaticCallNode"); | 1532 InlineBailout("EffectGraphVisitor::VisitStaticCallNode (deopt)"); |
| 1546 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1533 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1547 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 1534 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 1548 BuildPushArguments(*node->arguments(), arguments); | 1535 BuildPushArguments(*node->arguments(), arguments); |
| 1549 StaticCallInstr* call = | 1536 StaticCallInstr* call = |
| 1550 new StaticCallInstr(node->token_pos(), | 1537 new StaticCallInstr(node->token_pos(), |
| 1551 node->function(), | 1538 node->function(), |
| 1552 node->arguments()->names(), | 1539 node->arguments()->names(), |
| 1553 arguments); | 1540 arguments); |
| 1554 ReturnDefinition(call); | 1541 ReturnDefinition(call); |
| 1555 } | 1542 } |
| 1556 | 1543 |
| 1557 | 1544 |
| 1558 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall( | 1545 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall( |
| 1559 ClosureCallNode* node) { | 1546 ClosureCallNode* node) { |
| 1560 InlineBailout("EffectGraphVisitor::BuildClosureCall"); | 1547 InlineBailout("EffectGraphVisitor::BuildClosureCall (deopt)"); |
| 1561 ValueGraphVisitor for_closure(owner(), temp_index()); | 1548 ValueGraphVisitor for_closure(owner(), temp_index()); |
| 1562 node->closure()->Visit(&for_closure); | 1549 node->closure()->Visit(&for_closure); |
| 1563 Append(for_closure); | 1550 Append(for_closure); |
| 1564 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); | 1551 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); |
| 1565 | 1552 |
| 1566 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1553 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1567 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 1554 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 1568 arguments->Add(push_closure); | 1555 arguments->Add(push_closure); |
| 1569 BuildPushArguments(*node->arguments(), arguments); | 1556 BuildPushArguments(*node->arguments(), arguments); |
| 1570 | 1557 |
| 1571 // Save context around the call. | 1558 // Save context around the call. |
| 1572 BuildStoreContext(*owner()->parsed_function().expression_temp_var()); | 1559 BuildStoreContext(*owner()->parsed_function().expression_temp_var()); |
| 1573 return new ClosureCallInstr(node, arguments); | 1560 return new ClosureCallInstr(node, arguments); |
| 1574 } | 1561 } |
| 1575 | 1562 |
| 1576 | 1563 |
| 1577 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 1564 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 1578 InlineBailout("EffectGraphVisitor::VisitClosureCallNode"); | |
| 1579 Do(BuildClosureCall(node)); | 1565 Do(BuildClosureCall(node)); |
| 1580 // Restore context from saved location. | 1566 // Restore context from saved location. |
| 1581 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); | 1567 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); |
| 1582 } | 1568 } |
| 1583 | 1569 |
| 1584 | 1570 |
| 1585 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 1571 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 1586 InlineBailout("ValueGraphVisitor::VisitClosureCallNode"); | |
| 1587 Value* result = Bind(BuildClosureCall(node)); | 1572 Value* result = Bind(BuildClosureCall(node)); |
| 1588 // Restore context from temp. | 1573 // Restore context from temp. |
| 1589 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); | 1574 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); |
| 1590 ReturnValue(result); | 1575 ReturnValue(result); |
| 1591 } | 1576 } |
| 1592 | 1577 |
| 1593 | 1578 |
| 1594 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { | 1579 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { |
| 1595 InlineBailout("EffectGraphVisitor::VisitCloneContextNode"); | 1580 InlineBailout("EffectGraphVisitor::VisitCloneContextNode (deopt)"); |
| 1596 Value* context = Bind(new CurrentContextInstr()); | 1581 Value* context = Bind(new CurrentContextInstr()); |
| 1597 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context)); | 1582 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context)); |
| 1598 ReturnDefinition(new StoreContextInstr(clone)); | 1583 ReturnDefinition(new StoreContextInstr(clone)); |
| 1599 } | 1584 } |
| 1600 | 1585 |
| 1601 | 1586 |
| 1602 Value* EffectGraphVisitor::BuildObjectAllocation( | 1587 Value* EffectGraphVisitor::BuildObjectAllocation( |
| 1603 ConstructorCallNode* node) { | 1588 ConstructorCallNode* node) { |
| 1604 InlineBailout("EffectGraphVisitor::BuildObjectAllocation"); | |
| 1605 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); | 1589 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); |
| 1606 const bool requires_type_arguments = cls.HasTypeArguments(); | 1590 const bool requires_type_arguments = cls.HasTypeArguments(); |
| 1607 | 1591 |
| 1608 // In checked mode, if the type arguments are uninstantiated, they may need to | 1592 // In checked mode, if the type arguments are uninstantiated, they may need to |
| 1609 // be checked against declared bounds at run time. | 1593 // be checked against declared bounds at run time. |
| 1610 Definition* allocate_comp = NULL; | 1594 Definition* allocate_comp = NULL; |
| 1611 if (FLAG_enable_type_checks && | 1595 if (FLAG_enable_type_checks && |
| 1612 requires_type_arguments && | 1596 requires_type_arguments && |
| 1613 !node->type_arguments().IsNull() && | 1597 !node->type_arguments().IsNull() && |
| 1614 !node->type_arguments().IsInstantiated() && | 1598 !node->type_arguments().IsInstantiated() && |
| 1615 !node->type_arguments().IsWithinBoundsOf(cls, | 1599 !node->type_arguments().IsWithinBoundsOf(cls, |
| 1616 node->type_arguments(), | 1600 node->type_arguments(), |
| 1617 NULL)) { | 1601 NULL)) { |
| 1618 Value* type_arguments = NULL; | 1602 Value* type_arguments = NULL; |
| 1619 Value* instantiator = NULL; | 1603 Value* instantiator = NULL; |
| 1620 BuildConstructorTypeArguments(node, &type_arguments, &instantiator, NULL); | 1604 BuildConstructorTypeArguments(node, &type_arguments, &instantiator, NULL); |
| 1621 | 1605 |
| 1622 // The uninstantiated type arguments cannot be verified to be within their | 1606 // The uninstantiated type arguments cannot be verified to be within their |
| 1623 // bounds at compile time, so verify them at runtime. | 1607 // bounds at compile time, so verify them at runtime. |
| 1624 // Although the type arguments may be uninstantiated at compile time, they | 1608 // Although the type arguments may be uninstantiated at compile time, they |
| 1625 // may represent the identity vector and may be replaced by the instantiated | 1609 // may represent the identity vector and may be replaced by the instantiated |
| 1626 // type arguments of the instantiator at run time. | 1610 // type arguments of the instantiator at run time. |
| 1611 InlineBailout("EffectGraphVisitor::BuildObjectAllocation (deopt)"); |
| 1627 allocate_comp = new AllocateObjectWithBoundsCheckInstr(node, | 1612 allocate_comp = new AllocateObjectWithBoundsCheckInstr(node, |
| 1628 type_arguments, | 1613 type_arguments, |
| 1629 instantiator); | 1614 instantiator); |
| 1630 } else { | 1615 } else { |
| 1631 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = | 1616 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = |
| 1632 new ZoneGrowableArray<PushArgumentInstr*>(); | 1617 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 1633 | 1618 |
| 1634 if (requires_type_arguments) { | 1619 if (requires_type_arguments) { |
| 1635 BuildConstructorTypeArguments(node, NULL, NULL, allocate_arguments); | 1620 BuildConstructorTypeArguments(node, NULL, NULL, allocate_arguments); |
| 1636 } | 1621 } |
| 1637 | 1622 |
| 1638 allocate_comp = new AllocateObjectInstr(node, allocate_arguments); | 1623 allocate_comp = new AllocateObjectInstr(node, allocate_arguments); |
| 1639 } | 1624 } |
| 1640 return Bind(allocate_comp); | 1625 return Bind(allocate_comp); |
| 1641 } | 1626 } |
| 1642 | 1627 |
| 1643 | 1628 |
| 1644 void EffectGraphVisitor::BuildConstructorCall( | 1629 void EffectGraphVisitor::BuildConstructorCall( |
| 1645 ConstructorCallNode* node, | 1630 ConstructorCallNode* node, |
| 1646 PushArgumentInstr* push_alloc_value) { | 1631 PushArgumentInstr* push_alloc_value) { |
| 1647 InlineBailout("EffectGraphVisitor::BuildConstructorCall"); | 1632 InlineBailout("EffectGraphVisitor::BuildConstructorCall (deopt)"); |
| 1648 Value* ctor_arg = Bind( | 1633 Value* ctor_arg = Bind( |
| 1649 new ConstantInstr(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); | 1634 new ConstantInstr(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); |
| 1650 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); | 1635 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); |
| 1651 | 1636 |
| 1652 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1637 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1653 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1638 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1654 arguments->Add(push_alloc_value); | 1639 arguments->Add(push_alloc_value); |
| 1655 arguments->Add(push_ctor_arg); | 1640 arguments->Add(push_ctor_arg); |
| 1656 | 1641 |
| 1657 BuildPushArguments(*node->arguments(), arguments); | 1642 BuildPushArguments(*node->arguments(), arguments); |
| 1658 Do(new StaticCallInstr(node->token_pos(), | 1643 Do(new StaticCallInstr(node->token_pos(), |
| 1659 node->constructor(), | 1644 node->constructor(), |
| 1660 node->arguments()->names(), | 1645 node->arguments()->names(), |
| 1661 arguments)); | 1646 arguments)); |
| 1662 } | 1647 } |
| 1663 | 1648 |
| 1664 | 1649 |
| 1665 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { | 1650 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| 1666 InlineBailout("EffectGraphVisitor::VisitConstructorCallNode"); | |
| 1667 if (node->constructor().IsFactory()) { | 1651 if (node->constructor().IsFactory()) { |
| 1652 InlineBailout("EffectGraphVisitor::VisitConstructorCallNode (deopt)"); |
| 1668 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1653 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1669 new ZoneGrowableArray<PushArgumentInstr*>(); | 1654 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 1670 PushArgumentInstr* push_type_arguments = PushArgument( | 1655 PushArgumentInstr* push_type_arguments = PushArgument( |
| 1671 BuildInstantiatedTypeArguments(node->token_pos(), | 1656 BuildInstantiatedTypeArguments(node->token_pos(), |
| 1672 node->type_arguments())); | 1657 node->type_arguments())); |
| 1673 arguments->Add(push_type_arguments); | 1658 arguments->Add(push_type_arguments); |
| 1674 ASSERT(arguments->length() == 1); | 1659 ASSERT(arguments->length() == 1); |
| 1675 BuildPushArguments(*node->arguments(), arguments); | 1660 BuildPushArguments(*node->arguments(), arguments); |
| 1676 StaticCallInstr* call = | 1661 StaticCallInstr* call = |
| 1677 new StaticCallInstr(node->token_pos(), | 1662 new StaticCallInstr(node->token_pos(), |
| 1678 node->constructor(), | 1663 node->constructor(), |
| 1679 node->arguments()->names(), | 1664 node->arguments()->names(), |
| 1680 arguments); | 1665 arguments); |
| 1681 ReturnDefinition(call); | 1666 ReturnDefinition(call); |
| 1682 return; | 1667 return; |
| 1683 } | 1668 } |
| 1684 // t_n contains the allocated and initialized object. | 1669 // t_n contains the allocated and initialized object. |
| 1685 // t_n <- AllocateObject(class) | 1670 // t_n <- AllocateObject(class) |
| 1686 // t_n+1 <- ctor-arg | 1671 // t_n+1 <- ctor-arg |
| 1687 // t_n+2... <- constructor arguments start here | 1672 // t_n+2... <- constructor arguments start here |
| 1688 // StaticCall(constructor, t_n+1, t_n+2, ...) | 1673 // StaticCall(constructor, t_n+1, t_n+2, ...) |
| 1689 // No need to preserve allocated value (simpler than in ValueGraphVisitor). | 1674 // No need to preserve allocated value (simpler than in ValueGraphVisitor). |
| 1690 Value* allocated_value = BuildObjectAllocation(node); | 1675 Value* allocated_value = BuildObjectAllocation(node); |
| 1691 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); | 1676 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); |
| 1692 BuildConstructorCall(node, push_allocated_value); | 1677 BuildConstructorCall(node, push_allocated_value); |
| 1693 } | 1678 } |
| 1694 | 1679 |
| 1695 | 1680 |
| 1696 Value* EffectGraphVisitor::BuildInstantiator() { | 1681 Value* EffectGraphVisitor::BuildInstantiator() { |
| 1697 InlineBailout("EffectGraphVisitor::BuildInstantiator"); | |
| 1698 const Class& instantiator_class = Class::Handle( | 1682 const Class& instantiator_class = Class::Handle( |
| 1699 owner()->parsed_function().function().Owner()); | 1683 owner()->parsed_function().function().Owner()); |
| 1700 if (instantiator_class.NumTypeParameters() == 0) { | 1684 if (instantiator_class.NumTypeParameters() == 0) { |
| 1701 return NULL; | 1685 return NULL; |
| 1702 } | 1686 } |
| 1703 Function& outer_function = | 1687 Function& outer_function = |
| 1704 Function::Handle(owner()->parsed_function().function().raw()); | 1688 Function::Handle(owner()->parsed_function().function().raw()); |
| 1705 while (outer_function.IsLocalFunction()) { | 1689 while (outer_function.IsLocalFunction()) { |
| 1706 outer_function = outer_function.parent_function(); | 1690 outer_function = outer_function.parent_function(); |
| 1707 } | 1691 } |
| 1708 if (outer_function.IsFactory()) { | 1692 if (outer_function.IsFactory()) { |
| 1709 return NULL; | 1693 return NULL; |
| 1710 } | 1694 } |
| 1711 | 1695 |
| 1712 ASSERT(owner()->parsed_function().instantiator() != NULL); | 1696 ASSERT(owner()->parsed_function().instantiator() != NULL); |
| 1713 ValueGraphVisitor for_instantiator(owner(), temp_index()); | 1697 ValueGraphVisitor for_instantiator(owner(), temp_index()); |
| 1714 owner()->parsed_function().instantiator()->Visit(&for_instantiator); | 1698 owner()->parsed_function().instantiator()->Visit(&for_instantiator); |
| 1715 Append(for_instantiator); | 1699 Append(for_instantiator); |
| 1716 return for_instantiator.value(); | 1700 return for_instantiator.value(); |
| 1717 } | 1701 } |
| 1718 | 1702 |
| 1719 | 1703 |
| 1720 // 'expression_temp_var' may not be used inside this method if 'instantiator' | 1704 // 'expression_temp_var' may not be used inside this method if 'instantiator' |
| 1721 // is not NULL. | 1705 // is not NULL. |
| 1722 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( | 1706 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( |
| 1723 intptr_t token_pos, Value* instantiator) { | 1707 intptr_t token_pos, Value* instantiator) { |
| 1724 InlineBailout("EffectGraphVisitor::BuildInstantiatorTypeArguments"); | |
| 1725 const Class& instantiator_class = Class::Handle( | 1708 const Class& instantiator_class = Class::Handle( |
| 1726 owner()->parsed_function().function().Owner()); | 1709 owner()->parsed_function().function().Owner()); |
| 1727 if (instantiator_class.NumTypeParameters() == 0) { | 1710 if (instantiator_class.NumTypeParameters() == 0) { |
| 1728 // The type arguments are compile time constants. | 1711 // The type arguments are compile time constants. |
| 1729 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); | 1712 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); |
| 1730 // Type is temporary. Only its type arguments are preserved. | 1713 // Type is temporary. Only its type arguments are preserved. |
| 1731 Type& type = Type::Handle( | 1714 Type& type = Type::Handle( |
| 1732 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); | 1715 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); |
| 1733 type ^= ClassFinalizer::FinalizeType( | 1716 type ^= ClassFinalizer::FinalizeType( |
| 1734 instantiator_class, type, ClassFinalizer::kFinalize); | 1717 instantiator_class, type, ClassFinalizer::kFinalize); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1755 instantiator = BuildInstantiator(); | 1738 instantiator = BuildInstantiator(); |
| 1756 } | 1739 } |
| 1757 // The instantiator is the receiver of the caller, which is not a factory. | 1740 // The instantiator is the receiver of the caller, which is not a factory. |
| 1758 // The receiver cannot be null; extract its AbstractTypeArguments object. | 1741 // The receiver cannot be null; extract its AbstractTypeArguments object. |
| 1759 // Note that in the factory case, the instantiator is the first parameter | 1742 // Note that in the factory case, the instantiator is the first parameter |
| 1760 // of the factory, i.e. already an AbstractTypeArguments object. | 1743 // of the factory, i.e. already an AbstractTypeArguments object. |
| 1761 intptr_t type_arguments_instance_field_offset = | 1744 intptr_t type_arguments_instance_field_offset = |
| 1762 instantiator_class.type_arguments_instance_field_offset(); | 1745 instantiator_class.type_arguments_instance_field_offset(); |
| 1763 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments); | 1746 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments); |
| 1764 | 1747 |
| 1748 InlineBailout("EffectGraphVisitor::BuildInstantiatorTypeArguments (deopt)"); |
| 1765 return Bind(new LoadVMFieldInstr( | 1749 return Bind(new LoadVMFieldInstr( |
| 1766 instantiator, | 1750 instantiator, |
| 1767 type_arguments_instance_field_offset, | 1751 type_arguments_instance_field_offset, |
| 1768 Type::ZoneHandle())); // Not an instance, no type. | 1752 Type::ZoneHandle())); // Not an instance, no type. |
| 1769 } | 1753 } |
| 1770 | 1754 |
| 1771 | 1755 |
| 1772 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( | 1756 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( |
| 1773 intptr_t token_pos, | 1757 intptr_t token_pos, |
| 1774 const AbstractTypeArguments& type_arguments) { | 1758 const AbstractTypeArguments& type_arguments) { |
| 1775 InlineBailout("EffectGraphVisitor::BuildInstantiatedTypeArguments"); | |
| 1776 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { | 1759 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { |
| 1777 return Bind(new ConstantInstr(type_arguments)); | 1760 return Bind(new ConstantInstr(type_arguments)); |
| 1778 } | 1761 } |
| 1762 InlineBailout("EffectGraphVisitor::BuildInstantiatedTypeArguments (deopt)"); |
| 1779 // The type arguments are uninstantiated. | 1763 // The type arguments are uninstantiated. |
| 1780 Value* instantiator_value = | 1764 Value* instantiator_value = |
| 1781 BuildInstantiatorTypeArguments(token_pos, NULL); | 1765 BuildInstantiatorTypeArguments(token_pos, NULL); |
| 1782 return Bind(new InstantiateTypeArgumentsInstr(token_pos, | 1766 return Bind(new InstantiateTypeArgumentsInstr(token_pos, |
| 1783 type_arguments, | 1767 type_arguments, |
| 1784 instantiator_value)); | 1768 instantiator_value)); |
| 1785 } | 1769 } |
| 1786 | 1770 |
| 1787 | 1771 |
| 1788 void EffectGraphVisitor::BuildConstructorTypeArguments( | 1772 void EffectGraphVisitor::BuildConstructorTypeArguments( |
| 1789 ConstructorCallNode* node, | 1773 ConstructorCallNode* node, |
| 1790 Value** type_arguments, | 1774 Value** type_arguments, |
| 1791 Value** instantiator, | 1775 Value** instantiator, |
| 1792 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) { | 1776 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) { |
| 1793 InlineBailout("EffectGraphVisitor::BuildConstructorTypeArguments"); | |
| 1794 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); | 1777 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); |
| 1795 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); | 1778 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); |
| 1796 if (node->type_arguments().IsNull() || | 1779 if (node->type_arguments().IsNull() || |
| 1797 node->type_arguments().IsInstantiated()) { | 1780 node->type_arguments().IsInstantiated()) { |
| 1798 Value* type_arguments_val = Bind(new ConstantInstr(node->type_arguments())); | 1781 Value* type_arguments_val = Bind(new ConstantInstr(node->type_arguments())); |
| 1799 if (call_arguments != NULL) { | 1782 if (call_arguments != NULL) { |
| 1800 ASSERT(type_arguments == NULL); | 1783 ASSERT(type_arguments == NULL); |
| 1801 call_arguments->Add(PushArgument(type_arguments_val)); | 1784 call_arguments->Add(PushArgument(type_arguments_val)); |
| 1802 } else { | 1785 } else { |
| 1803 ASSERT(type_arguments != NULL); | 1786 ASSERT(type_arguments != NULL); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1862 ASSERT(instantiator == NULL); | 1845 ASSERT(instantiator == NULL); |
| 1863 call_arguments->Add(PushArgument(instantiator_val)); | 1846 call_arguments->Add(PushArgument(instantiator_val)); |
| 1864 } else { | 1847 } else { |
| 1865 ASSERT(instantiator != NULL); | 1848 ASSERT(instantiator != NULL); |
| 1866 *instantiator = instantiator_val; | 1849 *instantiator = instantiator_val; |
| 1867 } | 1850 } |
| 1868 } | 1851 } |
| 1869 | 1852 |
| 1870 | 1853 |
| 1871 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { | 1854 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| 1872 InlineBailout("ValueGraphVisitor::VisitConstructorCallNode"); | |
| 1873 if (node->constructor().IsFactory()) { | 1855 if (node->constructor().IsFactory()) { |
| 1874 EffectGraphVisitor::VisitConstructorCallNode(node); | 1856 EffectGraphVisitor::VisitConstructorCallNode(node); |
| 1875 return; | 1857 return; |
| 1876 } | 1858 } |
| 1877 | 1859 |
| 1878 // t_n contains the allocated and initialized object. | 1860 // t_n contains the allocated and initialized object. |
| 1879 // t_n <- AllocateObject(class) | 1861 // t_n <- AllocateObject(class) |
| 1880 // t_n <- StoreLocal(temp, t_n); | 1862 // t_n <- StoreLocal(temp, t_n); |
| 1881 // t_n+1 <- ctor-arg | 1863 // t_n+1 <- ctor-arg |
| 1882 // t_n+2... <- constructor arguments start here | 1864 // t_n+2... <- constructor arguments start here |
| 1883 // StaticCall(constructor, t_n, t_n+1, ...) | 1865 // StaticCall(constructor, t_n, t_n+1, ...) |
| 1884 // tn <- LoadLocal(temp) | 1866 // tn <- LoadLocal(temp) |
| 1885 | 1867 |
| 1886 Value* allocate = BuildObjectAllocation(node); | 1868 Value* allocate = BuildObjectAllocation(node); |
| 1887 Value* allocated_value = Bind(BuildStoreTemp( | 1869 Value* allocated_value = Bind(BuildStoreTemp( |
| 1888 node->allocated_object_var(), | 1870 node->allocated_object_var(), |
| 1889 allocate)); | 1871 allocate)); |
| 1890 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); | 1872 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); |
| 1891 BuildConstructorCall(node, push_allocated_value); | 1873 BuildConstructorCall(node, push_allocated_value); |
| 1892 Definition* load_allocated = BuildLoadLocal( | 1874 Definition* load_allocated = BuildLoadLocal( |
| 1893 node->allocated_object_var()); | 1875 node->allocated_object_var()); |
| 1894 allocated_value = Bind(load_allocated); | 1876 allocated_value = Bind(load_allocated); |
| 1895 ReturnValue(allocated_value); | 1877 ReturnValue(allocated_value); |
| 1896 } | 1878 } |
| 1897 | 1879 |
| 1898 | 1880 |
| 1899 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { | 1881 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { |
| 1900 InlineBailout("EffectGraphVisitor::VisitConstructorCallNode"); | 1882 InlineBailout("EffectGraphVisitor::VisitInstanceGetterNode (deopt)"); |
| 1901 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1883 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1902 node->receiver()->Visit(&for_receiver); | 1884 node->receiver()->Visit(&for_receiver); |
| 1903 Append(for_receiver); | 1885 Append(for_receiver); |
| 1904 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 1886 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 1905 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1887 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1906 new ZoneGrowableArray<PushArgumentInstr*>(1); | 1888 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 1907 arguments->Add(push_receiver); | 1889 arguments->Add(push_receiver); |
| 1908 const String& name = | 1890 const String& name = |
| 1909 String::ZoneHandle(Field::GetterSymbol(node->field_name())); | 1891 String::ZoneHandle(Field::GetterSymbol(node->field_name())); |
| 1910 InstanceCallInstr* call = new InstanceCallInstr( | 1892 InstanceCallInstr* call = new InstanceCallInstr( |
| 1911 node->token_pos(), name, Token::kGET, | 1893 node->token_pos(), name, Token::kGET, |
| 1912 arguments, Array::ZoneHandle(), 1); | 1894 arguments, Array::ZoneHandle(), 1); |
| 1913 ReturnDefinition(call); | 1895 ReturnDefinition(call); |
| 1914 } | 1896 } |
| 1915 | 1897 |
| 1916 | 1898 |
| 1917 void EffectGraphVisitor::BuildInstanceSetterArguments( | 1899 void EffectGraphVisitor::BuildInstanceSetterArguments( |
| 1918 InstanceSetterNode* node, | 1900 InstanceSetterNode* node, |
| 1919 ZoneGrowableArray<PushArgumentInstr*>* arguments, | 1901 ZoneGrowableArray<PushArgumentInstr*>* arguments, |
| 1920 bool result_is_needed) { | 1902 bool result_is_needed) { |
| 1921 InlineBailout("EffectGraphVisitor::BuildInstanceSetterArguments"); | |
| 1922 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1903 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1923 node->receiver()->Visit(&for_receiver); | 1904 node->receiver()->Visit(&for_receiver); |
| 1924 Append(for_receiver); | 1905 Append(for_receiver); |
| 1925 arguments->Add(PushArgument(for_receiver.value())); | 1906 arguments->Add(PushArgument(for_receiver.value())); |
| 1926 | 1907 |
| 1927 ValueGraphVisitor for_value(owner(), temp_index()); | 1908 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1928 node->value()->Visit(&for_value); | 1909 node->value()->Visit(&for_value); |
| 1929 Append(for_value); | 1910 Append(for_value); |
| 1930 | 1911 |
| 1931 Value* value = NULL; | 1912 Value* value = NULL; |
| 1932 if (result_is_needed) { | 1913 if (result_is_needed) { |
| 1933 value = Bind(BuildStoreExprTemp(for_value.value())); | 1914 value = Bind(BuildStoreExprTemp(for_value.value())); |
| 1934 } else { | 1915 } else { |
| 1935 value = for_value.value(); | 1916 value = for_value.value(); |
| 1936 } | 1917 } |
| 1937 arguments->Add(PushArgument(value)); | 1918 arguments->Add(PushArgument(value)); |
| 1938 } | 1919 } |
| 1939 | 1920 |
| 1940 | 1921 |
| 1941 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { | 1922 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| 1942 InlineBailout("EffectGraphVisitor::VisitInstanceSetterNode"); | 1923 InlineBailout("EffectGraphVisitor::VisitInstanceSetterNode (deopt)"); |
| 1943 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1924 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1944 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1925 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1945 BuildInstanceSetterArguments(node, arguments, kResultNotNeeded); | 1926 BuildInstanceSetterArguments(node, arguments, kResultNotNeeded); |
| 1946 const String& name = | 1927 const String& name = |
| 1947 String::ZoneHandle(Field::SetterSymbol(node->field_name())); | 1928 String::ZoneHandle(Field::SetterSymbol(node->field_name())); |
| 1948 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), | 1929 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), |
| 1949 name, | 1930 name, |
| 1950 Token::kSET, | 1931 Token::kSET, |
| 1951 arguments, | 1932 arguments, |
| 1952 Array::ZoneHandle(), | 1933 Array::ZoneHandle(), |
| 1953 1); // Checked arg count. | 1934 1); // Checked arg count. |
| 1954 ReturnDefinition(call); | 1935 ReturnDefinition(call); |
| 1955 } | 1936 } |
| 1956 | 1937 |
| 1957 | 1938 |
| 1958 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { | 1939 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| 1959 InlineBailout("ValueGraphVisitor::VisitInstanceSetterNode"); | 1940 InlineBailout("ValueGraphVisitor::VisitInstanceSetterNode (deopt)"); |
| 1960 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1941 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1961 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1942 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1962 BuildInstanceSetterArguments(node, arguments, kResultNeeded); | 1943 BuildInstanceSetterArguments(node, arguments, kResultNeeded); |
| 1963 const String& name = | 1944 const String& name = |
| 1964 String::ZoneHandle(Field::SetterSymbol(node->field_name())); | 1945 String::ZoneHandle(Field::SetterSymbol(node->field_name())); |
| 1965 Do(new InstanceCallInstr(node->token_pos(), | 1946 Do(new InstanceCallInstr(node->token_pos(), |
| 1966 name, | 1947 name, |
| 1967 Token::kSET, | 1948 Token::kSET, |
| 1968 arguments, | 1949 arguments, |
| 1969 Array::ZoneHandle(), | 1950 Array::ZoneHandle(), |
| 1970 1)); // Checked argument count. | 1951 1)); // Checked argument count. |
| 1971 ReturnDefinition(BuildLoadExprTemp()); | 1952 ReturnDefinition(BuildLoadExprTemp()); |
| 1972 } | 1953 } |
| 1973 | 1954 |
| 1974 | 1955 |
| 1975 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { | 1956 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { |
| 1976 InlineBailout("EffectGraphVisitor::VisitStaticGetterNode"); | 1957 InlineBailout("EffectGraphVisitor::VisitStaticGetterNode (deopt)"); |
| 1977 const String& getter_name = | 1958 const String& getter_name = |
| 1978 String::Handle(Field::GetterName(node->field_name())); | 1959 String::Handle(Field::GetterName(node->field_name())); |
| 1979 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1960 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1980 new ZoneGrowableArray<PushArgumentInstr*>(); | 1961 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 1981 Function& getter_function = Function::ZoneHandle(); | 1962 Function& getter_function = Function::ZoneHandle(); |
| 1982 if (node->is_super_getter()) { | 1963 if (node->is_super_getter()) { |
| 1983 // Statically resolved instance getter, i.e. "super getter". | 1964 // Statically resolved instance getter, i.e. "super getter". |
| 1984 getter_function = | 1965 getter_function = |
| 1985 Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); | 1966 Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); |
| 1986 ASSERT(!getter_function.IsNull()); | 1967 ASSERT(!getter_function.IsNull()); |
| 1987 ASSERT(node->receiver() != NULL); | 1968 ASSERT(node->receiver() != NULL); |
| 1988 ValueGraphVisitor receiver_value(owner(), temp_index()); | 1969 ValueGraphVisitor receiver_value(owner(), temp_index()); |
| 1989 node->receiver()->Visit(&receiver_value); | 1970 node->receiver()->Visit(&receiver_value); |
| 1990 Append(receiver_value); | 1971 Append(receiver_value); |
| 1991 arguments->Add(PushArgument(receiver_value.value())); | 1972 arguments->Add(PushArgument(receiver_value.value())); |
| 1992 } else { | 1973 } else { |
| 1993 getter_function = node->cls().LookupStaticFunction(getter_name); | 1974 getter_function = node->cls().LookupStaticFunction(getter_name); |
| 1994 ASSERT(!getter_function.IsNull()); | 1975 ASSERT(!getter_function.IsNull()); |
| 1995 } | 1976 } |
| 1996 StaticCallInstr* call = new StaticCallInstr(node->token_pos(), | 1977 StaticCallInstr* call = new StaticCallInstr(node->token_pos(), |
| 1997 getter_function, | 1978 getter_function, |
| 1998 Array::ZoneHandle(), // No names. | 1979 Array::ZoneHandle(), // No names. |
| 1999 arguments); | 1980 arguments); |
| 2000 ReturnDefinition(call); | 1981 ReturnDefinition(call); |
| 2001 } | 1982 } |
| 2002 | 1983 |
| 2003 | 1984 |
| 2004 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, | 1985 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, |
| 2005 bool result_is_needed) { | 1986 bool result_is_needed) { |
| 2006 InlineBailout("EffectGraphVisitor::BuildStaticSetter"); | 1987 InlineBailout("EffectGraphVisitor::VisitStaticSetter (deopt)"); |
| 2007 const String& setter_name = | 1988 const String& setter_name = |
| 2008 String::Handle(Field::SetterName(node->field_name())); | 1989 String::Handle(Field::SetterName(node->field_name())); |
| 2009 // A super setter is an instance setter whose setter function is | 1990 // A super setter is an instance setter whose setter function is |
| 2010 // resolved at compile time (in the caller instance getter's super class). | 1991 // resolved at compile time (in the caller instance getter's super class). |
| 2011 // Unlike a static getter, a super getter has a receiver parameter. | 1992 // Unlike a static getter, a super getter has a receiver parameter. |
| 2012 const bool is_super_setter = (node->receiver() != NULL); | 1993 const bool is_super_setter = (node->receiver() != NULL); |
| 2013 const Function& setter_function = | 1994 const Function& setter_function = |
| 2014 Function::ZoneHandle(is_super_setter | 1995 Function::ZoneHandle(is_super_setter |
| 2015 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name) | 1996 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name) |
| 2016 : node->cls().LookupStaticFunction(setter_name)); | 1997 : node->cls().LookupStaticFunction(setter_name)); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2043 if (result_is_needed) { | 2024 if (result_is_needed) { |
| 2044 Do(call); | 2025 Do(call); |
| 2045 ReturnDefinition(BuildLoadExprTemp()); | 2026 ReturnDefinition(BuildLoadExprTemp()); |
| 2046 } else { | 2027 } else { |
| 2047 ReturnDefinition(call); | 2028 ReturnDefinition(call); |
| 2048 } | 2029 } |
| 2049 } | 2030 } |
| 2050 | 2031 |
| 2051 | 2032 |
| 2052 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { | 2033 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { |
| 2053 InlineBailout("EffectGraphVisitor::VisitStaticSetterNode"); | |
| 2054 BuildStaticSetter(node, false); // Result not needed. | 2034 BuildStaticSetter(node, false); // Result not needed. |
| 2055 } | 2035 } |
| 2056 | 2036 |
| 2057 | 2037 |
| 2058 void ValueGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { | 2038 void ValueGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { |
| 2059 InlineBailout("ValueGraphVisitor::VisitStaticSetterNode"); | |
| 2060 BuildStaticSetter(node, true); // Result needed. | 2039 BuildStaticSetter(node, true); // Result needed. |
| 2061 } | 2040 } |
| 2062 | 2041 |
| 2063 | 2042 |
| 2064 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { | 2043 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { |
| 2065 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode"); | 2044 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode"); |
| 2066 NativeCallInstr* native_call = new NativeCallInstr(node); | 2045 NativeCallInstr* native_call = new NativeCallInstr(node); |
| 2067 ReturnDefinition(native_call); | 2046 ReturnDefinition(native_call); |
| 2068 } | 2047 } |
| 2069 | 2048 |
| 2070 | 2049 |
| 2071 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { | 2050 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { |
| 2072 InlineBailout("EffectGraphVisitor::VisitPrimaryNode"); | |
| 2073 // PrimaryNodes are temporary during parsing. | 2051 // PrimaryNodes are temporary during parsing. |
| 2074 UNREACHABLE(); | 2052 UNREACHABLE(); |
| 2075 } | 2053 } |
| 2076 | 2054 |
| 2077 | 2055 |
| 2078 // <Expression> ::= LoadLocal { local: LocalVariable } | 2056 // <Expression> ::= LoadLocal { local: LocalVariable } |
| 2079 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { | 2057 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| 2080 InlineBailout("EffectGraphVisitor::VisitLoadLocalNode"); | |
| 2081 if (node->HasPseudo()) { | 2058 if (node->HasPseudo()) { |
| 2082 EffectGraphVisitor for_pseudo(owner(), temp_index()); | 2059 EffectGraphVisitor for_pseudo(owner(), temp_index()); |
| 2083 node->pseudo()->Visit(&for_pseudo); | 2060 node->pseudo()->Visit(&for_pseudo); |
| 2084 Append(for_pseudo); | 2061 Append(for_pseudo); |
| 2085 } | 2062 } |
| 2086 } | 2063 } |
| 2087 | 2064 |
| 2088 | 2065 |
| 2089 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { | 2066 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| 2090 InlineBailout("ValueGraphVisitor::VisitLoadLocalNode"); | |
| 2091 EffectGraphVisitor::VisitLoadLocalNode(node); | 2067 EffectGraphVisitor::VisitLoadLocalNode(node); |
| 2092 Definition* load = BuildLoadLocal(node->local()); | 2068 Definition* load = BuildLoadLocal(node->local()); |
| 2093 ReturnDefinition(load); | 2069 ReturnDefinition(load); |
| 2094 } | 2070 } |
| 2095 | 2071 |
| 2096 | 2072 |
| 2097 // <Expression> ::= StoreLocal { local: LocalVariable | 2073 // <Expression> ::= StoreLocal { local: LocalVariable |
| 2098 // value: <Expression> } | 2074 // value: <Expression> } |
| 2099 void EffectGraphVisitor::HandleStoreLocal(StoreLocalNode* node, | 2075 void EffectGraphVisitor::HandleStoreLocal(StoreLocalNode* node, |
| 2100 bool result_is_needed) { | 2076 bool result_is_needed) { |
| 2101 InlineBailout("EffectGraphVisitor::VisitStoreLocalNode"); | |
| 2102 ValueGraphVisitor for_value(owner(), temp_index()); | 2077 ValueGraphVisitor for_value(owner(), temp_index()); |
| 2103 node->value()->Visit(&for_value); | 2078 node->value()->Visit(&for_value); |
| 2104 Append(for_value); | 2079 Append(for_value); |
| 2105 Value* store_value = for_value.value(); | 2080 Value* store_value = for_value.value(); |
| 2106 if (FLAG_enable_type_checks) { | 2081 if (FLAG_enable_type_checks) { |
| 2107 store_value = BuildAssignableValue(node->value()->token_pos(), | 2082 store_value = BuildAssignableValue(node->value()->token_pos(), |
| 2108 store_value, | 2083 store_value, |
| 2109 node->local().type(), | 2084 node->local().type(), |
| 2110 node->local().name()); | 2085 node->local().name()); |
| 2111 } | 2086 } |
| 2112 Definition* store = BuildStoreLocal(node->local(), | 2087 Definition* store = BuildStoreLocal(node->local(), |
| 2113 store_value, | 2088 store_value, |
| 2114 result_is_needed); | 2089 result_is_needed); |
| 2115 ReturnDefinition(store); | 2090 ReturnDefinition(store); |
| 2116 } | 2091 } |
| 2117 | 2092 |
| 2118 | 2093 |
| 2119 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { | 2094 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| 2120 HandleStoreLocal(node, kResultNotNeeded); | 2095 HandleStoreLocal(node, kResultNotNeeded); |
| 2121 } | 2096 } |
| 2122 | 2097 |
| 2123 | 2098 |
| 2124 void ValueGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { | 2099 void ValueGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| 2125 HandleStoreLocal(node, kResultNeeded); | 2100 HandleStoreLocal(node, kResultNeeded); |
| 2126 } | 2101 } |
| 2127 | 2102 |
| 2128 | 2103 |
| 2129 void EffectGraphVisitor::VisitLoadInstanceFieldNode( | 2104 void EffectGraphVisitor::VisitLoadInstanceFieldNode( |
| 2130 LoadInstanceFieldNode* node) { | 2105 LoadInstanceFieldNode* node) { |
| 2131 InlineBailout("EffectGraphVisitor::VisitLoadInstanceFieldNode"); | |
| 2132 ValueGraphVisitor for_instance(owner(), temp_index()); | 2106 ValueGraphVisitor for_instance(owner(), temp_index()); |
| 2133 node->instance()->Visit(&for_instance); | 2107 node->instance()->Visit(&for_instance); |
| 2134 Append(for_instance); | 2108 Append(for_instance); |
| 2135 LoadInstanceFieldInstr* load = new LoadInstanceFieldInstr( | 2109 LoadInstanceFieldInstr* load = new LoadInstanceFieldInstr( |
| 2136 node->field(), for_instance.value()); | 2110 node->field(), for_instance.value()); |
| 2137 ReturnDefinition(load); | 2111 ReturnDefinition(load); |
| 2138 } | 2112 } |
| 2139 | 2113 |
| 2140 | 2114 |
| 2141 void EffectGraphVisitor::VisitStoreInstanceFieldNode( | 2115 void EffectGraphVisitor::VisitStoreInstanceFieldNode( |
| 2142 StoreInstanceFieldNode* node) { | 2116 StoreInstanceFieldNode* node) { |
| 2143 InlineBailout("EffectGraphVisitor::VisitStoreInstanceFieldNode"); | |
| 2144 ValueGraphVisitor for_instance(owner(), temp_index()); | 2117 ValueGraphVisitor for_instance(owner(), temp_index()); |
| 2145 node->instance()->Visit(&for_instance); | 2118 node->instance()->Visit(&for_instance); |
| 2146 Append(for_instance); | 2119 Append(for_instance); |
| 2147 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); | 2120 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); |
| 2148 node->value()->Visit(&for_value); | 2121 node->value()->Visit(&for_value); |
| 2149 Append(for_value); | 2122 Append(for_value); |
| 2150 Value* store_value = for_value.value(); | 2123 Value* store_value = for_value.value(); |
| 2151 if (FLAG_enable_type_checks) { | 2124 if (FLAG_enable_type_checks) { |
| 2152 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 2125 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| 2153 const String& dst_name = String::ZoneHandle(node->field().name()); | 2126 const String& dst_name = String::ZoneHandle(node->field().name()); |
| 2154 store_value = BuildAssignableValue(node->value()->token_pos(), | 2127 store_value = BuildAssignableValue(node->value()->token_pos(), |
| 2155 store_value, | 2128 store_value, |
| 2156 type, | 2129 type, |
| 2157 dst_name); | 2130 dst_name); |
| 2158 } | 2131 } |
| 2159 StoreInstanceFieldInstr* store = new StoreInstanceFieldInstr( | 2132 StoreInstanceFieldInstr* store = new StoreInstanceFieldInstr( |
| 2160 node->field(), for_instance.value(), store_value); | 2133 node->field(), for_instance.value(), store_value); |
| 2161 ReturnDefinition(store); | 2134 ReturnDefinition(store); |
| 2162 } | 2135 } |
| 2163 | 2136 |
| 2164 | 2137 |
| 2165 // StoreInstanceFieldNode does not return result. | 2138 // StoreInstanceFieldNode does not return result. |
| 2166 void ValueGraphVisitor::VisitStoreInstanceFieldNode( | 2139 void ValueGraphVisitor::VisitStoreInstanceFieldNode( |
| 2167 StoreInstanceFieldNode* node) { | 2140 StoreInstanceFieldNode* node) { |
| 2168 InlineBailout("ValueGraphVisitor::VisitStoreInstanceFieldNode"); | |
| 2169 UNIMPLEMENTED(); | 2141 UNIMPLEMENTED(); |
| 2170 } | 2142 } |
| 2171 | 2143 |
| 2172 | 2144 |
| 2173 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { | 2145 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { |
| 2174 InlineBailout("EffectGraphVisitor::VisitLoadStaticFieldNode"); | |
| 2175 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(node->field()); | 2146 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(node->field()); |
| 2176 ReturnDefinition(load); | 2147 ReturnDefinition(load); |
| 2177 } | 2148 } |
| 2178 | 2149 |
| 2179 | 2150 |
| 2180 Definition* EffectGraphVisitor::BuildStoreStaticField( | 2151 Definition* EffectGraphVisitor::BuildStoreStaticField( |
| 2181 StoreStaticFieldNode* node, bool result_is_needed) { | 2152 StoreStaticFieldNode* node, bool result_is_needed) { |
| 2182 InlineBailout("EffectGraphVisitor::VisitStoreStaticFieldNode"); | |
| 2183 ValueGraphVisitor for_value(owner(), temp_index()); | 2153 ValueGraphVisitor for_value(owner(), temp_index()); |
| 2184 node->value()->Visit(&for_value); | 2154 node->value()->Visit(&for_value); |
| 2185 Append(for_value); | 2155 Append(for_value); |
| 2186 Value* store_value = NULL; | 2156 Value* store_value = NULL; |
| 2187 if (result_is_needed) { | 2157 if (result_is_needed) { |
| 2188 store_value = Bind(BuildStoreExprTemp(for_value.value())); | 2158 store_value = Bind(BuildStoreExprTemp(for_value.value())); |
| 2189 } else { | 2159 } else { |
| 2190 store_value = for_value.value(); | 2160 store_value = for_value.value(); |
| 2191 } | 2161 } |
| 2192 if (FLAG_enable_type_checks) { | 2162 if (FLAG_enable_type_checks) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2213 ReturnDefinition(BuildStoreStaticField(node, kResultNotNeeded)); | 2183 ReturnDefinition(BuildStoreStaticField(node, kResultNotNeeded)); |
| 2214 } | 2184 } |
| 2215 | 2185 |
| 2216 | 2186 |
| 2217 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { | 2187 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
| 2218 ReturnDefinition(BuildStoreStaticField(node, kResultNeeded)); | 2188 ReturnDefinition(BuildStoreStaticField(node, kResultNeeded)); |
| 2219 } | 2189 } |
| 2220 | 2190 |
| 2221 | 2191 |
| 2222 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { | 2192 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { |
| 2223 InlineBailout("EffectGraphVisitor::VisitLoadIndexedNode"); | 2193 InlineBailout("EffectGraphVisitor::VisitLoadIndexedNode (deopt)"); |
| 2224 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2194 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2225 new ZoneGrowableArray<PushArgumentInstr*>(2); | 2195 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 2226 ValueGraphVisitor for_array(owner(), temp_index()); | 2196 ValueGraphVisitor for_array(owner(), temp_index()); |
| 2227 node->array()->Visit(&for_array); | 2197 node->array()->Visit(&for_array); |
| 2228 Append(for_array); | 2198 Append(for_array); |
| 2229 arguments->Add(PushArgument(for_array.value())); | 2199 arguments->Add(PushArgument(for_array.value())); |
| 2230 | 2200 |
| 2231 ValueGraphVisitor for_index(owner(), temp_index()); | 2201 ValueGraphVisitor for_index(owner(), temp_index()); |
| 2232 node->index_expr()->Visit(&for_index); | 2202 node->index_expr()->Visit(&for_index); |
| 2233 Append(for_index); | 2203 Append(for_index); |
| 2234 arguments->Add(PushArgument(for_index.value())); | 2204 arguments->Add(PushArgument(for_index.value())); |
| 2235 | 2205 |
| 2236 const intptr_t checked_argument_count = 1; | 2206 const intptr_t checked_argument_count = 1; |
| 2237 const String& name = | 2207 const String& name = |
| 2238 String::ZoneHandle(Symbols::New(Token::Str(Token::kINDEX))); | 2208 String::ZoneHandle(Symbols::New(Token::Str(Token::kINDEX))); |
| 2239 InstanceCallInstr* load = new InstanceCallInstr(node->token_pos(), | 2209 InstanceCallInstr* load = new InstanceCallInstr(node->token_pos(), |
| 2240 name, | 2210 name, |
| 2241 Token::kINDEX, | 2211 Token::kINDEX, |
| 2242 arguments, | 2212 arguments, |
| 2243 Array::ZoneHandle(), | 2213 Array::ZoneHandle(), |
| 2244 checked_argument_count); | 2214 checked_argument_count); |
| 2245 ReturnDefinition(load); | 2215 ReturnDefinition(load); |
| 2246 } | 2216 } |
| 2247 | 2217 |
| 2248 | 2218 |
| 2249 Definition* EffectGraphVisitor::BuildStoreIndexedValues( | 2219 Definition* EffectGraphVisitor::BuildStoreIndexedValues( |
| 2250 StoreIndexedNode* node, | 2220 StoreIndexedNode* node, |
| 2251 bool result_is_needed) { | 2221 bool result_is_needed) { |
| 2252 InlineBailout("EffectGraphVisitor::BuildStoreIndexedValues"); | 2222 InlineBailout("EffectGraphVisitor::BuildStoreIndexedValues (deopt)"); |
| 2253 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2223 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2254 new ZoneGrowableArray<PushArgumentInstr*>(3); | 2224 new ZoneGrowableArray<PushArgumentInstr*>(3); |
| 2255 ValueGraphVisitor for_array(owner(), temp_index()); | 2225 ValueGraphVisitor for_array(owner(), temp_index()); |
| 2256 node->array()->Visit(&for_array); | 2226 node->array()->Visit(&for_array); |
| 2257 Append(for_array); | 2227 Append(for_array); |
| 2258 arguments->Add(PushArgument(for_array.value())); | 2228 arguments->Add(PushArgument(for_array.value())); |
| 2259 | 2229 |
| 2260 ValueGraphVisitor for_index(owner(), temp_index()); | 2230 ValueGraphVisitor for_index(owner(), temp_index()); |
| 2261 node->index_expr()->Visit(&for_index); | 2231 node->index_expr()->Visit(&for_index); |
| 2262 Append(for_index); | 2232 Append(for_index); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2285 if (result_is_needed) { | 2255 if (result_is_needed) { |
| 2286 Do(store); | 2256 Do(store); |
| 2287 return BuildLoadExprTemp(); | 2257 return BuildLoadExprTemp(); |
| 2288 } else { | 2258 } else { |
| 2289 return store; | 2259 return store; |
| 2290 } | 2260 } |
| 2291 } | 2261 } |
| 2292 | 2262 |
| 2293 | 2263 |
| 2294 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { | 2264 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { |
| 2295 InlineBailout("EffectGraphVisitor::VisitStoreIndexedNode"); | |
| 2296 ReturnDefinition(BuildStoreIndexedValues(node, kResultNotNeeded)); | 2265 ReturnDefinition(BuildStoreIndexedValues(node, kResultNotNeeded)); |
| 2297 } | 2266 } |
| 2298 | 2267 |
| 2299 | 2268 |
| 2300 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { | 2269 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { |
| 2301 InlineBailout("ValueGraphVisitor::VisitStoreIndexedNode"); | |
| 2302 ReturnDefinition(BuildStoreIndexedValues(node, kResultNeeded)); | 2270 ReturnDefinition(BuildStoreIndexedValues(node, kResultNeeded)); |
| 2303 } | 2271 } |
| 2304 | 2272 |
| 2305 | 2273 |
| 2306 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { | 2274 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { |
| 2307 return (node == owner()->parsed_function().node_sequence()) && | 2275 return (node == owner()->parsed_function().node_sequence()) && |
| 2308 (owner()->parsed_function().saved_context_var() != NULL); | 2276 (owner()->parsed_function().saved_context_var() != NULL); |
| 2309 } | 2277 } |
| 2310 | 2278 |
| 2311 | 2279 |
| 2312 void EffectGraphVisitor::UnchainContext() { | 2280 void EffectGraphVisitor::UnchainContext() { |
| 2313 InlineBailout("EffectGraphVisitor::UnchainContext"); | 2281 InlineBailout("EffectGraphVisitor::UnchainContext (deopt)"); |
| 2314 Value* context = Bind(new CurrentContextInstr()); | 2282 Value* context = Bind(new CurrentContextInstr()); |
| 2315 Value* parent = Bind( | 2283 Value* parent = Bind( |
| 2316 new LoadVMFieldInstr(context, | 2284 new LoadVMFieldInstr(context, |
| 2317 Context::parent_offset(), | 2285 Context::parent_offset(), |
| 2318 Type::ZoneHandle())); // Not an instance, no type. | 2286 Type::ZoneHandle())); // Not an instance, no type. |
| 2319 Do(new StoreContextInstr(parent)); | 2287 Do(new StoreContextInstr(parent)); |
| 2320 } | 2288 } |
| 2321 | 2289 |
| 2322 | 2290 |
| 2323 // <Statement> ::= Sequence { scope: LocalScope | 2291 // <Statement> ::= Sequence { scope: LocalScope |
| 2324 // nodes: <Statement>* | 2292 // nodes: <Statement>* |
| 2325 // label: SourceLabel } | 2293 // label: SourceLabel } |
| 2326 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { | 2294 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { |
| 2327 LocalScope* scope = node->scope(); | 2295 LocalScope* scope = node->scope(); |
| 2328 const intptr_t num_context_variables = | 2296 const intptr_t num_context_variables = |
| 2329 (scope != NULL) ? scope->num_context_variables() : 0; | 2297 (scope != NULL) ? scope->num_context_variables() : 0; |
| 2330 int previous_context_level = owner()->context_level(); | 2298 int previous_context_level = owner()->context_level(); |
| 2331 if (num_context_variables > 0) { | 2299 if (num_context_variables > 0) { |
| 2332 InlineBailout("EffectGraphVisitor::VisitSequenceNode (captured vars)"); | 2300 InlineBailout("EffectGraphVisitor::VisitSequenceNode (deopt)"); |
| 2333 // The loop local scope declares variables that are captured. | 2301 // The loop local scope declares variables that are captured. |
| 2334 // Allocate and chain a new context. | 2302 // Allocate and chain a new context. |
| 2335 // Allocate context computation (uses current CTX) | 2303 // Allocate context computation (uses current CTX) |
| 2336 Value* allocated_context = | 2304 Value* allocated_context = |
| 2337 Bind(new AllocateContextInstr(node->token_pos(), | 2305 Bind(new AllocateContextInstr(node->token_pos(), |
| 2338 num_context_variables)); | 2306 num_context_variables)); |
| 2339 | 2307 |
| 2340 // If this node_sequence is the body of the function being compiled, and if | 2308 // If this node_sequence is the body of the function being compiled, and if |
| 2341 // this function is not a closure, do not link the current context as the | 2309 // this function is not a closure, do not link the current context as the |
| 2342 // parent of the newly allocated context, as it is not accessible. Instead, | 2310 // parent of the newly allocated context, as it is not accessible. Instead, |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2387 Value* null_constant = | 2355 Value* null_constant = |
| 2388 Bind(new ConstantInstr(Object::ZoneHandle())); | 2356 Bind(new ConstantInstr(Object::ZoneHandle())); |
| 2389 Do(BuildStoreLocal(*temp_local, null_constant, kResultNotNeeded)); | 2357 Do(BuildStoreLocal(*temp_local, null_constant, kResultNotNeeded)); |
| 2390 } | 2358 } |
| 2391 } | 2359 } |
| 2392 } | 2360 } |
| 2393 } | 2361 } |
| 2394 | 2362 |
| 2395 if (FLAG_enable_type_checks && | 2363 if (FLAG_enable_type_checks && |
| 2396 (node == owner()->parsed_function().node_sequence())) { | 2364 (node == owner()->parsed_function().node_sequence())) { |
| 2397 InlineBailout("EffectGraphVisitor::VisitSequenceNode (type check)"); | |
| 2398 const Function& function = owner()->parsed_function().function(); | 2365 const Function& function = owner()->parsed_function().function(); |
| 2399 const int num_params = function.NumberOfParameters(); | 2366 const int num_params = function.NumberOfParameters(); |
| 2400 int pos = 0; | 2367 int pos = 0; |
| 2401 if (function.IsConstructor()) { | 2368 if (function.IsConstructor()) { |
| 2402 // Skip type checking of receiver and phase for constructor functions. | 2369 // Skip type checking of receiver and phase for constructor functions. |
| 2403 pos = 2; | 2370 pos = 2; |
| 2404 } else if (function.IsFactory() || function.IsDynamicFunction()) { | 2371 } else if (function.IsFactory() || function.IsDynamicFunction()) { |
| 2405 // Skip type checking of type arguments for factory functions. | 2372 // Skip type checking of type arguments for factory functions. |
| 2406 // Skip type checking of receiver for instance functions. | 2373 // Skip type checking of receiver for instance functions. |
| 2407 pos = 1; | 2374 pos = 1; |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2533 // Generate code for the finally block if one exists. | 2500 // Generate code for the finally block if one exists. |
| 2534 if ((node->finally_block() != NULL) && is_open()) { | 2501 if ((node->finally_block() != NULL) && is_open()) { |
| 2535 EffectGraphVisitor for_finally_block(owner(), temp_index()); | 2502 EffectGraphVisitor for_finally_block(owner(), temp_index()); |
| 2536 node->finally_block()->Visit(&for_finally_block); | 2503 node->finally_block()->Visit(&for_finally_block); |
| 2537 Append(for_finally_block); | 2504 Append(for_finally_block); |
| 2538 } | 2505 } |
| 2539 } | 2506 } |
| 2540 | 2507 |
| 2541 | 2508 |
| 2542 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { | 2509 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { |
| 2543 InlineBailout("EffectGraphVisitor::BuildThrowNode"); | |
| 2544 ValueGraphVisitor for_exception(owner(), temp_index()); | 2510 ValueGraphVisitor for_exception(owner(), temp_index()); |
| 2545 node->exception()->Visit(&for_exception); | 2511 node->exception()->Visit(&for_exception); |
| 2546 Append(for_exception); | 2512 Append(for_exception); |
| 2547 PushArgument(for_exception.value()); | 2513 PushArgument(for_exception.value()); |
| 2548 Instruction* instr = NULL; | 2514 Instruction* instr = NULL; |
| 2549 if (node->stacktrace() == NULL) { | 2515 if (node->stacktrace() == NULL) { |
| 2550 instr = new ThrowInstr(node->token_pos()); | 2516 instr = new ThrowInstr(node->token_pos()); |
| 2551 } else { | 2517 } else { |
| 2552 ValueGraphVisitor for_stack_trace(owner(), temp_index()); | 2518 ValueGraphVisitor for_stack_trace(owner(), temp_index()); |
| 2553 node->stacktrace()->Visit(&for_stack_trace); | 2519 node->stacktrace()->Visit(&for_stack_trace); |
| 2554 Append(for_stack_trace); | 2520 Append(for_stack_trace); |
| 2555 PushArgument(for_stack_trace.value()); | 2521 PushArgument(for_stack_trace.value()); |
| 2556 instr = new ReThrowInstr(node->token_pos()); | 2522 instr = new ReThrowInstr(node->token_pos()); |
| 2557 } | 2523 } |
| 2558 AddInstruction(instr); | 2524 AddInstruction(instr); |
| 2559 } | 2525 } |
| 2560 | 2526 |
| 2561 | 2527 |
| 2562 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { | 2528 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { |
| 2563 InlineBailout("EffectGraphVisitor::VisitThrowNode"); | |
| 2564 BuildThrowNode(node); | 2529 BuildThrowNode(node); |
| 2565 CloseFragment(); | 2530 CloseFragment(); |
| 2566 } | 2531 } |
| 2567 | 2532 |
| 2568 | 2533 |
| 2569 // A throw cannot be part of an expression, however, the parser may replace | 2534 // A throw cannot be part of an expression, however, the parser may replace |
| 2570 // certain expression nodes with a throw. In that case generate a literal null | 2535 // certain expression nodes with a throw. In that case generate a literal null |
| 2571 // so that the fragment is not closed in the middle of an expression. | 2536 // so that the fragment is not closed in the middle of an expression. |
| 2572 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { | 2537 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { |
| 2573 InlineBailout("ValueGraphVisitor::VisitThrowNode"); | |
| 2574 BuildThrowNode(node); | 2538 BuildThrowNode(node); |
| 2575 ReturnDefinition(new ConstantInstr(Instance::ZoneHandle())); | 2539 ReturnDefinition(new ConstantInstr(Instance::ZoneHandle())); |
| 2576 } | 2540 } |
| 2577 | 2541 |
| 2578 | 2542 |
| 2579 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { | 2543 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { |
| 2580 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode"); | 2544 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode"); |
| 2581 const intptr_t try_index = owner()->try_index(); | 2545 const intptr_t try_index = owner()->try_index(); |
| 2582 if (try_index >= 0) { | 2546 if (try_index >= 0) { |
| 2583 // We are about to generate code for an inlined finally block. Exceptions | 2547 // We are about to generate code for an inlined finally block. Exceptions |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2600 for_finally_block.Goto(after_finally); | 2564 for_finally_block.Goto(after_finally); |
| 2601 for_finally_block.exit_ = after_finally; | 2565 for_finally_block.exit_ = after_finally; |
| 2602 } | 2566 } |
| 2603 | 2567 |
| 2604 Goto(finally_entry); | 2568 Goto(finally_entry); |
| 2605 AppendFragment(finally_entry, for_finally_block); | 2569 AppendFragment(finally_entry, for_finally_block); |
| 2606 exit_ = for_finally_block.exit_; | 2570 exit_ = for_finally_block.exit_; |
| 2607 } | 2571 } |
| 2608 | 2572 |
| 2609 | 2573 |
| 2610 FlowGraph* FlowGraphBuilder::BuildGraph() { | 2574 FlowGraph* FlowGraphBuilder::BuildGraph(InliningContext context) { |
| 2611 if (FLAG_print_ast) { | 2575 if (FLAG_print_ast) { |
| 2612 // Print the function ast before IL generation. | 2576 // Print the function ast before IL generation. |
| 2613 AstPrinter::PrintFunctionNodes(parsed_function()); | 2577 AstPrinter::PrintFunctionNodes(parsed_function()); |
| 2614 } | 2578 } |
| 2579 // Set the inlining context. |
| 2580 ASSERT(inlining_context_ == kNotInlining); |
| 2581 inlining_context_ = context; |
| 2582 if (InInliningContext()) exits_ = new ZoneGrowableArray<ReturnInstr*>(); |
| 2615 // Compilation can be nested, preserve the computation-id. | 2583 // Compilation can be nested, preserve the computation-id. |
| 2616 const Function& function = parsed_function().function(); | 2584 const Function& function = parsed_function().function(); |
| 2617 TargetEntryInstr* normal_entry = new TargetEntryInstr( | 2585 TargetEntryInstr* normal_entry = new TargetEntryInstr( |
| 2618 CatchClauseNode::kInvalidTryIndex); | 2586 CatchClauseNode::kInvalidTryIndex); |
| 2619 graph_entry_ = new GraphEntryInstr(normal_entry); | 2587 graph_entry_ = new GraphEntryInstr(normal_entry); |
| 2620 EffectGraphVisitor for_effect(this, 0); | 2588 EffectGraphVisitor for_effect(this, 0); |
| 2621 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the | 2589 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the |
| 2622 // stack check on entry for leaf routines). | 2590 // stack check on entry for leaf routines). |
| 2623 for_effect.Do(new CheckStackOverflowInstr(function.token_pos())); | 2591 for_effect.Do(new CheckStackOverflowInstr(function.token_pos())); |
| 2624 parsed_function().node_sequence()->Visit(&for_effect); | 2592 parsed_function().node_sequence()->Visit(&for_effect); |
| 2625 AppendFragment(normal_entry, for_effect); | 2593 AppendFragment(normal_entry, for_effect); |
| 2626 // Check that the graph is properly terminated. | 2594 // Check that the graph is properly terminated. |
| 2627 ASSERT(!for_effect.is_open()); | 2595 ASSERT(!for_effect.is_open()); |
| 2628 return new FlowGraph(*this, graph_entry_); | |
| 2629 } | |
| 2630 | |
| 2631 | |
| 2632 FlowGraph* FlowGraphBuilder::BuildGraphForInlining(InliningContext context) { | |
| 2633 ASSERT(inlining_context_ == kNotInlining); | |
| 2634 inlining_context_ = context; | |
| 2635 exits_ = new ZoneGrowableArray<ReturnInstr*>(); | |
| 2636 TargetEntryInstr* normal_entry = new TargetEntryInstr( | |
| 2637 CatchClauseNode::kInvalidTryIndex); | |
| 2638 graph_entry_ = new GraphEntryInstr(normal_entry); | |
| 2639 EffectGraphVisitor for_effect(this, 0); | |
| 2640 parsed_function().node_sequence()->Visit(&for_effect); | |
| 2641 AppendFragment(normal_entry, for_effect); | |
| 2642 ASSERT(!for_effect.is_open()); | |
| 2643 FlowGraph* graph = new FlowGraph(*this, graph_entry_); | 2596 FlowGraph* graph = new FlowGraph(*this, graph_entry_); |
| 2644 graph->set_exits(exits_); | 2597 if (InInliningContext()) graph->set_exits(exits_); |
| 2645 return graph; | 2598 return graph; |
| 2646 } | 2599 } |
| 2647 | 2600 |
| 2648 | 2601 |
| 2649 void FlowGraphBuilder::Bailout(const char* reason) { | 2602 void FlowGraphBuilder::Bailout(const char* reason) { |
| 2650 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; | 2603 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; |
| 2651 const char* function_name = parsed_function_.function().ToCString(); | 2604 const char* function_name = parsed_function_.function().ToCString(); |
| 2652 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 2605 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 2653 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 2606 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 2654 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2607 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2655 const Error& error = Error::Handle( | 2608 const Error& error = Error::Handle( |
| 2656 LanguageError::New(String::Handle(String::New(chars)))); | 2609 LanguageError::New(String::Handle(String::New(chars)))); |
| 2657 Isolate::Current()->long_jump_base()->Jump(1, error); | 2610 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2658 } | 2611 } |
| 2659 | 2612 |
| 2660 | 2613 |
| 2661 } // namespace dart | 2614 } // namespace dart |
| OLD | NEW |