Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(591)

Side by Side Diff: runtime/vm/flow_graph_builder.cc

Issue 10913010: Inlining monomorphic calls. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698