| 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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 | 211 |
| 210 | 212 |
| 211 Definition* EffectGraphVisitor::BuildStoreLocal( | 213 Definition* EffectGraphVisitor::BuildStoreLocal( |
| 212 const LocalVariable& local, Value* value) { | 214 const LocalVariable& local, Value* value) { |
| 213 if (local.is_captured()) { | 215 if (local.is_captured()) { |
| 214 intptr_t delta = | 216 intptr_t delta = |
| 215 owner()->context_level() - local.owner()->context_level(); | 217 owner()->context_level() - local.owner()->context_level(); |
| 216 ASSERT(delta >= 0); | 218 ASSERT(delta >= 0); |
| 217 Value* context = Bind(new CurrentContextInstr()); | 219 Value* context = Bind(new CurrentContextInstr()); |
| 218 while (delta-- > 0) { | 220 while (delta-- > 0) { |
| 221 InlineBailout("EffectGraphVisitor::BuildStoreLocal (deopt)"); |
| 219 context = Bind(new LoadVMFieldInstr( | 222 context = Bind(new LoadVMFieldInstr( |
| 220 context, Context::parent_offset(), Type::ZoneHandle())); | 223 context, Context::parent_offset(), Type::ZoneHandle())); |
| 221 } | 224 } |
| 222 return new StoreVMFieldInstr( | 225 return new StoreVMFieldInstr( |
| 223 context, | 226 context, |
| 224 Context::variable_offset(local.index()), | 227 Context::variable_offset(local.index()), |
| 225 value, | 228 value, |
| 226 local.type()); | 229 local.type()); |
| 227 } else { | 230 } else { |
| 228 return new StoreLocalInstr(local, value, owner()->context_level()); | 231 return new StoreLocalInstr(local, value, owner()->context_level()); |
| 229 } | 232 } |
| 230 } | 233 } |
| 231 | 234 |
| 232 | 235 |
| 233 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) { | 236 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) { |
| 234 if (local.is_captured()) { | 237 if (local.is_captured()) { |
| 238 InlineBailout("EffectGraphVisitor::BuildStoreLocal (deopt)"); |
| 235 intptr_t delta = | 239 intptr_t delta = |
| 236 owner()->context_level() - local.owner()->context_level(); | 240 owner()->context_level() - local.owner()->context_level(); |
| 237 ASSERT(delta >= 0); | 241 ASSERT(delta >= 0); |
| 238 Value* context = Bind(new CurrentContextInstr()); | 242 Value* context = Bind(new CurrentContextInstr()); |
| 239 while (delta-- > 0) { | 243 while (delta-- > 0) { |
| 240 context = Bind(new LoadVMFieldInstr( | 244 context = Bind(new LoadVMFieldInstr( |
| 241 context, Context::parent_offset(), Type::ZoneHandle())); | 245 context, Context::parent_offset(), Type::ZoneHandle())); |
| 242 } | 246 } |
| 243 return new LoadVMFieldInstr(context, | 247 return new LoadVMFieldInstr(context, |
| 244 Context::variable_offset(local.index()), | 248 Context::variable_offset(local.index()), |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { | 444 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { |
| 441 InlineBailout("EffectGraphVisitor::VisitReturnNode (finally)"); | 445 InlineBailout("EffectGraphVisitor::VisitReturnNode (finally)"); |
| 442 EffectGraphVisitor for_effect(owner(), temp_index()); | 446 EffectGraphVisitor for_effect(owner(), temp_index()); |
| 443 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); | 447 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
| 444 Append(for_effect); | 448 Append(for_effect); |
| 445 if (!is_open()) return; | 449 if (!is_open()) return; |
| 446 } | 450 } |
| 447 | 451 |
| 448 Value* return_value = for_value.value(); | 452 Value* return_value = for_value.value(); |
| 449 if (FLAG_enable_type_checks) { | 453 if (FLAG_enable_type_checks) { |
| 450 InlineBailout("EffectGraphVisitor::VisitReturnNode (type check)"); | |
| 451 const Function& function = owner()->parsed_function().function(); | 454 const Function& function = owner()->parsed_function().function(); |
| 452 const bool is_implicit_dynamic_getter = | 455 const bool is_implicit_dynamic_getter = |
| 453 (!function.is_static() && | 456 (!function.is_static() && |
| 454 ((function.kind() == RawFunction::kImplicitGetter) || | 457 ((function.kind() == RawFunction::kImplicitGetter) || |
| 455 (function.kind() == RawFunction::kConstImplicitGetter))); | 458 (function.kind() == RawFunction::kConstImplicitGetter))); |
| 456 // Implicit getters do not need a type check at return, unless they compute | 459 // Implicit getters do not need a type check at return, unless they compute |
| 457 // the initial value of a static field. | 460 // the initial value of a static field. |
| 458 // The body of a constructor cannot modify the type of the | 461 // The body of a constructor cannot modify the type of the |
| 459 // constructed instance, which is passed in as an implicit parameter. | 462 // constructed instance, which is passed in as an implicit parameter. |
| 460 // However, factories may create an instance of the wrong type. | 463 // However, factories may create an instance of the wrong type. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } | 508 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); } |
| 506 | 509 |
| 507 | 510 |
| 508 // Returns true if the type check can be skipped, for example, if the | 511 // Returns true if the type check can be skipped, for example, if the |
| 509 // destination type is Dynamic or if the compile type of the value is a subtype | 512 // destination type is Dynamic or if the compile type of the value is a subtype |
| 510 // of the destination type. | 513 // of the destination type. |
| 511 bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos, | 514 bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos, |
| 512 Value* value, | 515 Value* value, |
| 513 const AbstractType& dst_type, | 516 const AbstractType& dst_type, |
| 514 const String& dst_name) { | 517 const String& dst_name) { |
| 515 InlineBailout("EffectGraphVisitor::CanSkipTypeCheck"); | |
| 516 ASSERT(!dst_type.IsNull()); | 518 ASSERT(!dst_type.IsNull()); |
| 517 ASSERT(dst_type.IsFinalized()); | 519 ASSERT(dst_type.IsFinalized()); |
| 518 | 520 |
| 519 // If the destination type is malformed, a dynamic type error must be thrown | 521 // If the destination type is malformed, a dynamic type error must be thrown |
| 520 // at run time. | 522 // at run time. |
| 521 if (dst_type.IsMalformed()) { | 523 if (dst_type.IsMalformed()) { |
| 522 return false; | 524 return false; |
| 523 } | 525 } |
| 524 | 526 |
| 525 // Any type is more specific than the Dynamic type and than the Object type. | 527 // Any type is more specific than the Dynamic type and than the Object type. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 553 eliminated); | 555 eliminated); |
| 554 } | 556 } |
| 555 return eliminated; | 557 return eliminated; |
| 556 } | 558 } |
| 557 | 559 |
| 558 | 560 |
| 559 // <Expression> :: Assignable { expr: <Expression> | 561 // <Expression> :: Assignable { expr: <Expression> |
| 560 // type: AbstractType | 562 // type: AbstractType |
| 561 // dst_name: String } | 563 // dst_name: String } |
| 562 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { | 564 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 563 InlineBailout("EffectGraphVisitor::VisitAssignableNode"); | |
| 564 UNREACHABLE(); | 565 UNREACHABLE(); |
| 565 } | 566 } |
| 566 | 567 |
| 567 | 568 |
| 568 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { | 569 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 569 InlineBailout("ValueGraphVisitor::VisitAssignableNode"); | |
| 570 ValueGraphVisitor for_value(owner(), temp_index()); | 570 ValueGraphVisitor for_value(owner(), temp_index()); |
| 571 node->expr()->Visit(&for_value); | 571 node->expr()->Visit(&for_value); |
| 572 Append(for_value); | 572 Append(for_value); |
| 573 ReturnValue(BuildAssignableValue(node->expr()->token_pos(), | 573 ReturnValue(BuildAssignableValue(node->expr()->token_pos(), |
| 574 for_value.value(), | 574 for_value.value(), |
| 575 node->type(), | 575 node->type(), |
| 576 node->dst_name())); | 576 node->dst_name())); |
| 577 } | 577 } |
| 578 | 578 |
| 579 | 579 |
| 580 // <Expression> :: BinaryOp { kind: Token::Kind | 580 // <Expression> :: BinaryOp { kind: Token::Kind |
| 581 // left: <Expression> | 581 // left: <Expression> |
| 582 // right: <Expression> } | 582 // right: <Expression> } |
| 583 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 583 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 584 InlineBailout("EffectGraphVisitor::VisitBinaryOpNode"); | |
| 585 // Operators "&&" and "||" cannot be overloaded therefore do not call | 584 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 586 // operator. | 585 // operator. |
| 587 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 586 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 588 // See ValueGraphVisitor::VisitBinaryOpNode. | 587 // See ValueGraphVisitor::VisitBinaryOpNode. |
| 589 TestGraphVisitor for_left(owner(), | 588 TestGraphVisitor for_left(owner(), |
| 590 temp_index(), | 589 temp_index(), |
| 591 node->left()->token_pos()); | 590 node->left()->token_pos()); |
| 592 node->left()->Visit(&for_left); | 591 node->left()->Visit(&for_left); |
| 593 EffectGraphVisitor for_right(owner(), temp_index()); | 592 EffectGraphVisitor for_right(owner(), temp_index()); |
| 594 node->right()->Visit(&for_right); | 593 node->right()->Visit(&for_right); |
| 595 EffectGraphVisitor empty(owner(), temp_index()); | 594 EffectGraphVisitor empty(owner(), temp_index()); |
| 596 if (node->kind() == Token::kAND) { | 595 if (node->kind() == Token::kAND) { |
| 597 Join(for_left, for_right, empty); | 596 Join(for_left, for_right, empty); |
| 598 } else { | 597 } else { |
| 599 Join(for_left, empty, for_right); | 598 Join(for_left, empty, for_right); |
| 600 } | 599 } |
| 601 return; | 600 return; |
| 602 } | 601 } |
| 602 InlineBailout("EffectGraphVisitor::VisitBinaryOpNode (deopt)"); |
| 603 ValueGraphVisitor for_left_value(owner(), temp_index()); | 603 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 604 node->left()->Visit(&for_left_value); | 604 node->left()->Visit(&for_left_value); |
| 605 Append(for_left_value); | 605 Append(for_left_value); |
| 606 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); | 606 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); |
| 607 | 607 |
| 608 ValueGraphVisitor for_right_value(owner(), temp_index()); | 608 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 609 node->right()->Visit(&for_right_value); | 609 node->right()->Visit(&for_right_value); |
| 610 Append(for_right_value); | 610 Append(for_right_value); |
| 611 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); | 611 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); |
| 612 | 612 |
| 613 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 613 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 614 new ZoneGrowableArray<PushArgumentInstr*>(2); | 614 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 615 arguments->Add(push_left); | 615 arguments->Add(push_left); |
| 616 arguments->Add(push_right); | 616 arguments->Add(push_right); |
| 617 const String& name = String::ZoneHandle(Symbols::New(node->Name())); | 617 const String& name = String::ZoneHandle(Symbols::New(node->Name())); |
| 618 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), | 618 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), |
| 619 name, | 619 name, |
| 620 node->kind(), | 620 node->kind(), |
| 621 arguments, | 621 arguments, |
| 622 Array::ZoneHandle(), | 622 Array::ZoneHandle(), |
| 623 2); | 623 2); |
| 624 ReturnDefinition(call); | 624 ReturnDefinition(call); |
| 625 } | 625 } |
| 626 | 626 |
| 627 | 627 |
| 628 // Special handling for AND/OR. | 628 // Special handling for AND/OR. |
| 629 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 629 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 630 InlineBailout("ValueGraphVisitor::VisitBinaryOpNode"); | |
| 631 // Operators "&&" and "||" cannot be overloaded therefore do not call | 630 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 632 // operator. | 631 // operator. |
| 633 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 632 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 634 // Implement short-circuit logic: do not evaluate right if evaluation | 633 // Implement short-circuit logic: do not evaluate right if evaluation |
| 635 // of left is sufficient. | 634 // of left is sufficient. |
| 636 // AND: left ? right === true : false; | 635 // AND: left ? right === true : false; |
| 637 // OR: left ? true : right === true; | 636 // OR: left ? true : right === true; |
| 638 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 637 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 639 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 638 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| 640 | 639 |
| 641 TestGraphVisitor for_test(owner(), | 640 TestGraphVisitor for_test(owner(), |
| 642 temp_index(), | 641 temp_index(), |
| 643 node->left()->token_pos()); | 642 node->left()->token_pos()); |
| 644 node->left()->Visit(&for_test); | 643 node->left()->Visit(&for_test); |
| 645 | 644 |
| 646 ValueGraphVisitor for_right(owner(), temp_index()); | 645 ValueGraphVisitor for_right(owner(), temp_index()); |
| 647 node->right()->Visit(&for_right); | 646 node->right()->Visit(&for_right); |
| 648 Value* right_value = for_right.value(); | 647 Value* right_value = for_right.value(); |
| 649 if (FLAG_enable_type_checks) { | 648 if (FLAG_enable_type_checks) { |
| 649 InlineBailout("ValueGraphVisitor::VisitBinaryOpNode (type check)"); |
| 650 right_value = | 650 right_value = |
| 651 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(), | 651 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(), |
| 652 right_value)); | 652 right_value)); |
| 653 } | 653 } |
| 654 Value* constant_true = for_right.Bind(new ConstantInstr(bool_true)); | 654 Value* constant_true = for_right.Bind(new ConstantInstr(bool_true)); |
| 655 Value* compare = | 655 Value* compare = |
| 656 for_right.Bind(new StrictCompareInstr(Token::kEQ_STRICT, | 656 for_right.Bind(new StrictCompareInstr(Token::kEQ_STRICT, |
| 657 right_value, | 657 right_value, |
| 658 constant_true)); | 658 constant_true)); |
| 659 for_right.Do(BuildStoreLocal( | 659 for_right.Do(BuildStoreLocal( |
| (...skipping 21 matching lines...) Expand all Loading... |
| 681 return; | 681 return; |
| 682 } | 682 } |
| 683 EffectGraphVisitor::VisitBinaryOpNode(node); | 683 EffectGraphVisitor::VisitBinaryOpNode(node); |
| 684 } | 684 } |
| 685 | 685 |
| 686 | 686 |
| 687 void EffectGraphVisitor::BuildTypecheckArguments( | 687 void EffectGraphVisitor::BuildTypecheckArguments( |
| 688 intptr_t token_pos, | 688 intptr_t token_pos, |
| 689 Value** instantiator_result, | 689 Value** instantiator_result, |
| 690 Value** instantiator_type_arguments_result) { | 690 Value** instantiator_type_arguments_result) { |
| 691 InlineBailout("EffectGraphVisitor::VisitBinaryOpNode"); | |
| 692 Value* instantiator = NULL; | 691 Value* instantiator = NULL; |
| 693 Value* instantiator_type_arguments = NULL; | 692 Value* instantiator_type_arguments = NULL; |
| 694 const Class& instantiator_class = Class::Handle( | 693 const Class& instantiator_class = Class::Handle( |
| 695 owner()->parsed_function().function().Owner()); | 694 owner()->parsed_function().function().Owner()); |
| 696 // Since called only when type tested against is not instantiated. | 695 // Since called only when type tested against is not instantiated. |
| 697 ASSERT(instantiator_class.NumTypeParameters() > 0); | 696 ASSERT(instantiator_class.NumTypeParameters() > 0); |
| 698 instantiator = BuildInstantiator(); | 697 instantiator = BuildInstantiator(); |
| 699 if (instantiator == NULL) { | 698 if (instantiator == NULL) { |
| 700 // No instantiator when inside factory. | 699 // No instantiator when inside factory. |
| 701 instantiator = BuildNullValue(); | 700 instantiator = BuildNullValue(); |
| 702 instantiator_type_arguments = | 701 instantiator_type_arguments = |
| 703 BuildInstantiatorTypeArguments(token_pos, NULL); | 702 BuildInstantiatorTypeArguments(token_pos, NULL); |
| 704 } else { | 703 } else { |
| 705 // Preserve instantiator. | 704 // Preserve instantiator. |
| 706 const LocalVariable& expr_temp = | 705 const LocalVariable& expr_temp = |
| 707 *owner()->parsed_function().expression_temp_var(); | 706 *owner()->parsed_function().expression_temp_var(); |
| 708 instantiator = Bind(BuildStoreLocal(expr_temp, instantiator)); | 707 instantiator = Bind(BuildStoreLocal(expr_temp, instantiator)); |
| 709 Value* loaded = Bind(BuildLoadLocal(expr_temp)); | 708 Value* loaded = Bind(BuildLoadLocal(expr_temp)); |
| 710 instantiator_type_arguments = | 709 instantiator_type_arguments = |
| 711 BuildInstantiatorTypeArguments(token_pos, loaded); | 710 BuildInstantiatorTypeArguments(token_pos, loaded); |
| 712 } | 711 } |
| 713 *instantiator_result = instantiator; | 712 *instantiator_result = instantiator; |
| 714 *instantiator_type_arguments_result = instantiator_type_arguments; | 713 *instantiator_type_arguments_result = instantiator_type_arguments; |
| 715 } | 714 } |
| 716 | 715 |
| 717 | 716 |
| 718 Value* EffectGraphVisitor::BuildNullValue() { | 717 Value* EffectGraphVisitor::BuildNullValue() { |
| 719 InlineBailout("EffectGraphVisitor::BuildNullValue"); | |
| 720 return Bind(new ConstantInstr(Object::ZoneHandle())); | 718 return Bind(new ConstantInstr(Object::ZoneHandle())); |
| 721 } | 719 } |
| 722 | 720 |
| 723 | 721 |
| 724 // Used for testing incoming arguments. | 722 // Used for testing incoming arguments. |
| 725 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( | 723 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( |
| 726 intptr_t token_pos, | 724 intptr_t token_pos, |
| 727 Value* value, | 725 Value* value, |
| 728 const AbstractType& dst_type, | 726 const AbstractType& dst_type, |
| 729 const String& dst_name) { | 727 const String& dst_name) { |
| 730 InlineBailout("EffectGraphVisitor::BuildAssertAssignable"); | 728 InlineBailout("EffectGraphVisitor::BuildAssertAssignable (deopt)"); |
| 731 // Build the type check computation. | 729 // Build the type check computation. |
| 732 Value* instantiator = NULL; | 730 Value* instantiator = NULL; |
| 733 Value* instantiator_type_arguments = NULL; | 731 Value* instantiator_type_arguments = NULL; |
| 734 if (dst_type.IsInstantiated()) { | 732 if (dst_type.IsInstantiated()) { |
| 735 instantiator = BuildNullValue(); | 733 instantiator = BuildNullValue(); |
| 736 instantiator_type_arguments = BuildNullValue(); | 734 instantiator_type_arguments = BuildNullValue(); |
| 737 } else { | 735 } else { |
| 738 BuildTypecheckArguments(token_pos, | 736 BuildTypecheckArguments(token_pos, |
| 739 &instantiator, | 737 &instantiator, |
| 740 &instantiator_type_arguments); | 738 &instantiator_type_arguments); |
| 741 } | 739 } |
| 742 return new AssertAssignableInstr(token_pos, | 740 return new AssertAssignableInstr(token_pos, |
| 743 value, | 741 value, |
| 744 instantiator, | 742 instantiator, |
| 745 instantiator_type_arguments, | 743 instantiator_type_arguments, |
| 746 dst_type, | 744 dst_type, |
| 747 dst_name); | 745 dst_name); |
| 748 } | 746 } |
| 749 | 747 |
| 750 | 748 |
| 751 // Used for type casts and to test assignments. | 749 // Used for type casts and to test assignments. |
| 752 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos, | 750 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos, |
| 753 Value* value, | 751 Value* value, |
| 754 const AbstractType& dst_type, | 752 const AbstractType& dst_type, |
| 755 const String& dst_name) { | 753 const String& dst_name) { |
| 756 InlineBailout("EffectGraphVisitor::BuildAssignableValue"); | |
| 757 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { | 754 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { |
| 758 return value; | 755 return value; |
| 759 } | 756 } |
| 760 return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name)); | 757 return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name)); |
| 761 } | 758 } |
| 762 | 759 |
| 763 | 760 |
| 764 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { | 761 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
| 765 InlineBailout("EffectGraphVisitor::BuildTypeTest"); | |
| 766 ASSERT(Token::IsTypeTestOperator(node->kind())); | 762 ASSERT(Token::IsTypeTestOperator(node->kind())); |
| 767 EffectGraphVisitor for_left_value(owner(), temp_index()); | 763 EffectGraphVisitor for_left_value(owner(), temp_index()); |
| 768 node->left()->Visit(&for_left_value); | 764 node->left()->Visit(&for_left_value); |
| 769 Append(for_left_value); | 765 Append(for_left_value); |
| 770 } | 766 } |
| 771 | 767 |
| 772 | 768 |
| 773 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { | 769 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { |
| 774 InlineBailout("EffectGraphVisitor::BuildTypeCast"); | |
| 775 ASSERT(Token::IsTypeCastOperator(node->kind())); | 770 ASSERT(Token::IsTypeCastOperator(node->kind())); |
| 776 const AbstractType& type = node->right()->AsTypeNode()->type(); | 771 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 777 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. | 772 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. |
| 778 ValueGraphVisitor for_value(owner(), temp_index()); | 773 ValueGraphVisitor for_value(owner(), temp_index()); |
| 779 node->left()->Visit(&for_value); | 774 node->left()->Visit(&for_value); |
| 780 const String& dst_name = String::ZoneHandle( | 775 const String& dst_name = String::ZoneHandle( |
| 781 Symbols::New(Exceptions::kCastExceptionDstName)); | 776 Symbols::New(Exceptions::kCastExceptionDstName)); |
| 782 if (!CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) { | 777 if (!CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) { |
| 783 Append(for_value); | 778 Append(for_value); |
| 784 Do(BuildAssertAssignable( | 779 Do(BuildAssertAssignable( |
| 785 node->token_pos(), for_value.value(), type, dst_name)); | 780 node->token_pos(), for_value.value(), type, dst_name)); |
| 786 } | 781 } |
| 787 } | 782 } |
| 788 | 783 |
| 789 | 784 |
| 790 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { | 785 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
| 791 InlineBailout("ValueGraphVisitor::BuildTypeTest"); | |
| 792 ASSERT(Token::IsTypeTestOperator(node->kind())); | 786 ASSERT(Token::IsTypeTestOperator(node->kind())); |
| 793 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 787 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 794 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 788 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| 795 const AbstractType& type = node->right()->AsTypeNode()->type(); | 789 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 796 ASSERT(type.IsFinalized() && !type.IsMalformed()); | 790 ASSERT(type.IsFinalized() && !type.IsMalformed()); |
| 797 const bool negate_result = (node->kind() == Token::kISNOT); | 791 const bool negate_result = (node->kind() == Token::kISNOT); |
| 798 // All objects are instances of type T if Object type is a subtype of type T. | 792 // All objects are instances of type T if Object type is a subtype of type T. |
| 799 const Type& object_type = Type::Handle(Type::ObjectType()); | 793 const Type& object_type = Type::Handle(Type::ObjectType()); |
| 800 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { | 794 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { |
| 801 // Must evaluate left side. | 795 // Must evaluate left side. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 822 } else { | 816 } else { |
| 823 if (literal_value.IsInstanceOf(type, TypeArguments::Handle(), NULL)) { | 817 if (literal_value.IsInstanceOf(type, TypeArguments::Handle(), NULL)) { |
| 824 result = new ConstantInstr(negate_result ? bool_false : bool_true); | 818 result = new ConstantInstr(negate_result ? bool_false : bool_true); |
| 825 } else { | 819 } else { |
| 826 result = new ConstantInstr(negate_result ? bool_true : bool_false); | 820 result = new ConstantInstr(negate_result ? bool_true : bool_false); |
| 827 } | 821 } |
| 828 } | 822 } |
| 829 ReturnDefinition(result); | 823 ReturnDefinition(result); |
| 830 return; | 824 return; |
| 831 } | 825 } |
| 826 InlineBailout("ValueGraphVisitor::BuildTypeTest (deopt)"); |
| 832 | 827 |
| 833 ValueGraphVisitor for_left_value(owner(), temp_index()); | 828 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 834 node->left()->Visit(&for_left_value); | 829 node->left()->Visit(&for_left_value); |
| 835 Append(for_left_value); | 830 Append(for_left_value); |
| 836 Value* instantiator = NULL; | 831 Value* instantiator = NULL; |
| 837 Value* instantiator_type_arguments = NULL; | 832 Value* instantiator_type_arguments = NULL; |
| 838 if (type.IsInstantiated()) { | 833 if (type.IsInstantiated()) { |
| 839 instantiator = BuildNullValue(); | 834 instantiator = BuildNullValue(); |
| 840 instantiator_type_arguments = BuildNullValue(); | 835 instantiator_type_arguments = BuildNullValue(); |
| 841 } else { | 836 } else { |
| 842 BuildTypecheckArguments(node->token_pos(), | 837 BuildTypecheckArguments(node->token_pos(), |
| 843 &instantiator, | 838 &instantiator, |
| 844 &instantiator_type_arguments); | 839 &instantiator_type_arguments); |
| 845 } | 840 } |
| 846 InstanceOfInstr* instance_of = | 841 InstanceOfInstr* instance_of = |
| 847 new InstanceOfInstr(node->token_pos(), | 842 new InstanceOfInstr(node->token_pos(), |
| 848 for_left_value.value(), | 843 for_left_value.value(), |
| 849 instantiator, | 844 instantiator, |
| 850 instantiator_type_arguments, | 845 instantiator_type_arguments, |
| 851 node->right()->AsTypeNode()->type(), | 846 node->right()->AsTypeNode()->type(), |
| 852 (node->kind() == Token::kISNOT)); | 847 (node->kind() == Token::kISNOT)); |
| 853 ReturnDefinition(instance_of); | 848 ReturnDefinition(instance_of); |
| 854 } | 849 } |
| 855 | 850 |
| 856 | 851 |
| 857 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { | 852 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { |
| 858 InlineBailout("ValueGraphVisitor::BuildTypeCast"); | |
| 859 ASSERT(Token::IsTypeCastOperator(node->kind())); | 853 ASSERT(Token::IsTypeCastOperator(node->kind())); |
| 860 const AbstractType& type = node->right()->AsTypeNode()->type(); | 854 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 861 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. | 855 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. |
| 862 ValueGraphVisitor for_value(owner(), temp_index()); | 856 ValueGraphVisitor for_value(owner(), temp_index()); |
| 863 node->left()->Visit(&for_value); | 857 node->left()->Visit(&for_value); |
| 864 Append(for_value); | 858 Append(for_value); |
| 865 const String& dst_name = String::ZoneHandle( | 859 const String& dst_name = String::ZoneHandle( |
| 866 Symbols::New(Exceptions::kCastExceptionDstName)); | 860 Symbols::New(Exceptions::kCastExceptionDstName)); |
| 867 ReturnValue(BuildAssignableValue(node->token_pos(), | 861 ReturnValue(BuildAssignableValue(node->token_pos(), |
| 868 for_value.value(), | 862 for_value.value(), |
| 869 type, | 863 type, |
| 870 dst_name)); | 864 dst_name)); |
| 871 } | 865 } |
| 872 | 866 |
| 873 | 867 |
| 874 // <Expression> :: Comparison { kind: Token::Kind | 868 // <Expression> :: Comparison { kind: Token::Kind |
| 875 // left: <Expression> | 869 // left: <Expression> |
| 876 // right: <Expression> } | 870 // right: <Expression> } |
| 877 // TODO(srdjan): Implement new equality. | 871 // TODO(srdjan): Implement new equality. |
| 878 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { | 872 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { |
| 879 InlineBailout("EffectGraphVisitor::VisitComparisonNode"); | |
| 880 if (Token::IsTypeTestOperator(node->kind())) { | 873 if (Token::IsTypeTestOperator(node->kind())) { |
| 881 BuildTypeTest(node); | 874 BuildTypeTest(node); |
| 882 return; | 875 return; |
| 883 } | 876 } |
| 884 if (Token::IsTypeCastOperator(node->kind())) { | 877 if (Token::IsTypeCastOperator(node->kind())) { |
| 885 BuildTypeCast(node); | 878 BuildTypeCast(node); |
| 886 return; | 879 return; |
| 887 } | 880 } |
| 888 if ((node->kind() == Token::kEQ_STRICT) || | 881 if ((node->kind() == Token::kEQ_STRICT) || |
| 889 (node->kind() == Token::kNE_STRICT)) { | 882 (node->kind() == Token::kNE_STRICT)) { |
| 890 ValueGraphVisitor for_left_value(owner(), temp_index()); | 883 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 891 node->left()->Visit(&for_left_value); | 884 node->left()->Visit(&for_left_value); |
| 892 Append(for_left_value); | 885 Append(for_left_value); |
| 893 ValueGraphVisitor for_right_value(owner(), temp_index()); | 886 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 894 node->right()->Visit(&for_right_value); | 887 node->right()->Visit(&for_right_value); |
| 895 Append(for_right_value); | 888 Append(for_right_value); |
| 896 StrictCompareInstr* comp = new StrictCompareInstr( | 889 StrictCompareInstr* comp = new StrictCompareInstr( |
| 897 node->kind(), for_left_value.value(), for_right_value.value()); | 890 node->kind(), for_left_value.value(), for_right_value.value()); |
| 898 ReturnDefinition(comp); | 891 ReturnDefinition(comp); |
| 899 return; | 892 return; |
| 900 } | 893 } |
| 894 InlineBailout("EffectGraphVisitor::VisitComparisonNode (deopt)"); |
| 901 | 895 |
| 902 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { | 896 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { |
| 903 ValueGraphVisitor for_left_value(owner(), temp_index()); | 897 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 904 node->left()->Visit(&for_left_value); | 898 node->left()->Visit(&for_left_value); |
| 905 Append(for_left_value); | 899 Append(for_left_value); |
| 906 ValueGraphVisitor for_right_value(owner(), temp_index()); | 900 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 907 node->right()->Visit(&for_right_value); | 901 node->right()->Visit(&for_right_value); |
| 908 Append(for_right_value); | 902 Append(for_right_value); |
| 909 if (FLAG_enable_type_checks) { | 903 if (FLAG_enable_type_checks) { |
| 910 EqualityCompareInstr* comp = new EqualityCompareInstr( | 904 EqualityCompareInstr* comp = new EqualityCompareInstr( |
| (...skipping 27 matching lines...) Expand all Loading... |
| 938 Append(for_right_value); | 932 Append(for_right_value); |
| 939 RelationalOpInstr* comp = new RelationalOpInstr(node->token_pos(), | 933 RelationalOpInstr* comp = new RelationalOpInstr(node->token_pos(), |
| 940 node->kind(), | 934 node->kind(), |
| 941 for_left_value.value(), | 935 for_left_value.value(), |
| 942 for_right_value.value()); | 936 for_right_value.value()); |
| 943 ReturnDefinition(comp); | 937 ReturnDefinition(comp); |
| 944 } | 938 } |
| 945 | 939 |
| 946 | 940 |
| 947 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { | 941 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { |
| 948 InlineBailout("EffectGraphVisitor::VisitUnaryOpNode"); | |
| 949 // "!" cannot be overloaded, therefore do not call operator. | 942 // "!" cannot be overloaded, therefore do not call operator. |
| 950 if (node->kind() == Token::kNOT) { | 943 if (node->kind() == Token::kNOT) { |
| 951 ValueGraphVisitor for_value(owner(), temp_index()); | 944 ValueGraphVisitor for_value(owner(), temp_index()); |
| 952 node->operand()->Visit(&for_value); | 945 node->operand()->Visit(&for_value); |
| 953 Append(for_value); | 946 Append(for_value); |
| 954 Value* value = for_value.value(); | 947 Value* value = for_value.value(); |
| 955 if (FLAG_enable_type_checks) { | 948 if (FLAG_enable_type_checks) { |
| 956 value = | 949 value = |
| 957 Bind(new AssertBooleanInstr(node->operand()->token_pos(), value)); | 950 Bind(new AssertBooleanInstr(node->operand()->token_pos(), value)); |
| 958 } | 951 } |
| 959 BooleanNegateInstr* negate = new BooleanNegateInstr(value); | 952 BooleanNegateInstr* negate = new BooleanNegateInstr(value); |
| 960 ReturnDefinition(negate); | 953 ReturnDefinition(negate); |
| 961 return; | 954 return; |
| 962 } | 955 } |
| 956 InlineBailout("EffectGraphVisitor::VisitUnaryOpNode (deopt)"); |
| 957 |
| 963 ValueGraphVisitor for_value(owner(), temp_index()); | 958 ValueGraphVisitor for_value(owner(), temp_index()); |
| 964 node->operand()->Visit(&for_value); | 959 node->operand()->Visit(&for_value); |
| 965 Append(for_value); | 960 Append(for_value); |
| 966 PushArgumentInstr* push_value = PushArgument(for_value.value()); | 961 PushArgumentInstr* push_value = PushArgument(for_value.value()); |
| 967 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 962 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 968 new ZoneGrowableArray<PushArgumentInstr*>(1); | 963 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 969 arguments->Add(push_value); | 964 arguments->Add(push_value); |
| 970 String& name = String::ZoneHandle(); | 965 String& name = String::ZoneHandle(); |
| 971 if (node->kind() == Token::kSUB) { | 966 if (node->kind() == Token::kSUB) { |
| 972 name = Symbols::New("unary-"); | 967 name = Symbols::New("unary-"); |
| 973 } else { | 968 } else { |
| 974 name = Symbols::New(Token::Str(node->kind())); | 969 name = Symbols::New(Token::Str(node->kind())); |
| 975 } | 970 } |
| 976 InstanceCallInstr* call = new InstanceCallInstr( | 971 InstanceCallInstr* call = new InstanceCallInstr( |
| 977 node->token_pos(), name, node->kind(), | 972 node->token_pos(), name, node->kind(), |
| 978 arguments, Array::ZoneHandle(), 1); | 973 arguments, Array::ZoneHandle(), 1); |
| 979 ReturnDefinition(call); | 974 ReturnDefinition(call); |
| 980 } | 975 } |
| 981 | 976 |
| 982 | 977 |
| 983 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 978 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| 984 InlineBailout("EffectGraphVisitor::VisitConditionalExprNode"); | |
| 985 TestGraphVisitor for_test(owner(), | 979 TestGraphVisitor for_test(owner(), |
| 986 temp_index(), | 980 temp_index(), |
| 987 node->condition()->token_pos()); | 981 node->condition()->token_pos()); |
| 988 node->condition()->Visit(&for_test); | 982 node->condition()->Visit(&for_test); |
| 989 | 983 |
| 990 // Translate the subexpressions for their effects. | 984 // Translate the subexpressions for their effects. |
| 991 EffectGraphVisitor for_true(owner(), temp_index()); | 985 EffectGraphVisitor for_true(owner(), temp_index()); |
| 992 node->true_expr()->Visit(&for_true); | 986 node->true_expr()->Visit(&for_true); |
| 993 EffectGraphVisitor for_false(owner(), temp_index()); | 987 EffectGraphVisitor for_false(owner(), temp_index()); |
| 994 node->false_expr()->Visit(&for_false); | 988 node->false_expr()->Visit(&for_false); |
| 995 | 989 |
| 996 Join(for_test, for_true, for_false); | 990 Join(for_test, for_true, for_false); |
| 997 } | 991 } |
| 998 | 992 |
| 999 | 993 |
| 1000 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 994 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| 1001 InlineBailout("ValueGraphVisitor::VisitConditionalExprNode"); | |
| 1002 TestGraphVisitor for_test(owner(), | 995 TestGraphVisitor for_test(owner(), |
| 1003 temp_index(), | 996 temp_index(), |
| 1004 node->condition()->token_pos()); | 997 node->condition()->token_pos()); |
| 1005 node->condition()->Visit(&for_test); | 998 node->condition()->Visit(&for_test); |
| 1006 | 999 |
| 1007 ValueGraphVisitor for_true(owner(), temp_index()); | 1000 ValueGraphVisitor for_true(owner(), temp_index()); |
| 1008 node->true_expr()->Visit(&for_true); | 1001 node->true_expr()->Visit(&for_true); |
| 1009 ASSERT(for_true.is_open()); | 1002 ASSERT(for_true.is_open()); |
| 1010 for_true.Do(BuildStoreLocal( | 1003 for_true.Do(BuildStoreLocal( |
| 1011 *owner()->parsed_function().expression_temp_var(), for_true.value())); | 1004 *owner()->parsed_function().expression_temp_var(), for_true.value())); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1036 | 1029 |
| 1037 node->true_branch()->Visit(&for_true); | 1030 node->true_branch()->Visit(&for_true); |
| 1038 // The for_false graph fragment will be empty (default graph fragment) if | 1031 // The for_false graph fragment will be empty (default graph fragment) if |
| 1039 // we do not call Visit. | 1032 // we do not call Visit. |
| 1040 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false); | 1033 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false); |
| 1041 Join(for_test, for_true, for_false); | 1034 Join(for_test, for_true, for_false); |
| 1042 } | 1035 } |
| 1043 | 1036 |
| 1044 | 1037 |
| 1045 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) { | 1038 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) { |
| 1046 InlineBailout("EffectGraphVisitor::VisitSwitchNode"); | |
| 1047 EffectGraphVisitor switch_body(owner(), temp_index()); | 1039 EffectGraphVisitor switch_body(owner(), temp_index()); |
| 1048 node->body()->Visit(&switch_body); | 1040 node->body()->Visit(&switch_body); |
| 1049 Append(switch_body); | 1041 Append(switch_body); |
| 1050 if ((node->label() != NULL) && (node->label()->join_for_break() != NULL)) { | 1042 if ((node->label() != NULL) && (node->label()->join_for_break() != NULL)) { |
| 1051 if (is_open()) Goto(node->label()->join_for_break()); | 1043 if (is_open()) Goto(node->label()->join_for_break()); |
| 1052 exit_ = node->label()->join_for_break(); | 1044 exit_ = node->label()->join_for_break(); |
| 1053 } | 1045 } |
| 1054 // No continue label allowed. | 1046 // No continue label allowed. |
| 1055 ASSERT((node->label() == NULL) || | 1047 ASSERT((node->label() == NULL) || |
| 1056 (node->label()->join_for_continue() == NULL)); | 1048 (node->label()->join_for_continue() == NULL)); |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1381 node->label()->set_join_for_continue( | 1373 node->label()->set_join_for_continue( |
| 1382 new JoinEntryInstr(owner()->try_index())); | 1374 new JoinEntryInstr(owner()->try_index())); |
| 1383 } | 1375 } |
| 1384 jump_target = node->label()->join_for_continue(); | 1376 jump_target = node->label()->join_for_continue(); |
| 1385 } | 1377 } |
| 1386 Goto(jump_target); | 1378 Goto(jump_target); |
| 1387 } | 1379 } |
| 1388 | 1380 |
| 1389 | 1381 |
| 1390 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { | 1382 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { |
| 1391 InlineBailout("EffectGraphVisitor::VisitArgumentListNode"); | |
| 1392 UNREACHABLE(); | 1383 UNREACHABLE(); |
| 1393 } | 1384 } |
| 1394 | 1385 |
| 1395 | 1386 |
| 1396 void EffectGraphVisitor::VisitArgumentDefinitionTestNode( | 1387 void EffectGraphVisitor::VisitArgumentDefinitionTestNode( |
| 1397 ArgumentDefinitionTestNode* node) { | 1388 ArgumentDefinitionTestNode* node) { |
| 1398 Definition* load = BuildLoadLocal(node->saved_arguments_descriptor()); | 1389 Definition* load = BuildLoadLocal(node->saved_arguments_descriptor()); |
| 1399 Value* arguments_descriptor = Bind(load); | 1390 Value* arguments_descriptor = Bind(load); |
| 1400 ArgumentDefinitionTestInstr* arg_def_test = | 1391 ArgumentDefinitionTestInstr* arg_def_test = |
| 1401 new ArgumentDefinitionTestInstr(node, arguments_descriptor); | 1392 new ArgumentDefinitionTestInstr(node, arguments_descriptor); |
| 1402 ReturnDefinition(arg_def_test); | 1393 ReturnDefinition(arg_def_test); |
| 1403 } | 1394 } |
| 1404 | 1395 |
| 1405 | 1396 |
| 1406 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { | 1397 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { |
| 1407 InlineBailout("EffectGraphVisitor::VisitArrayNode"); | |
| 1408 // Translate the array elements and collect their values. | 1398 // Translate the array elements and collect their values. |
| 1409 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1399 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1410 new ZoneGrowableArray<PushArgumentInstr*>(node->length()); | 1400 new ZoneGrowableArray<PushArgumentInstr*>(node->length()); |
| 1411 for (int i = 0; i < node->length(); ++i) { | 1401 for (int i = 0; i < node->length(); ++i) { |
| 1412 ValueGraphVisitor for_value(owner(), temp_index()); | 1402 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1413 node->ElementAt(i)->Visit(&for_value); | 1403 node->ElementAt(i)->Visit(&for_value); |
| 1414 Append(for_value); | 1404 Append(for_value); |
| 1415 arguments->Add(PushArgument(for_value.value())); | 1405 arguments->Add(PushArgument(for_value.value())); |
| 1416 } | 1406 } |
| 1417 const AbstractTypeArguments& type_args = | 1407 const AbstractTypeArguments& type_args = |
| 1418 AbstractTypeArguments::ZoneHandle(node->type().arguments()); | 1408 AbstractTypeArguments::ZoneHandle(node->type().arguments()); |
| 1419 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), | 1409 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), |
| 1420 type_args); | 1410 type_args); |
| 1421 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), | 1411 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), |
| 1422 arguments, | 1412 arguments, |
| 1423 node->type(), | 1413 node->type(), |
| 1424 element_type); | 1414 element_type); |
| 1425 ReturnDefinition(create); | 1415 ReturnDefinition(create); |
| 1426 } | 1416 } |
| 1427 | 1417 |
| 1428 | 1418 |
| 1429 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { | 1419 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { |
| 1430 InlineBailout("EffectGraphVisitor::VisitClosureNode"); | |
| 1431 const Function& function = node->function(); | 1420 const Function& function = node->function(); |
| 1432 | 1421 |
| 1433 Value* receiver = NULL; | 1422 Value* receiver = NULL; |
| 1434 if (function.IsNonImplicitClosureFunction()) { | 1423 if (function.IsNonImplicitClosureFunction()) { |
| 1435 // The context scope may have already been set by the non-optimizing | 1424 // The context scope may have already been set by the non-optimizing |
| 1436 // compiler. If it was not, set it here. | 1425 // compiler. If it was not, set it here. |
| 1437 if (function.context_scope() == ContextScope::null()) { | 1426 if (function.context_scope() == ContextScope::null()) { |
| 1438 // TODO(regis): Why are we not doing this in the parser? | 1427 // TODO(regis): Why are we not doing this in the parser? |
| 1439 const ContextScope& context_scope = ContextScope::ZoneHandle( | 1428 const ContextScope& context_scope = ContextScope::ZoneHandle( |
| 1440 node->scope()->PreserveOuterScope(owner()->context_level())); | 1429 node->scope()->PreserveOuterScope(owner()->context_level())); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1471 } | 1460 } |
| 1472 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments); | 1461 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments); |
| 1473 arguments->Add(push_type_arguments); | 1462 arguments->Add(push_type_arguments); |
| 1474 ReturnDefinition(new CreateClosureInstr(node, arguments)); | 1463 ReturnDefinition(new CreateClosureInstr(node, arguments)); |
| 1475 } | 1464 } |
| 1476 | 1465 |
| 1477 | 1466 |
| 1478 void EffectGraphVisitor::TranslateArgumentList( | 1467 void EffectGraphVisitor::TranslateArgumentList( |
| 1479 const ArgumentListNode& node, | 1468 const ArgumentListNode& node, |
| 1480 ZoneGrowableArray<Value*>* values) { | 1469 ZoneGrowableArray<Value*>* values) { |
| 1481 InlineBailout("EffectGraphVisitor::TranslateArgumentList"); | |
| 1482 for (intptr_t i = 0; i < node.length(); ++i) { | 1470 for (intptr_t i = 0; i < node.length(); ++i) { |
| 1483 ValueGraphVisitor for_argument(owner(), temp_index()); | 1471 ValueGraphVisitor for_argument(owner(), temp_index()); |
| 1484 node.NodeAt(i)->Visit(&for_argument); | 1472 node.NodeAt(i)->Visit(&for_argument); |
| 1485 Append(for_argument); | 1473 Append(for_argument); |
| 1486 values->Add(for_argument.value()); | 1474 values->Add(for_argument.value()); |
| 1487 } | 1475 } |
| 1488 } | 1476 } |
| 1489 | 1477 |
| 1490 | 1478 |
| 1491 void EffectGraphVisitor::BuildPushArguments( | 1479 void EffectGraphVisitor::BuildPushArguments( |
| 1492 const ArgumentListNode& node, | 1480 const ArgumentListNode& node, |
| 1493 ZoneGrowableArray<PushArgumentInstr*>* values) { | 1481 ZoneGrowableArray<PushArgumentInstr*>* values) { |
| 1494 InlineBailout("EffectGraphVisitor::BuildPushArguments"); | |
| 1495 for (intptr_t i = 0; i < node.length(); ++i) { | 1482 for (intptr_t i = 0; i < node.length(); ++i) { |
| 1496 ValueGraphVisitor for_argument(owner(), temp_index()); | 1483 ValueGraphVisitor for_argument(owner(), temp_index()); |
| 1497 node.NodeAt(i)->Visit(&for_argument); | 1484 node.NodeAt(i)->Visit(&for_argument); |
| 1498 Append(for_argument); | 1485 Append(for_argument); |
| 1499 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); | 1486 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); |
| 1500 values->Add(push_arg); | 1487 values->Add(push_arg); |
| 1501 } | 1488 } |
| 1502 } | 1489 } |
| 1503 | 1490 |
| 1504 | 1491 |
| 1505 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { | 1492 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { |
| 1506 InlineBailout("EffectGraphVisitor::VisitInstanceCallNode"); | 1493 InlineBailout("EffectGraphVisitor::VisitInstanceCallNode (deopt)"); |
| 1507 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1494 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1508 node->receiver()->Visit(&for_receiver); | 1495 node->receiver()->Visit(&for_receiver); |
| 1509 Append(for_receiver); | 1496 Append(for_receiver); |
| 1510 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 1497 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 1511 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1498 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1512 new ZoneGrowableArray<PushArgumentInstr*>( | 1499 new ZoneGrowableArray<PushArgumentInstr*>( |
| 1513 node->arguments()->length() + 1); | 1500 node->arguments()->length() + 1); |
| 1514 arguments->Add(push_receiver); | 1501 arguments->Add(push_receiver); |
| 1515 | 1502 |
| 1516 BuildPushArguments(*node->arguments(), arguments); | 1503 BuildPushArguments(*node->arguments(), arguments); |
| 1517 InstanceCallInstr* call = new InstanceCallInstr( | 1504 InstanceCallInstr* call = new InstanceCallInstr( |
| 1518 node->token_pos(), | 1505 node->token_pos(), |
| 1519 node->function_name(), Token::kILLEGAL, arguments, | 1506 node->function_name(), Token::kILLEGAL, arguments, |
| 1520 node->arguments()->names(), 1); | 1507 node->arguments()->names(), 1); |
| 1521 ReturnDefinition(call); | 1508 ReturnDefinition(call); |
| 1522 } | 1509 } |
| 1523 | 1510 |
| 1524 | 1511 |
| 1525 // <Expression> ::= StaticCall { function: Function | 1512 // <Expression> ::= StaticCall { function: Function |
| 1526 // arguments: <ArgumentList> } | 1513 // arguments: <ArgumentList> } |
| 1527 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { | 1514 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { |
| 1528 InlineBailout("EffectGraphVisitor::VisitStaticCallNode"); | 1515 InlineBailout("EffectGraphVisitor::VisitStaticCallNode (deopt)"); |
| 1529 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1516 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1530 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 1517 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 1531 BuildPushArguments(*node->arguments(), arguments); | 1518 BuildPushArguments(*node->arguments(), arguments); |
| 1532 StaticCallInstr* call = | 1519 StaticCallInstr* call = |
| 1533 new StaticCallInstr(node->token_pos(), | 1520 new StaticCallInstr(node->token_pos(), |
| 1534 node->function(), | 1521 node->function(), |
| 1535 node->arguments()->names(), | 1522 node->arguments()->names(), |
| 1536 arguments); | 1523 arguments); |
| 1537 ReturnDefinition(call); | 1524 ReturnDefinition(call); |
| 1538 } | 1525 } |
| 1539 | 1526 |
| 1540 | 1527 |
| 1541 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall( | 1528 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall( |
| 1542 ClosureCallNode* node) { | 1529 ClosureCallNode* node) { |
| 1543 InlineBailout("EffectGraphVisitor::BuildClosureCall"); | 1530 InlineBailout("EffectGraphVisitor::BuildClosureCall (deopt)"); |
| 1544 ValueGraphVisitor for_closure(owner(), temp_index()); | 1531 ValueGraphVisitor for_closure(owner(), temp_index()); |
| 1545 node->closure()->Visit(&for_closure); | 1532 node->closure()->Visit(&for_closure); |
| 1546 Append(for_closure); | 1533 Append(for_closure); |
| 1547 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); | 1534 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); |
| 1548 | 1535 |
| 1549 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1536 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1550 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 1537 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 1551 arguments->Add(push_closure); | 1538 arguments->Add(push_closure); |
| 1552 BuildPushArguments(*node->arguments(), arguments); | 1539 BuildPushArguments(*node->arguments(), arguments); |
| 1553 | 1540 |
| 1554 // Save context around the call. | 1541 // Save context around the call. |
| 1555 BuildStoreContext(*owner()->parsed_function().expression_temp_var()); | 1542 BuildStoreContext(*owner()->parsed_function().expression_temp_var()); |
| 1556 return new ClosureCallInstr(node, arguments); | 1543 return new ClosureCallInstr(node, arguments); |
| 1557 } | 1544 } |
| 1558 | 1545 |
| 1559 | 1546 |
| 1560 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 1547 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 1561 InlineBailout("EffectGraphVisitor::VisitClosureCallNode"); | |
| 1562 Do(BuildClosureCall(node)); | 1548 Do(BuildClosureCall(node)); |
| 1563 // Restore context from saved location. | 1549 // Restore context from saved location. |
| 1564 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); | 1550 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); |
| 1565 } | 1551 } |
| 1566 | 1552 |
| 1567 | 1553 |
| 1568 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 1554 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 1569 InlineBailout("ValueGraphVisitor::VisitClosureCallNode"); | |
| 1570 Value* result = Bind(BuildClosureCall(node)); | 1555 Value* result = Bind(BuildClosureCall(node)); |
| 1571 // Restore context from temp. | 1556 // Restore context from temp. |
| 1572 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); | 1557 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); |
| 1573 ReturnValue(result); | 1558 ReturnValue(result); |
| 1574 } | 1559 } |
| 1575 | 1560 |
| 1576 | 1561 |
| 1577 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { | 1562 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { |
| 1578 InlineBailout("EffectGraphVisitor::VisitCloneContextNode"); | 1563 InlineBailout("EffectGraphVisitor::VisitCloneContextNode (deopt)"); |
| 1579 Value* context = Bind(new CurrentContextInstr()); | 1564 Value* context = Bind(new CurrentContextInstr()); |
| 1580 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context)); | 1565 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context)); |
| 1581 ReturnDefinition(new StoreContextInstr(clone)); | 1566 ReturnDefinition(new StoreContextInstr(clone)); |
| 1582 } | 1567 } |
| 1583 | 1568 |
| 1584 | 1569 |
| 1585 Value* EffectGraphVisitor::BuildObjectAllocation( | 1570 Value* EffectGraphVisitor::BuildObjectAllocation( |
| 1586 ConstructorCallNode* node) { | 1571 ConstructorCallNode* node) { |
| 1587 InlineBailout("EffectGraphVisitor::BuildObjectAllocation"); | |
| 1588 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); | 1572 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); |
| 1589 const bool requires_type_arguments = cls.HasTypeArguments(); | 1573 const bool requires_type_arguments = cls.HasTypeArguments(); |
| 1590 | 1574 |
| 1591 // In checked mode, if the type arguments are uninstantiated, they may need to | 1575 // In checked mode, if the type arguments are uninstantiated, they may need to |
| 1592 // be checked against declared bounds at run time. | 1576 // be checked against declared bounds at run time. |
| 1593 Definition* allocate_comp = NULL; | 1577 Definition* allocate_comp = NULL; |
| 1594 if (FLAG_enable_type_checks && | 1578 if (FLAG_enable_type_checks && |
| 1595 requires_type_arguments && | 1579 requires_type_arguments && |
| 1596 !node->type_arguments().IsNull() && | 1580 !node->type_arguments().IsNull() && |
| 1597 !node->type_arguments().IsInstantiated() && | 1581 !node->type_arguments().IsInstantiated() && |
| 1598 !node->type_arguments().IsWithinBoundsOf(cls, | 1582 !node->type_arguments().IsWithinBoundsOf(cls, |
| 1599 node->type_arguments(), | 1583 node->type_arguments(), |
| 1600 NULL)) { | 1584 NULL)) { |
| 1601 Value* type_arguments = NULL; | 1585 Value* type_arguments = NULL; |
| 1602 Value* instantiator = NULL; | 1586 Value* instantiator = NULL; |
| 1603 BuildConstructorTypeArguments(node, &type_arguments, &instantiator, NULL); | 1587 BuildConstructorTypeArguments(node, &type_arguments, &instantiator, NULL); |
| 1604 | 1588 |
| 1605 // The uninstantiated type arguments cannot be verified to be within their | 1589 // The uninstantiated type arguments cannot be verified to be within their |
| 1606 // bounds at compile time, so verify them at runtime. | 1590 // bounds at compile time, so verify them at runtime. |
| 1607 // Although the type arguments may be uninstantiated at compile time, they | 1591 // Although the type arguments may be uninstantiated at compile time, they |
| 1608 // may represent the identity vector and may be replaced by the instantiated | 1592 // may represent the identity vector and may be replaced by the instantiated |
| 1609 // type arguments of the instantiator at run time. | 1593 // type arguments of the instantiator at run time. |
| 1594 InlineBailout("EffectGraphVisitor::BuildObjectAllocation (deopt)"); |
| 1610 allocate_comp = new AllocateObjectWithBoundsCheckInstr(node, | 1595 allocate_comp = new AllocateObjectWithBoundsCheckInstr(node, |
| 1611 type_arguments, | 1596 type_arguments, |
| 1612 instantiator); | 1597 instantiator); |
| 1613 } else { | 1598 } else { |
| 1614 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = | 1599 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = |
| 1615 new ZoneGrowableArray<PushArgumentInstr*>(); | 1600 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 1616 | 1601 |
| 1617 if (requires_type_arguments) { | 1602 if (requires_type_arguments) { |
| 1618 BuildConstructorTypeArguments(node, NULL, NULL, allocate_arguments); | 1603 BuildConstructorTypeArguments(node, NULL, NULL, allocate_arguments); |
| 1619 } | 1604 } |
| 1620 | 1605 |
| 1621 allocate_comp = new AllocateObjectInstr(node, allocate_arguments); | 1606 allocate_comp = new AllocateObjectInstr(node, allocate_arguments); |
| 1622 } | 1607 } |
| 1623 return Bind(allocate_comp); | 1608 return Bind(allocate_comp); |
| 1624 } | 1609 } |
| 1625 | 1610 |
| 1626 | 1611 |
| 1627 void EffectGraphVisitor::BuildConstructorCall( | 1612 void EffectGraphVisitor::BuildConstructorCall( |
| 1628 ConstructorCallNode* node, | 1613 ConstructorCallNode* node, |
| 1629 PushArgumentInstr* push_alloc_value) { | 1614 PushArgumentInstr* push_alloc_value) { |
| 1630 InlineBailout("EffectGraphVisitor::BuildConstructorCall"); | 1615 InlineBailout("EffectGraphVisitor::BuildConstructorCall (deopt)"); |
| 1631 Value* ctor_arg = Bind( | 1616 Value* ctor_arg = Bind( |
| 1632 new ConstantInstr(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); | 1617 new ConstantInstr(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); |
| 1633 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); | 1618 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); |
| 1634 | 1619 |
| 1635 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1620 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1636 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1621 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1637 arguments->Add(push_alloc_value); | 1622 arguments->Add(push_alloc_value); |
| 1638 arguments->Add(push_ctor_arg); | 1623 arguments->Add(push_ctor_arg); |
| 1639 | 1624 |
| 1640 BuildPushArguments(*node->arguments(), arguments); | 1625 BuildPushArguments(*node->arguments(), arguments); |
| 1641 Do(new StaticCallInstr(node->token_pos(), | 1626 Do(new StaticCallInstr(node->token_pos(), |
| 1642 node->constructor(), | 1627 node->constructor(), |
| 1643 node->arguments()->names(), | 1628 node->arguments()->names(), |
| 1644 arguments)); | 1629 arguments)); |
| 1645 } | 1630 } |
| 1646 | 1631 |
| 1647 | 1632 |
| 1648 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { | 1633 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| 1649 InlineBailout("EffectGraphVisitor::VisitConstructorCallNode"); | |
| 1650 if (node->constructor().IsFactory()) { | 1634 if (node->constructor().IsFactory()) { |
| 1635 InlineBailout("EffectGraphVisitor::VisitConstructorCallNode (deopt)"); |
| 1651 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1636 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1652 new ZoneGrowableArray<PushArgumentInstr*>(); | 1637 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 1653 PushArgumentInstr* push_type_arguments = PushArgument( | 1638 PushArgumentInstr* push_type_arguments = PushArgument( |
| 1654 BuildInstantiatedTypeArguments(node->token_pos(), | 1639 BuildInstantiatedTypeArguments(node->token_pos(), |
| 1655 node->type_arguments())); | 1640 node->type_arguments())); |
| 1656 arguments->Add(push_type_arguments); | 1641 arguments->Add(push_type_arguments); |
| 1657 ASSERT(arguments->length() == 1); | 1642 ASSERT(arguments->length() == 1); |
| 1658 BuildPushArguments(*node->arguments(), arguments); | 1643 BuildPushArguments(*node->arguments(), arguments); |
| 1659 StaticCallInstr* call = | 1644 StaticCallInstr* call = |
| 1660 new StaticCallInstr(node->token_pos(), | 1645 new StaticCallInstr(node->token_pos(), |
| 1661 node->constructor(), | 1646 node->constructor(), |
| 1662 node->arguments()->names(), | 1647 node->arguments()->names(), |
| 1663 arguments); | 1648 arguments); |
| 1664 ReturnDefinition(call); | 1649 ReturnDefinition(call); |
| 1665 return; | 1650 return; |
| 1666 } | 1651 } |
| 1667 // t_n contains the allocated and initialized object. | 1652 // t_n contains the allocated and initialized object. |
| 1668 // t_n <- AllocateObject(class) | 1653 // t_n <- AllocateObject(class) |
| 1669 // t_n+1 <- ctor-arg | 1654 // t_n+1 <- ctor-arg |
| 1670 // t_n+2... <- constructor arguments start here | 1655 // t_n+2... <- constructor arguments start here |
| 1671 // StaticCall(constructor, t_n+1, t_n+2, ...) | 1656 // StaticCall(constructor, t_n+1, t_n+2, ...) |
| 1672 // No need to preserve allocated value (simpler than in ValueGraphVisitor). | 1657 // No need to preserve allocated value (simpler than in ValueGraphVisitor). |
| 1673 Value* allocated_value = BuildObjectAllocation(node); | 1658 Value* allocated_value = BuildObjectAllocation(node); |
| 1674 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); | 1659 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); |
| 1675 BuildConstructorCall(node, push_allocated_value); | 1660 BuildConstructorCall(node, push_allocated_value); |
| 1676 } | 1661 } |
| 1677 | 1662 |
| 1678 | 1663 |
| 1679 Value* EffectGraphVisitor::BuildInstantiator() { | 1664 Value* EffectGraphVisitor::BuildInstantiator() { |
| 1680 InlineBailout("EffectGraphVisitor::BuildInstantiator"); | |
| 1681 const Class& instantiator_class = Class::Handle( | 1665 const Class& instantiator_class = Class::Handle( |
| 1682 owner()->parsed_function().function().Owner()); | 1666 owner()->parsed_function().function().Owner()); |
| 1683 if (instantiator_class.NumTypeParameters() == 0) { | 1667 if (instantiator_class.NumTypeParameters() == 0) { |
| 1684 return NULL; | 1668 return NULL; |
| 1685 } | 1669 } |
| 1686 Function& outer_function = | 1670 Function& outer_function = |
| 1687 Function::Handle(owner()->parsed_function().function().raw()); | 1671 Function::Handle(owner()->parsed_function().function().raw()); |
| 1688 while (outer_function.IsLocalFunction()) { | 1672 while (outer_function.IsLocalFunction()) { |
| 1689 outer_function = outer_function.parent_function(); | 1673 outer_function = outer_function.parent_function(); |
| 1690 } | 1674 } |
| 1691 if (outer_function.IsFactory()) { | 1675 if (outer_function.IsFactory()) { |
| 1692 return NULL; | 1676 return NULL; |
| 1693 } | 1677 } |
| 1694 | 1678 |
| 1695 ASSERT(owner()->parsed_function().instantiator() != NULL); | 1679 ASSERT(owner()->parsed_function().instantiator() != NULL); |
| 1696 ValueGraphVisitor for_instantiator(owner(), temp_index()); | 1680 ValueGraphVisitor for_instantiator(owner(), temp_index()); |
| 1697 owner()->parsed_function().instantiator()->Visit(&for_instantiator); | 1681 owner()->parsed_function().instantiator()->Visit(&for_instantiator); |
| 1698 Append(for_instantiator); | 1682 Append(for_instantiator); |
| 1699 return for_instantiator.value(); | 1683 return for_instantiator.value(); |
| 1700 } | 1684 } |
| 1701 | 1685 |
| 1702 | 1686 |
| 1703 // 'expression_temp_var' may not be used inside this method if 'instantiator' | 1687 // 'expression_temp_var' may not be used inside this method if 'instantiator' |
| 1704 // is not NULL. | 1688 // is not NULL. |
| 1705 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( | 1689 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( |
| 1706 intptr_t token_pos, Value* instantiator) { | 1690 intptr_t token_pos, Value* instantiator) { |
| 1707 InlineBailout("EffectGraphVisitor::BuildInstantiatorTypeArguments"); | |
| 1708 const Class& instantiator_class = Class::Handle( | 1691 const Class& instantiator_class = Class::Handle( |
| 1709 owner()->parsed_function().function().Owner()); | 1692 owner()->parsed_function().function().Owner()); |
| 1710 if (instantiator_class.NumTypeParameters() == 0) { | 1693 if (instantiator_class.NumTypeParameters() == 0) { |
| 1711 // The type arguments are compile time constants. | 1694 // The type arguments are compile time constants. |
| 1712 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); | 1695 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); |
| 1713 // Type is temporary. Only its type arguments are preserved. | 1696 // Type is temporary. Only its type arguments are preserved. |
| 1714 Type& type = Type::Handle( | 1697 Type& type = Type::Handle( |
| 1715 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); | 1698 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); |
| 1716 type ^= ClassFinalizer::FinalizeType( | 1699 type ^= ClassFinalizer::FinalizeType( |
| 1717 instantiator_class, type, ClassFinalizer::kFinalize); | 1700 instantiator_class, type, ClassFinalizer::kFinalize); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1738 instantiator = BuildInstantiator(); | 1721 instantiator = BuildInstantiator(); |
| 1739 } | 1722 } |
| 1740 // The instantiator is the receiver of the caller, which is not a factory. | 1723 // The instantiator is the receiver of the caller, which is not a factory. |
| 1741 // The receiver cannot be null; extract its AbstractTypeArguments object. | 1724 // The receiver cannot be null; extract its AbstractTypeArguments object. |
| 1742 // Note that in the factory case, the instantiator is the first parameter | 1725 // Note that in the factory case, the instantiator is the first parameter |
| 1743 // of the factory, i.e. already an AbstractTypeArguments object. | 1726 // of the factory, i.e. already an AbstractTypeArguments object. |
| 1744 intptr_t type_arguments_instance_field_offset = | 1727 intptr_t type_arguments_instance_field_offset = |
| 1745 instantiator_class.type_arguments_instance_field_offset(); | 1728 instantiator_class.type_arguments_instance_field_offset(); |
| 1746 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments); | 1729 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments); |
| 1747 | 1730 |
| 1731 InlineBailout("EffectGraphVisitor::BuildInstantiatorTypeArguments (deopt)"); |
| 1748 return Bind(new LoadVMFieldInstr( | 1732 return Bind(new LoadVMFieldInstr( |
| 1749 instantiator, | 1733 instantiator, |
| 1750 type_arguments_instance_field_offset, | 1734 type_arguments_instance_field_offset, |
| 1751 Type::ZoneHandle())); // Not an instance, no type. | 1735 Type::ZoneHandle())); // Not an instance, no type. |
| 1752 } | 1736 } |
| 1753 | 1737 |
| 1754 | 1738 |
| 1755 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( | 1739 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( |
| 1756 intptr_t token_pos, | 1740 intptr_t token_pos, |
| 1757 const AbstractTypeArguments& type_arguments) { | 1741 const AbstractTypeArguments& type_arguments) { |
| 1758 InlineBailout("EffectGraphVisitor::BuildInstantiatedTypeArguments"); | |
| 1759 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { | 1742 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { |
| 1760 return Bind(new ConstantInstr(type_arguments)); | 1743 return Bind(new ConstantInstr(type_arguments)); |
| 1761 } | 1744 } |
| 1745 InlineBailout("EffectGraphVisitor::BuildInstantiatedTypeArguments (deopt)"); |
| 1762 // The type arguments are uninstantiated. | 1746 // The type arguments are uninstantiated. |
| 1763 Value* instantiator_value = | 1747 Value* instantiator_value = |
| 1764 BuildInstantiatorTypeArguments(token_pos, NULL); | 1748 BuildInstantiatorTypeArguments(token_pos, NULL); |
| 1765 return Bind(new InstantiateTypeArgumentsInstr(token_pos, | 1749 return Bind(new InstantiateTypeArgumentsInstr(token_pos, |
| 1766 type_arguments, | 1750 type_arguments, |
| 1767 instantiator_value)); | 1751 instantiator_value)); |
| 1768 } | 1752 } |
| 1769 | 1753 |
| 1770 | 1754 |
| 1771 void EffectGraphVisitor::BuildConstructorTypeArguments( | 1755 void EffectGraphVisitor::BuildConstructorTypeArguments( |
| 1772 ConstructorCallNode* node, | 1756 ConstructorCallNode* node, |
| 1773 Value** type_arguments, | 1757 Value** type_arguments, |
| 1774 Value** instantiator, | 1758 Value** instantiator, |
| 1775 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) { | 1759 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) { |
| 1776 InlineBailout("EffectGraphVisitor::BuildConstructorTypeArguments"); | |
| 1777 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); | 1760 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); |
| 1778 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); | 1761 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); |
| 1779 if (node->type_arguments().IsNull() || | 1762 if (node->type_arguments().IsNull() || |
| 1780 node->type_arguments().IsInstantiated()) { | 1763 node->type_arguments().IsInstantiated()) { |
| 1781 Value* type_arguments_val = Bind(new ConstantInstr(node->type_arguments())); | 1764 Value* type_arguments_val = Bind(new ConstantInstr(node->type_arguments())); |
| 1782 if (call_arguments != NULL) { | 1765 if (call_arguments != NULL) { |
| 1783 ASSERT(type_arguments == NULL); | 1766 ASSERT(type_arguments == NULL); |
| 1784 call_arguments->Add(PushArgument(type_arguments_val)); | 1767 call_arguments->Add(PushArgument(type_arguments_val)); |
| 1785 } else { | 1768 } else { |
| 1786 ASSERT(type_arguments != NULL); | 1769 ASSERT(type_arguments != NULL); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1845 ASSERT(instantiator == NULL); | 1828 ASSERT(instantiator == NULL); |
| 1846 call_arguments->Add(PushArgument(instantiator_val)); | 1829 call_arguments->Add(PushArgument(instantiator_val)); |
| 1847 } else { | 1830 } else { |
| 1848 ASSERT(instantiator != NULL); | 1831 ASSERT(instantiator != NULL); |
| 1849 *instantiator = instantiator_val; | 1832 *instantiator = instantiator_val; |
| 1850 } | 1833 } |
| 1851 } | 1834 } |
| 1852 | 1835 |
| 1853 | 1836 |
| 1854 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { | 1837 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| 1855 InlineBailout("ValueGraphVisitor::VisitConstructorCallNode"); | |
| 1856 if (node->constructor().IsFactory()) { | 1838 if (node->constructor().IsFactory()) { |
| 1857 EffectGraphVisitor::VisitConstructorCallNode(node); | 1839 EffectGraphVisitor::VisitConstructorCallNode(node); |
| 1858 return; | 1840 return; |
| 1859 } | 1841 } |
| 1860 | 1842 |
| 1861 // t_n contains the allocated and initialized object. | 1843 // t_n contains the allocated and initialized object. |
| 1862 // t_n <- AllocateObject(class) | 1844 // t_n <- AllocateObject(class) |
| 1863 // t_n <- StoreLocal(temp, t_n); | 1845 // t_n <- StoreLocal(temp, t_n); |
| 1864 // t_n+1 <- ctor-arg | 1846 // t_n+1 <- ctor-arg |
| 1865 // t_n+2... <- constructor arguments start here | 1847 // t_n+2... <- constructor arguments start here |
| 1866 // StaticCall(constructor, t_n, t_n+1, ...) | 1848 // StaticCall(constructor, t_n, t_n+1, ...) |
| 1867 // tn <- LoadLocal(temp) | 1849 // tn <- LoadLocal(temp) |
| 1868 | 1850 |
| 1869 Value* allocate = BuildObjectAllocation(node); | 1851 Value* allocate = BuildObjectAllocation(node); |
| 1870 Definition* store_allocated = BuildStoreLocal( | 1852 Definition* store_allocated = BuildStoreLocal( |
| 1871 node->allocated_object_var(), | 1853 node->allocated_object_var(), |
| 1872 allocate); | 1854 allocate); |
| 1873 Value* allocated_value = Bind(store_allocated); | 1855 Value* allocated_value = Bind(store_allocated); |
| 1874 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); | 1856 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); |
| 1875 BuildConstructorCall(node, push_allocated_value); | 1857 BuildConstructorCall(node, push_allocated_value); |
| 1876 Definition* load_allocated = BuildLoadLocal( | 1858 Definition* load_allocated = BuildLoadLocal( |
| 1877 node->allocated_object_var()); | 1859 node->allocated_object_var()); |
| 1878 allocated_value = Bind(load_allocated); | 1860 allocated_value = Bind(load_allocated); |
| 1879 ReturnValue(allocated_value); | 1861 ReturnValue(allocated_value); |
| 1880 } | 1862 } |
| 1881 | 1863 |
| 1882 | 1864 |
| 1883 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { | 1865 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { |
| 1884 InlineBailout("EffectGraphVisitor::VisitConstructorCallNode"); | 1866 InlineBailout("EffectGraphVisitor::VisitInstanceGetterNode (deopt)"); |
| 1885 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1867 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1886 node->receiver()->Visit(&for_receiver); | 1868 node->receiver()->Visit(&for_receiver); |
| 1887 Append(for_receiver); | 1869 Append(for_receiver); |
| 1888 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 1870 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 1889 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1871 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1890 new ZoneGrowableArray<PushArgumentInstr*>(1); | 1872 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 1891 arguments->Add(push_receiver); | 1873 arguments->Add(push_receiver); |
| 1892 const String& name = | 1874 const String& name = |
| 1893 String::ZoneHandle(Field::GetterSymbol(node->field_name())); | 1875 String::ZoneHandle(Field::GetterSymbol(node->field_name())); |
| 1894 InstanceCallInstr* call = new InstanceCallInstr( | 1876 InstanceCallInstr* call = new InstanceCallInstr( |
| 1895 node->token_pos(), name, Token::kGET, | 1877 node->token_pos(), name, Token::kGET, |
| 1896 arguments, Array::ZoneHandle(), 1); | 1878 arguments, Array::ZoneHandle(), 1); |
| 1897 ReturnDefinition(call); | 1879 ReturnDefinition(call); |
| 1898 } | 1880 } |
| 1899 | 1881 |
| 1900 | 1882 |
| 1901 void EffectGraphVisitor::BuildInstanceSetterArguments( | 1883 void EffectGraphVisitor::BuildInstanceSetterArguments( |
| 1902 InstanceSetterNode* node, | 1884 InstanceSetterNode* node, |
| 1903 ZoneGrowableArray<PushArgumentInstr*>* arguments, | 1885 ZoneGrowableArray<PushArgumentInstr*>* arguments, |
| 1904 bool result_is_needed) { | 1886 bool result_is_needed) { |
| 1905 InlineBailout("EffectGraphVisitor::BuildInstanceSetterArguments"); | |
| 1906 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1887 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1907 node->receiver()->Visit(&for_receiver); | 1888 node->receiver()->Visit(&for_receiver); |
| 1908 Append(for_receiver); | 1889 Append(for_receiver); |
| 1909 arguments->Add(PushArgument(for_receiver.value())); | 1890 arguments->Add(PushArgument(for_receiver.value())); |
| 1910 | 1891 |
| 1911 ValueGraphVisitor for_value(owner(), temp_index()); | 1892 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1912 node->value()->Visit(&for_value); | 1893 node->value()->Visit(&for_value); |
| 1913 Append(for_value); | 1894 Append(for_value); |
| 1914 | 1895 |
| 1915 Value* value = NULL; | 1896 Value* value = NULL; |
| 1916 if (result_is_needed) { | 1897 if (result_is_needed) { |
| 1917 value = Bind( | 1898 value = Bind( |
| 1918 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(), | 1899 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(), |
| 1919 for_value.value())); | 1900 for_value.value())); |
| 1920 } else { | 1901 } else { |
| 1921 value = for_value.value(); | 1902 value = for_value.value(); |
| 1922 } | 1903 } |
| 1923 arguments->Add(PushArgument(value)); | 1904 arguments->Add(PushArgument(value)); |
| 1924 } | 1905 } |
| 1925 | 1906 |
| 1926 | 1907 |
| 1927 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { | 1908 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| 1928 InlineBailout("EffectGraphVisitor::VisitInstanceSetterNode"); | 1909 InlineBailout("EffectGraphVisitor::VisitInstanceSetterNode (deopt)"); |
| 1929 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1910 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1930 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1911 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1931 BuildInstanceSetterArguments(node, arguments, false); // Value not used. | 1912 BuildInstanceSetterArguments(node, arguments, false); // Value not used. |
| 1932 const String& name = | 1913 const String& name = |
| 1933 String::ZoneHandle(Field::SetterSymbol(node->field_name())); | 1914 String::ZoneHandle(Field::SetterSymbol(node->field_name())); |
| 1934 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), | 1915 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), |
| 1935 name, | 1916 name, |
| 1936 Token::kSET, | 1917 Token::kSET, |
| 1937 arguments, | 1918 arguments, |
| 1938 Array::ZoneHandle(), | 1919 Array::ZoneHandle(), |
| 1939 1); // Checked arg count. | 1920 1); // Checked arg count. |
| 1940 ReturnDefinition(call); | 1921 ReturnDefinition(call); |
| 1941 } | 1922 } |
| 1942 | 1923 |
| 1943 | 1924 |
| 1944 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { | 1925 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| 1945 InlineBailout("ValueGraphVisitor::VisitInstanceSetterNode"); | 1926 InlineBailout("ValueGraphVisitor::VisitInstanceSetterNode (deopt)"); |
| 1946 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1927 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1947 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1928 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1948 BuildInstanceSetterArguments(node, arguments, true); // Value used. | 1929 BuildInstanceSetterArguments(node, arguments, true); // Value used. |
| 1949 const String& name = | 1930 const String& name = |
| 1950 String::ZoneHandle(Field::SetterSymbol(node->field_name())); | 1931 String::ZoneHandle(Field::SetterSymbol(node->field_name())); |
| 1951 Do(new InstanceCallInstr(node->token_pos(), | 1932 Do(new InstanceCallInstr(node->token_pos(), |
| 1952 name, | 1933 name, |
| 1953 Token::kSET, | 1934 Token::kSET, |
| 1954 arguments, | 1935 arguments, |
| 1955 Array::ZoneHandle(), | 1936 Array::ZoneHandle(), |
| 1956 1)); // Checked argument count. | 1937 1)); // Checked argument count. |
| 1957 ReturnDefinition( | 1938 ReturnDefinition( |
| 1958 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); | 1939 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); |
| 1959 } | 1940 } |
| 1960 | 1941 |
| 1961 | 1942 |
| 1962 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { | 1943 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { |
| 1963 InlineBailout("EffectGraphVisitor::VisitStaticGetterNode"); | 1944 InlineBailout("EffectGraphVisitor::VisitStaticGetterNode (deopt)"); |
| 1964 const String& getter_name = | 1945 const String& getter_name = |
| 1965 String::Handle(Field::GetterName(node->field_name())); | 1946 String::Handle(Field::GetterName(node->field_name())); |
| 1966 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1947 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1967 new ZoneGrowableArray<PushArgumentInstr*>(); | 1948 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 1968 Function& getter_function = Function::ZoneHandle(); | 1949 Function& getter_function = Function::ZoneHandle(); |
| 1969 if (node->is_super_getter()) { | 1950 if (node->is_super_getter()) { |
| 1970 // Statically resolved instance getter, i.e. "super getter". | 1951 // Statically resolved instance getter, i.e. "super getter". |
| 1971 getter_function = | 1952 getter_function = |
| 1972 Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); | 1953 Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); |
| 1973 ASSERT(!getter_function.IsNull()); | 1954 ASSERT(!getter_function.IsNull()); |
| 1974 ASSERT(node->receiver() != NULL); | 1955 ASSERT(node->receiver() != NULL); |
| 1975 ValueGraphVisitor receiver_value(owner(), temp_index()); | 1956 ValueGraphVisitor receiver_value(owner(), temp_index()); |
| 1976 node->receiver()->Visit(&receiver_value); | 1957 node->receiver()->Visit(&receiver_value); |
| 1977 Append(receiver_value); | 1958 Append(receiver_value); |
| 1978 arguments->Add(PushArgument(receiver_value.value())); | 1959 arguments->Add(PushArgument(receiver_value.value())); |
| 1979 } else { | 1960 } else { |
| 1980 getter_function = node->cls().LookupStaticFunction(getter_name); | 1961 getter_function = node->cls().LookupStaticFunction(getter_name); |
| 1981 ASSERT(!getter_function.IsNull()); | 1962 ASSERT(!getter_function.IsNull()); |
| 1982 } | 1963 } |
| 1983 StaticCallInstr* call = new StaticCallInstr(node->token_pos(), | 1964 StaticCallInstr* call = new StaticCallInstr(node->token_pos(), |
| 1984 getter_function, | 1965 getter_function, |
| 1985 Array::ZoneHandle(), // No names. | 1966 Array::ZoneHandle(), // No names. |
| 1986 arguments); | 1967 arguments); |
| 1987 ReturnDefinition(call); | 1968 ReturnDefinition(call); |
| 1988 } | 1969 } |
| 1989 | 1970 |
| 1990 | 1971 |
| 1991 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, | 1972 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, |
| 1992 bool result_is_needed) { | 1973 bool result_is_needed) { |
| 1993 InlineBailout("EffectGraphVisitor::BuildStaticSetter"); | 1974 InlineBailout("EffectGraphVisitor::VisitStaticSetter (deopt)"); |
| 1994 const String& setter_name = | 1975 const String& setter_name = |
| 1995 String::Handle(Field::SetterName(node->field_name())); | 1976 String::Handle(Field::SetterName(node->field_name())); |
| 1996 // A super setter is an instance setter whose setter function is | 1977 // A super setter is an instance setter whose setter function is |
| 1997 // resolved at compile time (in the caller instance getter's super class). | 1978 // resolved at compile time (in the caller instance getter's super class). |
| 1998 // Unlike a static getter, a super getter has a receiver parameter. | 1979 // Unlike a static getter, a super getter has a receiver parameter. |
| 1999 const bool is_super_setter = (node->receiver() != NULL); | 1980 const bool is_super_setter = (node->receiver() != NULL); |
| 2000 const Function& setter_function = | 1981 const Function& setter_function = |
| 2001 Function::ZoneHandle(is_super_setter | 1982 Function::ZoneHandle(is_super_setter |
| 2002 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name) | 1983 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name) |
| 2003 : node->cls().LookupStaticFunction(setter_name)); | 1984 : node->cls().LookupStaticFunction(setter_name)); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2033 Do(call); | 2014 Do(call); |
| 2034 ReturnDefinition( | 2015 ReturnDefinition( |
| 2035 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); | 2016 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); |
| 2036 } else { | 2017 } else { |
| 2037 ReturnDefinition(call); | 2018 ReturnDefinition(call); |
| 2038 } | 2019 } |
| 2039 } | 2020 } |
| 2040 | 2021 |
| 2041 | 2022 |
| 2042 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { | 2023 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { |
| 2043 InlineBailout("EffectGraphVisitor::VisitStaticSetterNode"); | |
| 2044 BuildStaticSetter(node, false); // Result not needed. | 2024 BuildStaticSetter(node, false); // Result not needed. |
| 2045 } | 2025 } |
| 2046 | 2026 |
| 2047 | 2027 |
| 2048 void ValueGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { | 2028 void ValueGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { |
| 2049 InlineBailout("ValueGraphVisitor::VisitStaticSetterNode"); | |
| 2050 BuildStaticSetter(node, true); // Result needed. | 2029 BuildStaticSetter(node, true); // Result needed. |
| 2051 } | 2030 } |
| 2052 | 2031 |
| 2053 | 2032 |
| 2054 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { | 2033 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { |
| 2055 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode"); | 2034 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode"); |
| 2056 NativeCallInstr* native_call = new NativeCallInstr(node); | 2035 NativeCallInstr* native_call = new NativeCallInstr(node); |
| 2057 ReturnDefinition(native_call); | 2036 ReturnDefinition(native_call); |
| 2058 } | 2037 } |
| 2059 | 2038 |
| 2060 | 2039 |
| 2061 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { | 2040 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { |
| 2062 InlineBailout("EffectGraphVisitor::VisitPrimaryNode"); | |
| 2063 // PrimaryNodes are temporary during parsing. | 2041 // PrimaryNodes are temporary during parsing. |
| 2064 UNREACHABLE(); | 2042 UNREACHABLE(); |
| 2065 } | 2043 } |
| 2066 | 2044 |
| 2067 | 2045 |
| 2068 // <Expression> ::= LoadLocal { local: LocalVariable } | 2046 // <Expression> ::= LoadLocal { local: LocalVariable } |
| 2069 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { | 2047 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| 2070 InlineBailout("EffectGraphVisitor::VisitLoadLocalNode"); | |
| 2071 if (node->HasPseudo()) { | 2048 if (node->HasPseudo()) { |
| 2072 EffectGraphVisitor for_pseudo(owner(), temp_index()); | 2049 EffectGraphVisitor for_pseudo(owner(), temp_index()); |
| 2073 node->pseudo()->Visit(&for_pseudo); | 2050 node->pseudo()->Visit(&for_pseudo); |
| 2074 Append(for_pseudo); | 2051 Append(for_pseudo); |
| 2075 } | 2052 } |
| 2076 } | 2053 } |
| 2077 | 2054 |
| 2078 | 2055 |
| 2079 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { | 2056 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| 2080 InlineBailout("ValueGraphVisitor::VisitLoadLocalNode"); | |
| 2081 EffectGraphVisitor::VisitLoadLocalNode(node); | 2057 EffectGraphVisitor::VisitLoadLocalNode(node); |
| 2082 Definition* load = BuildLoadLocal(node->local()); | 2058 Definition* load = BuildLoadLocal(node->local()); |
| 2083 ReturnDefinition(load); | 2059 ReturnDefinition(load); |
| 2084 } | 2060 } |
| 2085 | 2061 |
| 2086 | 2062 |
| 2087 // <Expression> ::= StoreLocal { local: LocalVariable | 2063 // <Expression> ::= StoreLocal { local: LocalVariable |
| 2088 // value: <Expression> } | 2064 // value: <Expression> } |
| 2089 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { | 2065 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| 2090 InlineBailout("EffectGraphVisitor::VisitStoreLocalNode"); | |
| 2091 ValueGraphVisitor for_value(owner(), temp_index()); | 2066 ValueGraphVisitor for_value(owner(), temp_index()); |
| 2092 node->value()->Visit(&for_value); | 2067 node->value()->Visit(&for_value); |
| 2093 Append(for_value); | 2068 Append(for_value); |
| 2094 Value* store_value = for_value.value(); | 2069 Value* store_value = for_value.value(); |
| 2095 if (FLAG_enable_type_checks) { | 2070 if (FLAG_enable_type_checks) { |
| 2096 store_value = BuildAssignableValue(node->value()->token_pos(), | 2071 store_value = BuildAssignableValue(node->value()->token_pos(), |
| 2097 store_value, | 2072 store_value, |
| 2098 node->local().type(), | 2073 node->local().type(), |
| 2099 node->local().name()); | 2074 node->local().name()); |
| 2100 } | 2075 } |
| 2101 Definition* store = BuildStoreLocal(node->local(), store_value); | 2076 Definition* store = BuildStoreLocal(node->local(), store_value); |
| 2102 ReturnDefinition(store); | 2077 ReturnDefinition(store); |
| 2103 } | 2078 } |
| 2104 | 2079 |
| 2105 | 2080 |
| 2106 void EffectGraphVisitor::VisitLoadInstanceFieldNode( | 2081 void EffectGraphVisitor::VisitLoadInstanceFieldNode( |
| 2107 LoadInstanceFieldNode* node) { | 2082 LoadInstanceFieldNode* node) { |
| 2108 InlineBailout("EffectGraphVisitor::VisitLoadInstanceFieldNode"); | |
| 2109 ValueGraphVisitor for_instance(owner(), temp_index()); | 2083 ValueGraphVisitor for_instance(owner(), temp_index()); |
| 2110 node->instance()->Visit(&for_instance); | 2084 node->instance()->Visit(&for_instance); |
| 2111 Append(for_instance); | 2085 Append(for_instance); |
| 2112 LoadInstanceFieldInstr* load = new LoadInstanceFieldInstr( | 2086 LoadInstanceFieldInstr* load = new LoadInstanceFieldInstr( |
| 2113 node->field(), for_instance.value()); | 2087 node->field(), for_instance.value()); |
| 2114 ReturnDefinition(load); | 2088 ReturnDefinition(load); |
| 2115 } | 2089 } |
| 2116 | 2090 |
| 2117 | 2091 |
| 2118 void EffectGraphVisitor::VisitStoreInstanceFieldNode( | 2092 void EffectGraphVisitor::VisitStoreInstanceFieldNode( |
| 2119 StoreInstanceFieldNode* node) { | 2093 StoreInstanceFieldNode* node) { |
| 2120 InlineBailout("EffectGraphVisitor::VisitStoreInstanceFieldNode"); | |
| 2121 ValueGraphVisitor for_instance(owner(), temp_index()); | 2094 ValueGraphVisitor for_instance(owner(), temp_index()); |
| 2122 node->instance()->Visit(&for_instance); | 2095 node->instance()->Visit(&for_instance); |
| 2123 Append(for_instance); | 2096 Append(for_instance); |
| 2124 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); | 2097 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); |
| 2125 node->value()->Visit(&for_value); | 2098 node->value()->Visit(&for_value); |
| 2126 Append(for_value); | 2099 Append(for_value); |
| 2127 Value* store_value = for_value.value(); | 2100 Value* store_value = for_value.value(); |
| 2128 if (FLAG_enable_type_checks) { | 2101 if (FLAG_enable_type_checks) { |
| 2129 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 2102 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| 2130 const String& dst_name = String::ZoneHandle(node->field().name()); | 2103 const String& dst_name = String::ZoneHandle(node->field().name()); |
| 2131 store_value = BuildAssignableValue(node->value()->token_pos(), | 2104 store_value = BuildAssignableValue(node->value()->token_pos(), |
| 2132 store_value, | 2105 store_value, |
| 2133 type, | 2106 type, |
| 2134 dst_name); | 2107 dst_name); |
| 2135 } | 2108 } |
| 2136 StoreInstanceFieldInstr* store = new StoreInstanceFieldInstr( | 2109 StoreInstanceFieldInstr* store = new StoreInstanceFieldInstr( |
| 2137 node->field(), for_instance.value(), store_value); | 2110 node->field(), for_instance.value(), store_value); |
| 2138 ReturnDefinition(store); | 2111 ReturnDefinition(store); |
| 2139 } | 2112 } |
| 2140 | 2113 |
| 2141 | 2114 |
| 2142 // StoreInstanceFieldNode does not return result. | 2115 // StoreInstanceFieldNode does not return result. |
| 2143 void ValueGraphVisitor::VisitStoreInstanceFieldNode( | 2116 void ValueGraphVisitor::VisitStoreInstanceFieldNode( |
| 2144 StoreInstanceFieldNode* node) { | 2117 StoreInstanceFieldNode* node) { |
| 2145 InlineBailout("ValueGraphVisitor::VisitStoreInstanceFieldNode"); | |
| 2146 UNIMPLEMENTED(); | 2118 UNIMPLEMENTED(); |
| 2147 } | 2119 } |
| 2148 | 2120 |
| 2149 | 2121 |
| 2150 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { | 2122 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { |
| 2151 InlineBailout("EffectGraphVisitor::VisitLoadStaticFieldNode"); | |
| 2152 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(node->field()); | 2123 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(node->field()); |
| 2153 ReturnDefinition(load); | 2124 ReturnDefinition(load); |
| 2154 } | 2125 } |
| 2155 | 2126 |
| 2156 | 2127 |
| 2157 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { | 2128 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
| 2158 InlineBailout("EffectGraphVisitor::VisitStoreStaticFieldNode"); | |
| 2159 ValueGraphVisitor for_value(owner(), temp_index()); | 2129 ValueGraphVisitor for_value(owner(), temp_index()); |
| 2160 node->value()->Visit(&for_value); | 2130 node->value()->Visit(&for_value); |
| 2161 Append(for_value); | 2131 Append(for_value); |
| 2162 Value* store_value = for_value.value(); | 2132 Value* store_value = for_value.value(); |
| 2163 if (FLAG_enable_type_checks) { | 2133 if (FLAG_enable_type_checks) { |
| 2164 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 2134 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| 2165 const String& dst_name = String::ZoneHandle(node->field().name()); | 2135 const String& dst_name = String::ZoneHandle(node->field().name()); |
| 2166 store_value = BuildAssignableValue(node->value()->token_pos(), | 2136 store_value = BuildAssignableValue(node->value()->token_pos(), |
| 2167 store_value, | 2137 store_value, |
| 2168 type, | 2138 type, |
| 2169 dst_name); | 2139 dst_name); |
| 2170 } | 2140 } |
| 2171 StoreStaticFieldInstr* store = | 2141 StoreStaticFieldInstr* store = |
| 2172 new StoreStaticFieldInstr(node->field(), store_value); | 2142 new StoreStaticFieldInstr(node->field(), store_value); |
| 2173 ReturnDefinition(store); | 2143 ReturnDefinition(store); |
| 2174 } | 2144 } |
| 2175 | 2145 |
| 2176 | 2146 |
| 2177 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { | 2147 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { |
| 2178 InlineBailout("EffectGraphVisitor::VisitLoadIndexedNode"); | 2148 InlineBailout("EffectGraphVisitor::VisitLoadIndexedNode (deopt)"); |
| 2179 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2149 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2180 new ZoneGrowableArray<PushArgumentInstr*>(2); | 2150 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 2181 ValueGraphVisitor for_array(owner(), temp_index()); | 2151 ValueGraphVisitor for_array(owner(), temp_index()); |
| 2182 node->array()->Visit(&for_array); | 2152 node->array()->Visit(&for_array); |
| 2183 Append(for_array); | 2153 Append(for_array); |
| 2184 arguments->Add(PushArgument(for_array.value())); | 2154 arguments->Add(PushArgument(for_array.value())); |
| 2185 | 2155 |
| 2186 ValueGraphVisitor for_index(owner(), temp_index()); | 2156 ValueGraphVisitor for_index(owner(), temp_index()); |
| 2187 node->index_expr()->Visit(&for_index); | 2157 node->index_expr()->Visit(&for_index); |
| 2188 Append(for_index); | 2158 Append(for_index); |
| 2189 arguments->Add(PushArgument(for_index.value())); | 2159 arguments->Add(PushArgument(for_index.value())); |
| 2190 | 2160 |
| 2191 const intptr_t checked_argument_count = 1; | 2161 const intptr_t checked_argument_count = 1; |
| 2192 const String& name = | 2162 const String& name = |
| 2193 String::ZoneHandle(Symbols::New(Token::Str(Token::kINDEX))); | 2163 String::ZoneHandle(Symbols::New(Token::Str(Token::kINDEX))); |
| 2194 InstanceCallInstr* load = new InstanceCallInstr(node->token_pos(), | 2164 InstanceCallInstr* load = new InstanceCallInstr(node->token_pos(), |
| 2195 name, | 2165 name, |
| 2196 Token::kINDEX, | 2166 Token::kINDEX, |
| 2197 arguments, | 2167 arguments, |
| 2198 Array::ZoneHandle(), | 2168 Array::ZoneHandle(), |
| 2199 checked_argument_count); | 2169 checked_argument_count); |
| 2200 ReturnDefinition(load); | 2170 ReturnDefinition(load); |
| 2201 } | 2171 } |
| 2202 | 2172 |
| 2203 | 2173 |
| 2204 Definition* EffectGraphVisitor::BuildStoreIndexedValues( | 2174 Definition* EffectGraphVisitor::BuildStoreIndexedValues( |
| 2205 StoreIndexedNode* node, | 2175 StoreIndexedNode* node, |
| 2206 bool result_is_needed) { | 2176 bool result_is_needed) { |
| 2207 InlineBailout("EffectGraphVisitor::BuildStoreIndexedValues"); | 2177 InlineBailout("EffectGraphVisitor::BuildStoreIndexedValues (deopt)"); |
| 2208 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2178 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2209 new ZoneGrowableArray<PushArgumentInstr*>(3); | 2179 new ZoneGrowableArray<PushArgumentInstr*>(3); |
| 2210 ValueGraphVisitor for_array(owner(), temp_index()); | 2180 ValueGraphVisitor for_array(owner(), temp_index()); |
| 2211 node->array()->Visit(&for_array); | 2181 node->array()->Visit(&for_array); |
| 2212 Append(for_array); | 2182 Append(for_array); |
| 2213 arguments->Add(PushArgument(for_array.value())); | 2183 arguments->Add(PushArgument(for_array.value())); |
| 2214 | 2184 |
| 2215 ValueGraphVisitor for_index(owner(), temp_index()); | 2185 ValueGraphVisitor for_index(owner(), temp_index()); |
| 2216 node->index_expr()->Visit(&for_index); | 2186 node->index_expr()->Visit(&for_index); |
| 2217 Append(for_index); | 2187 Append(for_index); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2242 if (result_is_needed) { | 2212 if (result_is_needed) { |
| 2243 Do(store); | 2213 Do(store); |
| 2244 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var()); | 2214 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var()); |
| 2245 } else { | 2215 } else { |
| 2246 return store; | 2216 return store; |
| 2247 } | 2217 } |
| 2248 } | 2218 } |
| 2249 | 2219 |
| 2250 | 2220 |
| 2251 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { | 2221 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { |
| 2252 InlineBailout("EffectGraphVisitor::VisitStoreIndexedNode"); | |
| 2253 ReturnDefinition(BuildStoreIndexedValues(node, | 2222 ReturnDefinition(BuildStoreIndexedValues(node, |
| 2254 false)); // Result not needed. | 2223 false)); // Result not needed. |
| 2255 } | 2224 } |
| 2256 | 2225 |
| 2257 | 2226 |
| 2258 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { | 2227 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { |
| 2259 InlineBailout("ValueGraphVisitor::VisitStoreIndexedNode"); | |
| 2260 ReturnDefinition(BuildStoreIndexedValues(node, | 2228 ReturnDefinition(BuildStoreIndexedValues(node, |
| 2261 true)); // Result is needed. | 2229 true)); // Result is needed. |
| 2262 } | 2230 } |
| 2263 | 2231 |
| 2264 | 2232 |
| 2265 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { | 2233 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { |
| 2266 return (node == owner()->parsed_function().node_sequence()) && | 2234 return (node == owner()->parsed_function().node_sequence()) && |
| 2267 (owner()->parsed_function().saved_context_var() != NULL); | 2235 (owner()->parsed_function().saved_context_var() != NULL); |
| 2268 } | 2236 } |
| 2269 | 2237 |
| 2270 | 2238 |
| 2271 void EffectGraphVisitor::UnchainContext() { | 2239 void EffectGraphVisitor::UnchainContext() { |
| 2272 InlineBailout("EffectGraphVisitor::UnchainContext"); | 2240 InlineBailout("EffectGraphVisitor::UnchainContext (deopt)"); |
| 2273 Value* context = Bind(new CurrentContextInstr()); | 2241 Value* context = Bind(new CurrentContextInstr()); |
| 2274 Value* parent = Bind( | 2242 Value* parent = Bind( |
| 2275 new LoadVMFieldInstr(context, | 2243 new LoadVMFieldInstr(context, |
| 2276 Context::parent_offset(), | 2244 Context::parent_offset(), |
| 2277 Type::ZoneHandle())); // Not an instance, no type. | 2245 Type::ZoneHandle())); // Not an instance, no type. |
| 2278 Do(new StoreContextInstr(parent)); | 2246 Do(new StoreContextInstr(parent)); |
| 2279 } | 2247 } |
| 2280 | 2248 |
| 2281 | 2249 |
| 2282 // <Statement> ::= Sequence { scope: LocalScope | 2250 // <Statement> ::= Sequence { scope: LocalScope |
| 2283 // nodes: <Statement>* | 2251 // nodes: <Statement>* |
| 2284 // label: SourceLabel } | 2252 // label: SourceLabel } |
| 2285 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { | 2253 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { |
| 2286 LocalScope* scope = node->scope(); | 2254 LocalScope* scope = node->scope(); |
| 2287 const intptr_t num_context_variables = | 2255 const intptr_t num_context_variables = |
| 2288 (scope != NULL) ? scope->num_context_variables() : 0; | 2256 (scope != NULL) ? scope->num_context_variables() : 0; |
| 2289 int previous_context_level = owner()->context_level(); | 2257 int previous_context_level = owner()->context_level(); |
| 2290 if (num_context_variables > 0) { | 2258 if (num_context_variables > 0) { |
| 2291 InlineBailout("EffectGraphVisitor::VisitSequenceNode (captured vars)"); | 2259 InlineBailout("EffectGraphVisitor::VisitSequenceNode (deopt)"); |
| 2292 // The loop local scope declares variables that are captured. | 2260 // The loop local scope declares variables that are captured. |
| 2293 // Allocate and chain a new context. | 2261 // Allocate and chain a new context. |
| 2294 // Allocate context computation (uses current CTX) | 2262 // Allocate context computation (uses current CTX) |
| 2295 Value* allocated_context = | 2263 Value* allocated_context = |
| 2296 Bind(new AllocateContextInstr(node->token_pos(), | 2264 Bind(new AllocateContextInstr(node->token_pos(), |
| 2297 num_context_variables)); | 2265 num_context_variables)); |
| 2298 | 2266 |
| 2299 // If this node_sequence is the body of the function being compiled, and if | 2267 // If this node_sequence is the body of the function being compiled, and if |
| 2300 // this function is not a closure, do not link the current context as the | 2268 // this function is not a closure, do not link the current context as the |
| 2301 // parent of the newly allocated context, as it is not accessible. Instead, | 2269 // 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... |
| 2346 Value* null_constant = | 2314 Value* null_constant = |
| 2347 Bind(new ConstantInstr(Object::ZoneHandle())); | 2315 Bind(new ConstantInstr(Object::ZoneHandle())); |
| 2348 Do(BuildStoreLocal(*temp_local, null_constant)); | 2316 Do(BuildStoreLocal(*temp_local, null_constant)); |
| 2349 } | 2317 } |
| 2350 } | 2318 } |
| 2351 } | 2319 } |
| 2352 } | 2320 } |
| 2353 | 2321 |
| 2354 if (FLAG_enable_type_checks && | 2322 if (FLAG_enable_type_checks && |
| 2355 (node == owner()->parsed_function().node_sequence())) { | 2323 (node == owner()->parsed_function().node_sequence())) { |
| 2356 InlineBailout("EffectGraphVisitor::VisitSequenceNode (type check)"); | |
| 2357 const Function& function = owner()->parsed_function().function(); | 2324 const Function& function = owner()->parsed_function().function(); |
| 2358 const int num_params = function.NumberOfParameters(); | 2325 const int num_params = function.NumberOfParameters(); |
| 2359 int pos = 0; | 2326 int pos = 0; |
| 2360 if (function.IsConstructor()) { | 2327 if (function.IsConstructor()) { |
| 2361 // Skip type checking of receiver and phase for constructor functions. | 2328 // Skip type checking of receiver and phase for constructor functions. |
| 2362 pos = 2; | 2329 pos = 2; |
| 2363 } else if (function.IsFactory() || function.IsDynamicFunction()) { | 2330 } else if (function.IsFactory() || function.IsDynamicFunction()) { |
| 2364 // Skip type checking of type arguments for factory functions. | 2331 // Skip type checking of type arguments for factory functions. |
| 2365 // Skip type checking of receiver for instance functions. | 2332 // Skip type checking of receiver for instance functions. |
| 2366 pos = 1; | 2333 pos = 1; |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2492 // Generate code for the finally block if one exists. | 2459 // Generate code for the finally block if one exists. |
| 2493 if ((node->finally_block() != NULL) && is_open()) { | 2460 if ((node->finally_block() != NULL) && is_open()) { |
| 2494 EffectGraphVisitor for_finally_block(owner(), temp_index()); | 2461 EffectGraphVisitor for_finally_block(owner(), temp_index()); |
| 2495 node->finally_block()->Visit(&for_finally_block); | 2462 node->finally_block()->Visit(&for_finally_block); |
| 2496 Append(for_finally_block); | 2463 Append(for_finally_block); |
| 2497 } | 2464 } |
| 2498 } | 2465 } |
| 2499 | 2466 |
| 2500 | 2467 |
| 2501 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { | 2468 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { |
| 2502 InlineBailout("EffectGraphVisitor::BuildThrowNode"); | |
| 2503 ValueGraphVisitor for_exception(owner(), temp_index()); | 2469 ValueGraphVisitor for_exception(owner(), temp_index()); |
| 2504 node->exception()->Visit(&for_exception); | 2470 node->exception()->Visit(&for_exception); |
| 2505 Append(for_exception); | 2471 Append(for_exception); |
| 2506 PushArgument(for_exception.value()); | 2472 PushArgument(for_exception.value()); |
| 2507 Instruction* instr = NULL; | 2473 Instruction* instr = NULL; |
| 2508 if (node->stacktrace() == NULL) { | 2474 if (node->stacktrace() == NULL) { |
| 2509 instr = new ThrowInstr(node->token_pos()); | 2475 instr = new ThrowInstr(node->token_pos()); |
| 2510 } else { | 2476 } else { |
| 2511 ValueGraphVisitor for_stack_trace(owner(), temp_index()); | 2477 ValueGraphVisitor for_stack_trace(owner(), temp_index()); |
| 2512 node->stacktrace()->Visit(&for_stack_trace); | 2478 node->stacktrace()->Visit(&for_stack_trace); |
| 2513 Append(for_stack_trace); | 2479 Append(for_stack_trace); |
| 2514 PushArgument(for_stack_trace.value()); | 2480 PushArgument(for_stack_trace.value()); |
| 2515 instr = new ReThrowInstr(node->token_pos()); | 2481 instr = new ReThrowInstr(node->token_pos()); |
| 2516 } | 2482 } |
| 2517 AddInstruction(instr); | 2483 AddInstruction(instr); |
| 2518 } | 2484 } |
| 2519 | 2485 |
| 2520 | 2486 |
| 2521 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { | 2487 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { |
| 2522 InlineBailout("EffectGraphVisitor::VisitThrowNode"); | |
| 2523 BuildThrowNode(node); | 2488 BuildThrowNode(node); |
| 2524 CloseFragment(); | 2489 CloseFragment(); |
| 2525 } | 2490 } |
| 2526 | 2491 |
| 2527 | 2492 |
| 2528 // A throw cannot be part of an expression, however, the parser may replace | 2493 // A throw cannot be part of an expression, however, the parser may replace |
| 2529 // certain expression nodes with a throw. In that case generate a literal null | 2494 // certain expression nodes with a throw. In that case generate a literal null |
| 2530 // so that the fragment is not closed in the middle of an expression. | 2495 // so that the fragment is not closed in the middle of an expression. |
| 2531 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { | 2496 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { |
| 2532 InlineBailout("ValueGraphVisitor::VisitThrowNode"); | |
| 2533 BuildThrowNode(node); | 2497 BuildThrowNode(node); |
| 2534 ReturnDefinition(new ConstantInstr(Instance::ZoneHandle())); | 2498 ReturnDefinition(new ConstantInstr(Instance::ZoneHandle())); |
| 2535 } | 2499 } |
| 2536 | 2500 |
| 2537 | 2501 |
| 2538 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { | 2502 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { |
| 2539 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode"); | 2503 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode"); |
| 2540 const intptr_t try_index = owner()->try_index(); | 2504 const intptr_t try_index = owner()->try_index(); |
| 2541 if (try_index >= 0) { | 2505 if (try_index >= 0) { |
| 2542 // We are about to generate code for an inlined finally block. Exceptions | 2506 // We are about to generate code for an inlined finally block. Exceptions |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2559 for_finally_block.Goto(after_finally); | 2523 for_finally_block.Goto(after_finally); |
| 2560 for_finally_block.exit_ = after_finally; | 2524 for_finally_block.exit_ = after_finally; |
| 2561 } | 2525 } |
| 2562 | 2526 |
| 2563 Goto(finally_entry); | 2527 Goto(finally_entry); |
| 2564 AppendFragment(finally_entry, for_finally_block); | 2528 AppendFragment(finally_entry, for_finally_block); |
| 2565 exit_ = for_finally_block.exit_; | 2529 exit_ = for_finally_block.exit_; |
| 2566 } | 2530 } |
| 2567 | 2531 |
| 2568 | 2532 |
| 2569 FlowGraph* FlowGraphBuilder::BuildGraph() { | 2533 FlowGraph* FlowGraphBuilder::BuildGraph(InliningContext context) { |
| 2570 if (FLAG_print_ast) { | 2534 if (FLAG_print_ast) { |
| 2571 // Print the function ast before IL generation. | 2535 // Print the function ast before IL generation. |
| 2572 AstPrinter::PrintFunctionNodes(parsed_function()); | 2536 AstPrinter::PrintFunctionNodes(parsed_function()); |
| 2573 } | 2537 } |
| 2538 // Set the inlining context. |
| 2539 ASSERT(inlining_context_ == kNotInlining); |
| 2540 inlining_context_ = context; |
| 2541 if (InInliningContext()) exits_ = new ZoneGrowableArray<ReturnInstr*>(); |
| 2574 // Compilation can be nested, preserve the computation-id. | 2542 // Compilation can be nested, preserve the computation-id. |
| 2575 const Function& function = parsed_function().function(); | 2543 const Function& function = parsed_function().function(); |
| 2576 TargetEntryInstr* normal_entry = new TargetEntryInstr( | 2544 TargetEntryInstr* normal_entry = new TargetEntryInstr( |
| 2577 CatchClauseNode::kInvalidTryIndex); | 2545 CatchClauseNode::kInvalidTryIndex); |
| 2578 graph_entry_ = new GraphEntryInstr(normal_entry); | 2546 graph_entry_ = new GraphEntryInstr(normal_entry); |
| 2579 EffectGraphVisitor for_effect(this, 0); | 2547 EffectGraphVisitor for_effect(this, 0); |
| 2580 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the | 2548 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the |
| 2581 // stack check on entry for leaf routines). | 2549 // stack check on entry for leaf routines). |
| 2582 for_effect.Do(new CheckStackOverflowInstr(function.token_pos())); | 2550 for_effect.Do(new CheckStackOverflowInstr(function.token_pos())); |
| 2583 parsed_function().node_sequence()->Visit(&for_effect); | 2551 parsed_function().node_sequence()->Visit(&for_effect); |
| 2584 AppendFragment(normal_entry, for_effect); | 2552 AppendFragment(normal_entry, for_effect); |
| 2585 // Check that the graph is properly terminated. | 2553 // Check that the graph is properly terminated. |
| 2586 ASSERT(!for_effect.is_open()); | 2554 ASSERT(!for_effect.is_open()); |
| 2587 return new FlowGraph(*this, graph_entry_); | |
| 2588 } | |
| 2589 | |
| 2590 | |
| 2591 FlowGraph* FlowGraphBuilder::BuildGraphForInlining(InliningContext context) { | |
| 2592 ASSERT(inlining_context_ == kNotInlining); | |
| 2593 inlining_context_ = context; | |
| 2594 exits_ = new ZoneGrowableArray<ReturnInstr*>(); | |
| 2595 TargetEntryInstr* normal_entry = new TargetEntryInstr( | |
| 2596 CatchClauseNode::kInvalidTryIndex); | |
| 2597 graph_entry_ = new GraphEntryInstr(normal_entry); | |
| 2598 EffectGraphVisitor for_effect(this, 0); | |
| 2599 parsed_function().node_sequence()->Visit(&for_effect); | |
| 2600 AppendFragment(normal_entry, for_effect); | |
| 2601 ASSERT(!for_effect.is_open()); | |
| 2602 FlowGraph* graph = new FlowGraph(*this, graph_entry_); | 2555 FlowGraph* graph = new FlowGraph(*this, graph_entry_); |
| 2603 graph->set_exits(exits_); | 2556 if (InInliningContext()) graph->set_exits(exits_); |
| 2604 return graph; | 2557 return graph; |
| 2605 } | 2558 } |
| 2606 | 2559 |
| 2607 | 2560 |
| 2608 void FlowGraphBuilder::Bailout(const char* reason) { | 2561 void FlowGraphBuilder::Bailout(const char* reason) { |
| 2609 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; | 2562 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; |
| 2610 const char* function_name = parsed_function_.function().ToCString(); | 2563 const char* function_name = parsed_function_.function().ToCString(); |
| 2611 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 2564 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 2612 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 2565 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 2613 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2566 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2614 const Error& error = Error::Handle( | 2567 const Error& error = Error::Handle( |
| 2615 LanguageError::New(String::Handle(String::New(chars)))); | 2568 LanguageError::New(String::Handle(String::New(chars)))); |
| 2616 Isolate::Current()->long_jump_base()->Jump(1, error); | 2569 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2617 } | 2570 } |
| 2618 | 2571 |
| 2619 | 2572 |
| 2620 } // namespace dart | 2573 } // namespace dart |
| OLD | NEW |