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

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

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

Powered by Google App Engine
This is Rietveld 408576698