| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "vm/ast_printer.h" | 7 #include "vm/ast_printer.h" |
| 8 #include "vm/code_descriptors.h" | 8 #include "vm/code_descriptors.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flags.h" | 10 #include "vm/flags.h" |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 } else { | 59 } else { |
| 60 exit()->set_next(other_fragment.entry()); | 60 exit()->set_next(other_fragment.entry()); |
| 61 exit_ = other_fragment.exit(); | 61 exit_ = other_fragment.exit(); |
| 62 } | 62 } |
| 63 temp_index_ = other_fragment.temp_index(); | 63 temp_index_ = other_fragment.temp_index(); |
| 64 } | 64 } |
| 65 | 65 |
| 66 | 66 |
| 67 Value* EffectGraphVisitor::Bind(Definition* definition) { | 67 Value* EffectGraphVisitor::Bind(Definition* definition) { |
| 68 ASSERT(is_open()); | 68 ASSERT(is_open()); |
| 69 ASSERT(!owner()->InInliningContext() || !definition->CanDeoptimize()); |
| 69 DeallocateTempIndex(definition->InputCount()); | 70 DeallocateTempIndex(definition->InputCount()); |
| 70 definition->set_use_kind(Definition::kValue); | 71 definition->set_use_kind(Definition::kValue); |
| 71 definition->set_temp_index(AllocateTempIndex()); | 72 definition->set_temp_index(AllocateTempIndex()); |
| 72 if (is_empty()) { | 73 if (is_empty()) { |
| 73 entry_ = definition; | 74 entry_ = definition; |
| 74 } else { | 75 } else { |
| 75 exit()->set_next(definition); | 76 exit()->set_next(definition); |
| 76 } | 77 } |
| 77 exit_ = definition; | 78 exit_ = definition; |
| 78 return new Value(definition); | 79 return new Value(definition); |
| 79 } | 80 } |
| 80 | 81 |
| 81 | 82 |
| 82 void EffectGraphVisitor::Do(Definition* definition) { | 83 void EffectGraphVisitor::Do(Definition* definition) { |
| 83 ASSERT(is_open()); | 84 ASSERT(is_open()); |
| 85 ASSERT(!owner()->InInliningContext() || !definition->CanDeoptimize()); |
| 84 DeallocateTempIndex(definition->InputCount()); | 86 DeallocateTempIndex(definition->InputCount()); |
| 85 definition->set_use_kind(Definition::kEffect); | 87 definition->set_use_kind(Definition::kEffect); |
| 86 if (is_empty()) { | 88 if (is_empty()) { |
| 87 entry_ = definition; | 89 entry_ = definition; |
| 88 } else { | 90 } else { |
| 89 exit()->set_next(definition); | 91 exit()->set_next(definition); |
| 90 } | 92 } |
| 91 exit_ = definition; | 93 exit_ = definition; |
| 92 } | 94 } |
| 93 | 95 |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 MergeBranchWithNegate(neg); | 410 MergeBranchWithNegate(neg); |
| 409 return; | 411 return; |
| 410 } | 412 } |
| 411 } | 413 } |
| 412 ReturnValue(Bind(definition)); | 414 ReturnValue(Bind(definition)); |
| 413 } | 415 } |
| 414 | 416 |
| 415 | 417 |
| 416 // Special handling for AND/OR. | 418 // Special handling for AND/OR. |
| 417 void TestGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 419 void TestGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 420 InlineBailout("TestGraphVisitor::VisitBinaryOpNode"); |
| 421 |
| 418 // Operators "&&" and "||" cannot be overloaded therefore do not call | 422 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 419 // operator. | 423 // operator. |
| 420 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 424 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 421 TestGraphVisitor for_left(owner(), | 425 TestGraphVisitor for_left(owner(), |
| 422 temp_index(), | 426 temp_index(), |
| 423 node->left()->token_pos()); | 427 node->left()->token_pos()); |
| 424 node->left()->Visit(&for_left); | 428 node->left()->Visit(&for_left); |
| 425 | 429 |
| 426 TestGraphVisitor for_right(owner(), | 430 TestGraphVisitor for_right(owner(), |
| 427 temp_index(), | 431 temp_index(), |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 | 464 |
| 461 | 465 |
| 462 // <Statement> ::= Return { value: <Expression> | 466 // <Statement> ::= Return { value: <Expression> |
| 463 // inlined_finally_list: <InlinedFinally>* } | 467 // inlined_finally_list: <InlinedFinally>* } |
| 464 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { | 468 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { |
| 465 ValueGraphVisitor for_value(owner(), temp_index()); | 469 ValueGraphVisitor for_value(owner(), temp_index()); |
| 466 node->value()->Visit(&for_value); | 470 node->value()->Visit(&for_value); |
| 467 Append(for_value); | 471 Append(for_value); |
| 468 | 472 |
| 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 (exception)"); | 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 const Function& function = owner()->parsed_function().function(); | 483 const Function& function = owner()->parsed_function().function(); |
| 480 const bool is_implicit_dynamic_getter = | 484 const bool is_implicit_dynamic_getter = |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 EffectGraphVisitor for_right(owner(), temp_index()); | 621 EffectGraphVisitor for_right(owner(), temp_index()); |
| 618 node->right()->Visit(&for_right); | 622 node->right()->Visit(&for_right); |
| 619 EffectGraphVisitor empty(owner(), temp_index()); | 623 EffectGraphVisitor empty(owner(), temp_index()); |
| 620 if (node->kind() == Token::kAND) { | 624 if (node->kind() == Token::kAND) { |
| 621 Join(for_left, for_right, empty); | 625 Join(for_left, for_right, empty); |
| 622 } else { | 626 } else { |
| 623 Join(for_left, empty, for_right); | 627 Join(for_left, empty, for_right); |
| 624 } | 628 } |
| 625 return; | 629 return; |
| 626 } | 630 } |
| 631 InlineBailout("EffectGraphVisitor::VisitBinaryOpNode (deopt)"); |
| 627 ValueGraphVisitor for_left_value(owner(), temp_index()); | 632 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 628 node->left()->Visit(&for_left_value); | 633 node->left()->Visit(&for_left_value); |
| 629 Append(for_left_value); | 634 Append(for_left_value); |
| 630 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); | 635 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); |
| 631 | 636 |
| 632 ValueGraphVisitor for_right_value(owner(), temp_index()); | 637 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 633 node->right()->Visit(&for_right_value); | 638 node->right()->Visit(&for_right_value); |
| 634 Append(for_right_value); | 639 Append(for_right_value); |
| 635 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); | 640 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); |
| 636 | 641 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 663 | 668 |
| 664 TestGraphVisitor for_test(owner(), | 669 TestGraphVisitor for_test(owner(), |
| 665 temp_index(), | 670 temp_index(), |
| 666 node->left()->token_pos()); | 671 node->left()->token_pos()); |
| 667 node->left()->Visit(&for_test); | 672 node->left()->Visit(&for_test); |
| 668 | 673 |
| 669 ValueGraphVisitor for_right(owner(), temp_index()); | 674 ValueGraphVisitor for_right(owner(), temp_index()); |
| 670 node->right()->Visit(&for_right); | 675 node->right()->Visit(&for_right); |
| 671 Value* right_value = for_right.value(); | 676 Value* right_value = for_right.value(); |
| 672 if (FLAG_enable_type_checks) { | 677 if (FLAG_enable_type_checks) { |
| 678 InlineBailout("ValueGraphVisitor::VisitBinaryOpNode (type check)"); |
| 673 right_value = | 679 right_value = |
| 674 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(), | 680 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(), |
| 675 right_value)); | 681 right_value)); |
| 676 } | 682 } |
| 677 Value* constant_true = for_right.Bind(new ConstantInstr(bool_true)); | 683 Value* constant_true = for_right.Bind(new ConstantInstr(bool_true)); |
| 678 Value* compare = | 684 Value* compare = |
| 679 for_right.Bind(new StrictCompareInstr(Token::kEQ_STRICT, | 685 for_right.Bind(new StrictCompareInstr(Token::kEQ_STRICT, |
| 680 right_value, | 686 right_value, |
| 681 constant_true)); | 687 constant_true)); |
| 682 for_right.Do(BuildStoreExprTemp(compare)); | 688 for_right.Do(BuildStoreExprTemp(compare)); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 return Bind(new ConstantInstr(Object::ZoneHandle())); | 738 return Bind(new ConstantInstr(Object::ZoneHandle())); |
| 733 } | 739 } |
| 734 | 740 |
| 735 | 741 |
| 736 // Used for testing incoming arguments. | 742 // Used for testing incoming arguments. |
| 737 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( | 743 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( |
| 738 intptr_t token_pos, | 744 intptr_t token_pos, |
| 739 Value* value, | 745 Value* value, |
| 740 const AbstractType& dst_type, | 746 const AbstractType& dst_type, |
| 741 const String& dst_name) { | 747 const String& dst_name) { |
| 748 InlineBailout("EffectGraphVisitor::BuildAssertAssignable (deopt)"); |
| 742 // Build the type check computation. | 749 // Build the type check computation. |
| 743 Value* instantiator = NULL; | 750 Value* instantiator = NULL; |
| 744 Value* instantiator_type_arguments = NULL; | 751 Value* instantiator_type_arguments = NULL; |
| 745 if (dst_type.IsInstantiated()) { | 752 if (dst_type.IsInstantiated()) { |
| 746 instantiator = BuildNullValue(); | 753 instantiator = BuildNullValue(); |
| 747 instantiator_type_arguments = BuildNullValue(); | 754 instantiator_type_arguments = BuildNullValue(); |
| 748 } else { | 755 } else { |
| 749 BuildTypecheckArguments(token_pos, | 756 BuildTypecheckArguments(token_pos, |
| 750 &instantiator, | 757 &instantiator, |
| 751 &instantiator_type_arguments); | 758 &instantiator_type_arguments); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 } else { | 836 } else { |
| 830 if (literal_value.IsInstanceOf(type, TypeArguments::Handle(), NULL)) { | 837 if (literal_value.IsInstanceOf(type, TypeArguments::Handle(), NULL)) { |
| 831 result = new ConstantInstr(negate_result ? bool_false : bool_true); | 838 result = new ConstantInstr(negate_result ? bool_false : bool_true); |
| 832 } else { | 839 } else { |
| 833 result = new ConstantInstr(negate_result ? bool_true : bool_false); | 840 result = new ConstantInstr(negate_result ? bool_true : bool_false); |
| 834 } | 841 } |
| 835 } | 842 } |
| 836 ReturnDefinition(result); | 843 ReturnDefinition(result); |
| 837 return; | 844 return; |
| 838 } | 845 } |
| 846 InlineBailout("ValueGraphVisitor::BuildTypeTest (deopt)"); |
| 839 | 847 |
| 840 ValueGraphVisitor for_left_value(owner(), temp_index()); | 848 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 841 node->left()->Visit(&for_left_value); | 849 node->left()->Visit(&for_left_value); |
| 842 Append(for_left_value); | 850 Append(for_left_value); |
| 843 Value* instantiator = NULL; | 851 Value* instantiator = NULL; |
| 844 Value* instantiator_type_arguments = NULL; | 852 Value* instantiator_type_arguments = NULL; |
| 845 if (type.IsInstantiated()) { | 853 if (type.IsInstantiated()) { |
| 846 instantiator = BuildNullValue(); | 854 instantiator = BuildNullValue(); |
| 847 instantiator_type_arguments = BuildNullValue(); | 855 instantiator_type_arguments = BuildNullValue(); |
| 848 } else { | 856 } else { |
| 849 BuildTypecheckArguments(node->token_pos(), | 857 BuildTypecheckArguments(node->token_pos(), |
| 850 &instantiator, | 858 &instantiator, |
| 851 &instantiator_type_arguments); | 859 &instantiator_type_arguments); |
| 852 } | 860 } |
| 853 // TODO(zerny): Remove this when issues 5216 and 5217 are fixed. | |
| 854 InlineBailout("instance of"); | |
| 855 InstanceOfInstr* instance_of = | 861 InstanceOfInstr* instance_of = |
| 856 new InstanceOfInstr(node->token_pos(), | 862 new InstanceOfInstr(node->token_pos(), |
| 857 for_left_value.value(), | 863 for_left_value.value(), |
| 858 instantiator, | 864 instantiator, |
| 859 instantiator_type_arguments, | 865 instantiator_type_arguments, |
| 860 node->right()->AsTypeNode()->type(), | 866 node->right()->AsTypeNode()->type(), |
| 861 (node->kind() == Token::kISNOT)); | 867 (node->kind() == Token::kISNOT)); |
| 862 ReturnDefinition(instance_of); | 868 ReturnDefinition(instance_of); |
| 863 } | 869 } |
| 864 | 870 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 898 node->left()->Visit(&for_left_value); | 904 node->left()->Visit(&for_left_value); |
| 899 Append(for_left_value); | 905 Append(for_left_value); |
| 900 ValueGraphVisitor for_right_value(owner(), temp_index()); | 906 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 901 node->right()->Visit(&for_right_value); | 907 node->right()->Visit(&for_right_value); |
| 902 Append(for_right_value); | 908 Append(for_right_value); |
| 903 StrictCompareInstr* comp = new StrictCompareInstr( | 909 StrictCompareInstr* comp = new StrictCompareInstr( |
| 904 node->kind(), for_left_value.value(), for_right_value.value()); | 910 node->kind(), for_left_value.value(), for_right_value.value()); |
| 905 ReturnDefinition(comp); | 911 ReturnDefinition(comp); |
| 906 return; | 912 return; |
| 907 } | 913 } |
| 914 InlineBailout("EffectGraphVisitor::VisitComparisonNode (deopt)"); |
| 908 | 915 |
| 909 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { | 916 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { |
| 910 ValueGraphVisitor for_left_value(owner(), temp_index()); | 917 ValueGraphVisitor for_left_value(owner(), temp_index()); |
| 911 node->left()->Visit(&for_left_value); | 918 node->left()->Visit(&for_left_value); |
| 912 Append(for_left_value); | 919 Append(for_left_value); |
| 913 ValueGraphVisitor for_right_value(owner(), temp_index()); | 920 ValueGraphVisitor for_right_value(owner(), temp_index()); |
| 914 node->right()->Visit(&for_right_value); | 921 node->right()->Visit(&for_right_value); |
| 915 Append(for_right_value); | 922 Append(for_right_value); |
| 916 if (FLAG_enable_type_checks) { | 923 if (FLAG_enable_type_checks) { |
| 917 EqualityCompareInstr* comp = new EqualityCompareInstr( | 924 EqualityCompareInstr* comp = new EqualityCompareInstr( |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 959 Append(for_value); | 966 Append(for_value); |
| 960 Value* value = for_value.value(); | 967 Value* value = for_value.value(); |
| 961 if (FLAG_enable_type_checks) { | 968 if (FLAG_enable_type_checks) { |
| 962 value = | 969 value = |
| 963 Bind(new AssertBooleanInstr(node->operand()->token_pos(), value)); | 970 Bind(new AssertBooleanInstr(node->operand()->token_pos(), value)); |
| 964 } | 971 } |
| 965 BooleanNegateInstr* negate = new BooleanNegateInstr(value); | 972 BooleanNegateInstr* negate = new BooleanNegateInstr(value); |
| 966 ReturnDefinition(negate); | 973 ReturnDefinition(negate); |
| 967 return; | 974 return; |
| 968 } | 975 } |
| 976 InlineBailout("EffectGraphVisitor::VisitUnaryOpNode (deopt)"); |
| 969 | 977 |
| 970 ValueGraphVisitor for_value(owner(), temp_index()); | 978 ValueGraphVisitor for_value(owner(), temp_index()); |
| 971 node->operand()->Visit(&for_value); | 979 node->operand()->Visit(&for_value); |
| 972 Append(for_value); | 980 Append(for_value); |
| 973 PushArgumentInstr* push_value = PushArgument(for_value.value()); | 981 PushArgumentInstr* push_value = PushArgument(for_value.value()); |
| 974 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 982 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 975 new ZoneGrowableArray<PushArgumentInstr*>(1); | 983 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 976 arguments->Add(push_value); | 984 arguments->Add(push_value); |
| 977 InstanceCallInstr* call = (node->kind() == Token::kSUB) | 985 InstanceCallInstr* call = (node->kind() == Token::kSUB) |
| 978 ? new InstanceCallInstr(node->token_pos(), | 986 ? new InstanceCallInstr(node->token_pos(), |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1078 // e) true-target-0 -> case-statements-join | 1086 // e) true-target-0 -> case-statements-join |
| 1079 // f) true-target-1 -> case-statements-join | 1087 // f) true-target-1 -> case-statements-join |
| 1080 // g) case-statements-join | 1088 // g) case-statements-join |
| 1081 // h) [ case-statements ] -> exit-join | 1089 // h) [ case-statements ] -> exit-join |
| 1082 // i) exit-target -> exit-join | 1090 // i) exit-target -> exit-join |
| 1083 // j) exit-join | 1091 // j) exit-join |
| 1084 // | 1092 // |
| 1085 // Note: The specification of switch/case is under discussion and may change | 1093 // Note: The specification of switch/case is under discussion and may change |
| 1086 // drastically. | 1094 // drastically. |
| 1087 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { | 1095 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { |
| 1088 InlineBailout("EffectGraphVisitor::VisitCaseNode (control)"); | 1096 InlineBailout("EffectGraphVisitor::VisitCaseNode"); |
| 1089 const intptr_t len = node->case_expressions()->length(); | 1097 const intptr_t len = node->case_expressions()->length(); |
| 1090 // Create case statements instructions. | 1098 // Create case statements instructions. |
| 1091 EffectGraphVisitor for_case_statements(owner(), temp_index()); | 1099 EffectGraphVisitor for_case_statements(owner(), temp_index()); |
| 1092 // Compute start of statements fragment. | 1100 // Compute start of statements fragment. |
| 1093 JoinEntryInstr* statement_start = NULL; | 1101 JoinEntryInstr* statement_start = NULL; |
| 1094 if ((node->label() != NULL) && node->label()->is_continue_target()) { | 1102 if ((node->label() != NULL) && node->label()->is_continue_target()) { |
| 1095 // Since a labeled jump continue statement occur in a different case node, | 1103 // Since a labeled jump continue statement occur in a different case node, |
| 1096 // allocate JoinNode here and use it as statement start. | 1104 // allocate JoinNode here and use it as statement start. |
| 1097 statement_start = node->label()->join_for_continue(); | 1105 statement_start = node->label()->join_for_continue(); |
| 1098 if (statement_start == NULL) { | 1106 if (statement_start == NULL) { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1171 // body: <Sequence> } | 1179 // body: <Sequence> } |
| 1172 // The fragment is composed as follows: | 1180 // The fragment is composed as follows: |
| 1173 // a) loop-join | 1181 // a) loop-join |
| 1174 // b) [ test ] -> (body-entry-target, loop-exit-target) | 1182 // b) [ test ] -> (body-entry-target, loop-exit-target) |
| 1175 // c) body-entry-target | 1183 // c) body-entry-target |
| 1176 // d) [ body ] -> (continue-join) | 1184 // d) [ body ] -> (continue-join) |
| 1177 // e) continue-join -> (loop-join) | 1185 // e) continue-join -> (loop-join) |
| 1178 // f) loop-exit-target | 1186 // f) loop-exit-target |
| 1179 // g) break-join (optional) | 1187 // g) break-join (optional) |
| 1180 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { | 1188 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { |
| 1181 InlineBailout("EffectGraphVisitor::VisitWhileNode (control)"); | 1189 InlineBailout("EffectGraphVisitor::VisitWhileNode"); |
| 1182 TestGraphVisitor for_test(owner(), | 1190 TestGraphVisitor for_test(owner(), |
| 1183 temp_index(), | 1191 temp_index(), |
| 1184 node->condition()->token_pos()); | 1192 node->condition()->token_pos()); |
| 1185 node->condition()->Visit(&for_test); | 1193 node->condition()->Visit(&for_test); |
| 1186 ASSERT(!for_test.is_empty()); // Language spec. | 1194 ASSERT(!for_test.is_empty()); // Language spec. |
| 1187 | 1195 |
| 1188 EffectGraphVisitor for_body(owner(), temp_index()); | 1196 EffectGraphVisitor for_body(owner(), temp_index()); |
| 1189 for_body.Do( | 1197 for_body.Do( |
| 1190 new CheckStackOverflowInstr(node->token_pos())); | 1198 new CheckStackOverflowInstr(node->token_pos())); |
| 1191 node->body()->Visit(&for_body); | 1199 node->body()->Visit(&for_body); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1209 | 1217 |
| 1210 // The fragment is composed as follows: | 1218 // The fragment is composed as follows: |
| 1211 // a) body-entry-join | 1219 // a) body-entry-join |
| 1212 // b) [ body ] | 1220 // b) [ body ] |
| 1213 // c) test-entry (continue-join or body-exit-target) | 1221 // c) test-entry (continue-join or body-exit-target) |
| 1214 // d) [ test-entry ] -> (back-target, loop-exit-target) | 1222 // d) [ test-entry ] -> (back-target, loop-exit-target) |
| 1215 // e) back-target -> (body-entry-join) | 1223 // e) back-target -> (body-entry-join) |
| 1216 // f) loop-exit-target | 1224 // f) loop-exit-target |
| 1217 // g) break-join | 1225 // g) break-join |
| 1218 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { | 1226 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { |
| 1219 InlineBailout("EffectGraphVisitor::VisitDoWhileNode (control)"); | 1227 InlineBailout("EffectGraphVisitor::VisitDoWhileNode"); |
| 1220 // Traverse body first in order to generate continue and break labels. | 1228 // Traverse body first in order to generate continue and break labels. |
| 1221 EffectGraphVisitor for_body(owner(), temp_index()); | 1229 EffectGraphVisitor for_body(owner(), temp_index()); |
| 1222 for_body.Do( | 1230 for_body.Do( |
| 1223 new CheckStackOverflowInstr(node->token_pos())); | 1231 new CheckStackOverflowInstr(node->token_pos())); |
| 1224 node->body()->Visit(&for_body); | 1232 node->body()->Visit(&for_body); |
| 1225 | 1233 |
| 1226 TestGraphVisitor for_test(owner(), | 1234 TestGraphVisitor for_test(owner(), |
| 1227 temp_index(), | 1235 temp_index(), |
| 1228 node->condition()->token_pos()); | 1236 node->condition()->token_pos()); |
| 1229 node->condition()->Visit(&for_test); | 1237 node->condition()->Visit(&for_test); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1260 // a) [ initializer ] | 1268 // a) [ initializer ] |
| 1261 // b) loop-join | 1269 // b) loop-join |
| 1262 // c) [ test ] -> (body-entry-target, loop-exit-target) | 1270 // c) [ test ] -> (body-entry-target, loop-exit-target) |
| 1263 // d) body-entry-target | 1271 // d) body-entry-target |
| 1264 // e) [ body ] | 1272 // e) [ body ] |
| 1265 // f) continue-join (optional) | 1273 // f) continue-join (optional) |
| 1266 // g) [ increment ] -> (loop-join) | 1274 // g) [ increment ] -> (loop-join) |
| 1267 // h) loop-exit-target | 1275 // h) loop-exit-target |
| 1268 // i) break-join | 1276 // i) break-join |
| 1269 void EffectGraphVisitor::VisitForNode(ForNode* node) { | 1277 void EffectGraphVisitor::VisitForNode(ForNode* node) { |
| 1270 InlineBailout("EffectGraphVisitor::VisitForNode (control)"); | 1278 InlineBailout("EffectGraphVisitor::VisitForNode"); |
| 1271 EffectGraphVisitor for_initializer(owner(), temp_index()); | 1279 EffectGraphVisitor for_initializer(owner(), temp_index()); |
| 1272 node->initializer()->Visit(&for_initializer); | 1280 node->initializer()->Visit(&for_initializer); |
| 1273 Append(for_initializer); | 1281 Append(for_initializer); |
| 1274 ASSERT(is_open()); | 1282 ASSERT(is_open()); |
| 1275 | 1283 |
| 1276 // Compose body to set any jump labels. | 1284 // Compose body to set any jump labels. |
| 1277 EffectGraphVisitor for_body(owner(), temp_index()); | 1285 EffectGraphVisitor for_body(owner(), temp_index()); |
| 1278 for_body.Do( | 1286 for_body.Do( |
| 1279 new CheckStackOverflowInstr(node->token_pos())); | 1287 new CheckStackOverflowInstr(node->token_pos())); |
| 1280 node->body()->Visit(&for_body); | 1288 node->body()->Visit(&for_body); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1332 exit_ = for_test.CreateFalseSuccessor(); | 1340 exit_ = for_test.CreateFalseSuccessor(); |
| 1333 } else { | 1341 } else { |
| 1334 for_test.IfFalseGoto(node->label()->join_for_break()); | 1342 for_test.IfFalseGoto(node->label()->join_for_break()); |
| 1335 exit_ = node->label()->join_for_break(); | 1343 exit_ = node->label()->join_for_break(); |
| 1336 } | 1344 } |
| 1337 } | 1345 } |
| 1338 } | 1346 } |
| 1339 | 1347 |
| 1340 | 1348 |
| 1341 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { | 1349 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { |
| 1342 InlineBailout("EffectGraphVisitor::VisitJumpNode (control)"); | 1350 InlineBailout("EffectGraphVisitor::VisitJumpNode"); |
| 1343 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { | 1351 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { |
| 1344 EffectGraphVisitor for_effect(owner(), temp_index()); | 1352 EffectGraphVisitor for_effect(owner(), temp_index()); |
| 1345 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); | 1353 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
| 1346 Append(for_effect); | 1354 Append(for_effect); |
| 1347 if (!is_open()) return; | 1355 if (!is_open()) return; |
| 1348 } | 1356 } |
| 1349 | 1357 |
| 1350 // Unchain the context(s) up to the outer context level of the scope which | 1358 // Unchain the context(s) up to the outer context level of the scope which |
| 1351 // contains the destination label. | 1359 // contains the destination label. |
| 1352 SourceLabel* label = node->label(); | 1360 SourceLabel* label = node->label(); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1497 ValueGraphVisitor for_argument(owner(), temp_index()); | 1505 ValueGraphVisitor for_argument(owner(), temp_index()); |
| 1498 node.NodeAt(i)->Visit(&for_argument); | 1506 node.NodeAt(i)->Visit(&for_argument); |
| 1499 Append(for_argument); | 1507 Append(for_argument); |
| 1500 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); | 1508 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); |
| 1501 values->Add(push_arg); | 1509 values->Add(push_arg); |
| 1502 } | 1510 } |
| 1503 } | 1511 } |
| 1504 | 1512 |
| 1505 | 1513 |
| 1506 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { | 1514 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { |
| 1515 InlineBailout("EffectGraphVisitor::VisitInstanceCallNode (deopt)"); |
| 1507 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1516 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1508 node->receiver()->Visit(&for_receiver); | 1517 node->receiver()->Visit(&for_receiver); |
| 1509 Append(for_receiver); | 1518 Append(for_receiver); |
| 1510 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 1519 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 1511 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1520 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1512 new ZoneGrowableArray<PushArgumentInstr*>( | 1521 new ZoneGrowableArray<PushArgumentInstr*>( |
| 1513 node->arguments()->length() + 1); | 1522 node->arguments()->length() + 1); |
| 1514 arguments->Add(push_receiver); | 1523 arguments->Add(push_receiver); |
| 1515 | 1524 |
| 1516 BuildPushArguments(*node->arguments(), arguments); | 1525 BuildPushArguments(*node->arguments(), arguments); |
| 1517 InstanceCallInstr* call = new InstanceCallInstr( | 1526 InstanceCallInstr* call = new InstanceCallInstr( |
| 1518 node->token_pos(), | 1527 node->token_pos(), |
| 1519 node->function_name(), Token::kILLEGAL, arguments, | 1528 node->function_name(), Token::kILLEGAL, arguments, |
| 1520 node->arguments()->names(), 1); | 1529 node->arguments()->names(), 1); |
| 1521 ReturnDefinition(call); | 1530 ReturnDefinition(call); |
| 1522 } | 1531 } |
| 1523 | 1532 |
| 1524 | 1533 |
| 1525 // <Expression> ::= StaticCall { function: Function | 1534 // <Expression> ::= StaticCall { function: Function |
| 1526 // arguments: <ArgumentList> } | 1535 // arguments: <ArgumentList> } |
| 1527 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { | 1536 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { |
| 1537 InlineBailout("EffectGraphVisitor::VisitStaticCallNode (deopt)"); |
| 1528 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1538 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1529 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 1539 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 1530 BuildPushArguments(*node->arguments(), arguments); | 1540 BuildPushArguments(*node->arguments(), arguments); |
| 1531 StaticCallInstr* call = | 1541 StaticCallInstr* call = |
| 1532 new StaticCallInstr(node->token_pos(), | 1542 new StaticCallInstr(node->token_pos(), |
| 1533 node->function(), | 1543 node->function(), |
| 1534 node->arguments()->names(), | 1544 node->arguments()->names(), |
| 1535 arguments); | 1545 arguments); |
| 1536 ReturnDefinition(call); | 1546 ReturnDefinition(call); |
| 1537 } | 1547 } |
| 1538 | 1548 |
| 1539 | 1549 |
| 1540 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall( | 1550 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall( |
| 1541 ClosureCallNode* node) { | 1551 ClosureCallNode* node) { |
| 1552 InlineBailout("EffectGraphVisitor::BuildClosureCall (deopt)"); |
| 1542 ValueGraphVisitor for_closure(owner(), temp_index()); | 1553 ValueGraphVisitor for_closure(owner(), temp_index()); |
| 1543 node->closure()->Visit(&for_closure); | 1554 node->closure()->Visit(&for_closure); |
| 1544 Append(for_closure); | 1555 Append(for_closure); |
| 1545 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); | 1556 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); |
| 1546 | 1557 |
| 1547 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1558 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1548 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 1559 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 1549 arguments->Add(push_closure); | 1560 arguments->Add(push_closure); |
| 1550 BuildPushArguments(*node->arguments(), arguments); | 1561 BuildPushArguments(*node->arguments(), arguments); |
| 1551 | 1562 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1564 | 1575 |
| 1565 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 1576 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 1566 Value* result = Bind(BuildClosureCall(node)); | 1577 Value* result = Bind(BuildClosureCall(node)); |
| 1567 // Restore context from temp. | 1578 // Restore context from temp. |
| 1568 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); | 1579 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); |
| 1569 ReturnValue(result); | 1580 ReturnValue(result); |
| 1570 } | 1581 } |
| 1571 | 1582 |
| 1572 | 1583 |
| 1573 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { | 1584 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { |
| 1574 InlineBailout("EffectGraphVisitor::VisitCloneContextNode (context)"); | 1585 InlineBailout("EffectGraphVisitor::VisitCloneContextNode (deopt)"); |
| 1575 Value* context = Bind(new CurrentContextInstr()); | 1586 Value* context = Bind(new CurrentContextInstr()); |
| 1576 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context)); | 1587 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context)); |
| 1577 ReturnDefinition(new StoreContextInstr(clone)); | 1588 ReturnDefinition(new StoreContextInstr(clone)); |
| 1578 } | 1589 } |
| 1579 | 1590 |
| 1580 | 1591 |
| 1581 Value* EffectGraphVisitor::BuildObjectAllocation( | 1592 Value* EffectGraphVisitor::BuildObjectAllocation( |
| 1582 ConstructorCallNode* node) { | 1593 ConstructorCallNode* node) { |
| 1583 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); | 1594 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); |
| 1584 const bool requires_type_arguments = cls.HasTypeArguments(); | 1595 const bool requires_type_arguments = cls.HasTypeArguments(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1595 NULL)) { | 1606 NULL)) { |
| 1596 Value* type_arguments = NULL; | 1607 Value* type_arguments = NULL; |
| 1597 Value* instantiator = NULL; | 1608 Value* instantiator = NULL; |
| 1598 BuildConstructorTypeArguments(node, &type_arguments, &instantiator, NULL); | 1609 BuildConstructorTypeArguments(node, &type_arguments, &instantiator, NULL); |
| 1599 | 1610 |
| 1600 // The uninstantiated type arguments cannot be verified to be within their | 1611 // The uninstantiated type arguments cannot be verified to be within their |
| 1601 // bounds at compile time, so verify them at runtime. | 1612 // bounds at compile time, so verify them at runtime. |
| 1602 // Although the type arguments may be uninstantiated at compile time, they | 1613 // Although the type arguments may be uninstantiated at compile time, they |
| 1603 // may represent the identity vector and may be replaced by the instantiated | 1614 // may represent the identity vector and may be replaced by the instantiated |
| 1604 // type arguments of the instantiator at run time. | 1615 // type arguments of the instantiator at run time. |
| 1616 InlineBailout("EffectGraphVisitor::BuildObjectAllocation (deopt)"); |
| 1605 allocate_comp = new AllocateObjectWithBoundsCheckInstr(node, | 1617 allocate_comp = new AllocateObjectWithBoundsCheckInstr(node, |
| 1606 type_arguments, | 1618 type_arguments, |
| 1607 instantiator); | 1619 instantiator); |
| 1608 } else { | 1620 } else { |
| 1609 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = | 1621 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = |
| 1610 new ZoneGrowableArray<PushArgumentInstr*>(); | 1622 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 1611 | 1623 |
| 1612 if (requires_type_arguments) { | 1624 if (requires_type_arguments) { |
| 1613 BuildConstructorTypeArguments(node, NULL, NULL, allocate_arguments); | 1625 BuildConstructorTypeArguments(node, NULL, NULL, allocate_arguments); |
| 1614 } | 1626 } |
| 1615 | 1627 |
| 1616 allocate_comp = new AllocateObjectInstr(node, allocate_arguments); | 1628 allocate_comp = new AllocateObjectInstr(node, allocate_arguments); |
| 1617 } | 1629 } |
| 1618 return Bind(allocate_comp); | 1630 return Bind(allocate_comp); |
| 1619 } | 1631 } |
| 1620 | 1632 |
| 1621 | 1633 |
| 1622 void EffectGraphVisitor::BuildConstructorCall( | 1634 void EffectGraphVisitor::BuildConstructorCall( |
| 1623 ConstructorCallNode* node, | 1635 ConstructorCallNode* node, |
| 1624 PushArgumentInstr* push_alloc_value) { | 1636 PushArgumentInstr* push_alloc_value) { |
| 1637 InlineBailout("EffectGraphVisitor::BuildConstructorCall (deopt)"); |
| 1625 Value* ctor_arg = Bind( | 1638 Value* ctor_arg = Bind( |
| 1626 new ConstantInstr(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); | 1639 new ConstantInstr(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); |
| 1627 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); | 1640 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); |
| 1628 | 1641 |
| 1629 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1642 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1630 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1643 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1631 arguments->Add(push_alloc_value); | 1644 arguments->Add(push_alloc_value); |
| 1632 arguments->Add(push_ctor_arg); | 1645 arguments->Add(push_ctor_arg); |
| 1633 | 1646 |
| 1634 BuildPushArguments(*node->arguments(), arguments); | 1647 BuildPushArguments(*node->arguments(), arguments); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1657 } | 1670 } |
| 1658 } | 1671 } |
| 1659 } | 1672 } |
| 1660 } | 1673 } |
| 1661 return kDynamicCid; // Result cid not known. | 1674 return kDynamicCid; // Result cid not known. |
| 1662 } | 1675 } |
| 1663 | 1676 |
| 1664 | 1677 |
| 1665 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { | 1678 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| 1666 if (node->constructor().IsFactory()) { | 1679 if (node->constructor().IsFactory()) { |
| 1680 InlineBailout("EffectGraphVisitor::VisitConstructorCallNode (deopt)"); |
| 1667 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1681 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1668 new ZoneGrowableArray<PushArgumentInstr*>(); | 1682 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 1669 PushArgumentInstr* push_type_arguments = PushArgument( | 1683 PushArgumentInstr* push_type_arguments = PushArgument( |
| 1670 BuildInstantiatedTypeArguments(node->token_pos(), | 1684 BuildInstantiatedTypeArguments(node->token_pos(), |
| 1671 node->type_arguments())); | 1685 node->type_arguments())); |
| 1672 arguments->Add(push_type_arguments); | 1686 arguments->Add(push_type_arguments); |
| 1673 ASSERT(arguments->length() == 1); | 1687 ASSERT(arguments->length() == 1); |
| 1674 BuildPushArguments(*node->arguments(), arguments); | 1688 BuildPushArguments(*node->arguments(), arguments); |
| 1675 StaticCallInstr* call = | 1689 StaticCallInstr* call = |
| 1676 new StaticCallInstr(node->token_pos(), | 1690 new StaticCallInstr(node->token_pos(), |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1754 instantiator = BuildInstantiator(); | 1768 instantiator = BuildInstantiator(); |
| 1755 } | 1769 } |
| 1756 // The instantiator is the receiver of the caller, which is not a factory. | 1770 // The instantiator is the receiver of the caller, which is not a factory. |
| 1757 // The receiver cannot be null; extract its AbstractTypeArguments object. | 1771 // The receiver cannot be null; extract its AbstractTypeArguments object. |
| 1758 // Note that in the factory case, the instantiator is the first parameter | 1772 // Note that in the factory case, the instantiator is the first parameter |
| 1759 // of the factory, i.e. already an AbstractTypeArguments object. | 1773 // of the factory, i.e. already an AbstractTypeArguments object. |
| 1760 intptr_t type_arguments_instance_field_offset = | 1774 intptr_t type_arguments_instance_field_offset = |
| 1761 instantiator_class.type_arguments_instance_field_offset(); | 1775 instantiator_class.type_arguments_instance_field_offset(); |
| 1762 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments); | 1776 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments); |
| 1763 | 1777 |
| 1778 InlineBailout("EffectGraphVisitor::BuildInstantiatorTypeArguments (deopt)"); |
| 1764 return Bind(new LoadFieldInstr( | 1779 return Bind(new LoadFieldInstr( |
| 1765 instantiator, | 1780 instantiator, |
| 1766 type_arguments_instance_field_offset, | 1781 type_arguments_instance_field_offset, |
| 1767 Type::ZoneHandle())); // Not an instance, no type. | 1782 Type::ZoneHandle())); // Not an instance, no type. |
| 1768 } | 1783 } |
| 1769 | 1784 |
| 1770 | 1785 |
| 1771 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( | 1786 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( |
| 1772 intptr_t token_pos, | 1787 intptr_t token_pos, |
| 1773 const AbstractTypeArguments& type_arguments) { | 1788 const AbstractTypeArguments& type_arguments) { |
| 1774 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { | 1789 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { |
| 1775 return Bind(new ConstantInstr(type_arguments)); | 1790 return Bind(new ConstantInstr(type_arguments)); |
| 1776 } | 1791 } |
| 1792 InlineBailout("EffectGraphVisitor::BuildInstantiatedTypeArguments (deopt)"); |
| 1777 // The type arguments are uninstantiated. | 1793 // The type arguments are uninstantiated. |
| 1778 Value* instantiator_value = | 1794 Value* instantiator_value = |
| 1779 BuildInstantiatorTypeArguments(token_pos, NULL); | 1795 BuildInstantiatorTypeArguments(token_pos, NULL); |
| 1780 return Bind(new InstantiateTypeArgumentsInstr(token_pos, | 1796 return Bind(new InstantiateTypeArgumentsInstr(token_pos, |
| 1781 type_arguments, | 1797 type_arguments, |
| 1782 instantiator_value)); | 1798 instantiator_value)); |
| 1783 } | 1799 } |
| 1784 | 1800 |
| 1785 | 1801 |
| 1786 void EffectGraphVisitor::BuildConstructorTypeArguments( | 1802 void EffectGraphVisitor::BuildConstructorTypeArguments( |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1886 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); | 1902 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); |
| 1887 BuildConstructorCall(node, push_allocated_value); | 1903 BuildConstructorCall(node, push_allocated_value); |
| 1888 Definition* load_allocated = BuildLoadLocal( | 1904 Definition* load_allocated = BuildLoadLocal( |
| 1889 node->allocated_object_var()); | 1905 node->allocated_object_var()); |
| 1890 allocated_value = Bind(load_allocated); | 1906 allocated_value = Bind(load_allocated); |
| 1891 ReturnValue(allocated_value); | 1907 ReturnValue(allocated_value); |
| 1892 } | 1908 } |
| 1893 | 1909 |
| 1894 | 1910 |
| 1895 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { | 1911 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { |
| 1912 InlineBailout("EffectGraphVisitor::VisitInstanceGetterNode (deopt)"); |
| 1896 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1913 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 1897 node->receiver()->Visit(&for_receiver); | 1914 node->receiver()->Visit(&for_receiver); |
| 1898 Append(for_receiver); | 1915 Append(for_receiver); |
| 1899 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 1916 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 1900 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1917 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1901 new ZoneGrowableArray<PushArgumentInstr*>(1); | 1918 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 1902 arguments->Add(push_receiver); | 1919 arguments->Add(push_receiver); |
| 1903 const String& name = | 1920 const String& name = |
| 1904 String::ZoneHandle(Field::GetterSymbol(node->field_name())); | 1921 String::ZoneHandle(Field::GetterSymbol(node->field_name())); |
| 1905 InstanceCallInstr* call = new InstanceCallInstr( | 1922 InstanceCallInstr* call = new InstanceCallInstr( |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1926 if (result_is_needed) { | 1943 if (result_is_needed) { |
| 1927 value = Bind(BuildStoreExprTemp(for_value.value())); | 1944 value = Bind(BuildStoreExprTemp(for_value.value())); |
| 1928 } else { | 1945 } else { |
| 1929 value = for_value.value(); | 1946 value = for_value.value(); |
| 1930 } | 1947 } |
| 1931 arguments->Add(PushArgument(value)); | 1948 arguments->Add(PushArgument(value)); |
| 1932 } | 1949 } |
| 1933 | 1950 |
| 1934 | 1951 |
| 1935 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { | 1952 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| 1953 InlineBailout("EffectGraphVisitor::VisitInstanceSetterNode (deopt)"); |
| 1936 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1954 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1937 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1955 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1938 BuildInstanceSetterArguments(node, arguments, kResultNotNeeded); | 1956 BuildInstanceSetterArguments(node, arguments, kResultNotNeeded); |
| 1939 const String& name = | 1957 const String& name = |
| 1940 String::ZoneHandle(Field::SetterSymbol(node->field_name())); | 1958 String::ZoneHandle(Field::SetterSymbol(node->field_name())); |
| 1941 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), | 1959 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), |
| 1942 name, | 1960 name, |
| 1943 Token::kSET, | 1961 Token::kSET, |
| 1944 arguments, | 1962 arguments, |
| 1945 Array::ZoneHandle(), | 1963 Array::ZoneHandle(), |
| 1946 2); // Checked arg count. | 1964 2); // Checked arg count. |
| 1947 ReturnDefinition(call); | 1965 ReturnDefinition(call); |
| 1948 } | 1966 } |
| 1949 | 1967 |
| 1950 | 1968 |
| 1951 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { | 1969 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| 1970 InlineBailout("ValueGraphVisitor::VisitInstanceSetterNode (deopt)"); |
| 1952 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1971 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1953 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1972 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1954 BuildInstanceSetterArguments(node, arguments, kResultNeeded); | 1973 BuildInstanceSetterArguments(node, arguments, kResultNeeded); |
| 1955 const String& name = | 1974 const String& name = |
| 1956 String::ZoneHandle(Field::SetterSymbol(node->field_name())); | 1975 String::ZoneHandle(Field::SetterSymbol(node->field_name())); |
| 1957 Do(new InstanceCallInstr(node->token_pos(), | 1976 Do(new InstanceCallInstr(node->token_pos(), |
| 1958 name, | 1977 name, |
| 1959 Token::kSET, | 1978 Token::kSET, |
| 1960 arguments, | 1979 arguments, |
| 1961 Array::ZoneHandle(), | 1980 Array::ZoneHandle(), |
| 1962 2)); // Checked argument count. | 1981 2)); // Checked argument count. |
| 1963 ReturnDefinition(BuildLoadExprTemp()); | 1982 ReturnDefinition(BuildLoadExprTemp()); |
| 1964 } | 1983 } |
| 1965 | 1984 |
| 1966 | 1985 |
| 1967 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { | 1986 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { |
| 1987 InlineBailout("EffectGraphVisitor::VisitStaticGetterNode (deopt)"); |
| 1968 const String& getter_name = | 1988 const String& getter_name = |
| 1969 String::Handle(Field::GetterName(node->field_name())); | 1989 String::Handle(Field::GetterName(node->field_name())); |
| 1970 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1990 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1971 new ZoneGrowableArray<PushArgumentInstr*>(); | 1991 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 1972 Function& getter_function = Function::ZoneHandle(); | 1992 Function& getter_function = Function::ZoneHandle(); |
| 1973 if (node->is_super_getter()) { | 1993 if (node->is_super_getter()) { |
| 1974 // Statically resolved instance getter, i.e. "super getter". | 1994 // Statically resolved instance getter, i.e. "super getter". |
| 1975 getter_function = | 1995 getter_function = |
| 1976 Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); | 1996 Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); |
| 1977 ASSERT(!getter_function.IsNull()); | 1997 ASSERT(!getter_function.IsNull()); |
| 1978 ASSERT(node->receiver() != NULL); | 1998 ASSERT(node->receiver() != NULL); |
| 1979 ValueGraphVisitor receiver_value(owner(), temp_index()); | 1999 ValueGraphVisitor receiver_value(owner(), temp_index()); |
| 1980 node->receiver()->Visit(&receiver_value); | 2000 node->receiver()->Visit(&receiver_value); |
| 1981 Append(receiver_value); | 2001 Append(receiver_value); |
| 1982 arguments->Add(PushArgument(receiver_value.value())); | 2002 arguments->Add(PushArgument(receiver_value.value())); |
| 1983 } else { | 2003 } else { |
| 1984 getter_function = node->cls().LookupStaticFunction(getter_name); | 2004 getter_function = node->cls().LookupStaticFunction(getter_name); |
| 1985 ASSERT(!getter_function.IsNull()); | 2005 ASSERT(!getter_function.IsNull()); |
| 1986 } | 2006 } |
| 1987 StaticCallInstr* call = new StaticCallInstr(node->token_pos(), | 2007 StaticCallInstr* call = new StaticCallInstr(node->token_pos(), |
| 1988 getter_function, | 2008 getter_function, |
| 1989 Array::ZoneHandle(), // No names. | 2009 Array::ZoneHandle(), // No names. |
| 1990 arguments); | 2010 arguments); |
| 1991 ReturnDefinition(call); | 2011 ReturnDefinition(call); |
| 1992 } | 2012 } |
| 1993 | 2013 |
| 1994 | 2014 |
| 1995 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, | 2015 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, |
| 1996 bool result_is_needed) { | 2016 bool result_is_needed) { |
| 2017 InlineBailout("EffectGraphVisitor::VisitStaticSetter (deopt)"); |
| 1997 const String& setter_name = | 2018 const String& setter_name = |
| 1998 String::Handle(Field::SetterName(node->field_name())); | 2019 String::Handle(Field::SetterName(node->field_name())); |
| 1999 // A super setter is an instance setter whose setter function is | 2020 // A super setter is an instance setter whose setter function is |
| 2000 // resolved at compile time (in the caller instance getter's super class). | 2021 // resolved at compile time (in the caller instance getter's super class). |
| 2001 // Unlike a static getter, a super getter has a receiver parameter. | 2022 // Unlike a static getter, a super getter has a receiver parameter. |
| 2002 const bool is_super_setter = (node->receiver() != NULL); | 2023 const bool is_super_setter = (node->receiver() != NULL); |
| 2003 const Function& setter_function = | 2024 const Function& setter_function = |
| 2004 Function::ZoneHandle(is_super_setter | 2025 Function::ZoneHandle(is_super_setter |
| 2005 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name) | 2026 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name) |
| 2006 : node->cls().LookupStaticFunction(setter_name)); | 2027 : node->cls().LookupStaticFunction(setter_name)); |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2195 ReturnDefinition(BuildStoreStaticField(node, kResultNotNeeded)); | 2216 ReturnDefinition(BuildStoreStaticField(node, kResultNotNeeded)); |
| 2196 } | 2217 } |
| 2197 | 2218 |
| 2198 | 2219 |
| 2199 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { | 2220 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
| 2200 ReturnDefinition(BuildStoreStaticField(node, kResultNeeded)); | 2221 ReturnDefinition(BuildStoreStaticField(node, kResultNeeded)); |
| 2201 } | 2222 } |
| 2202 | 2223 |
| 2203 | 2224 |
| 2204 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { | 2225 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { |
| 2226 InlineBailout("EffectGraphVisitor::VisitLoadIndexedNode (deopt)"); |
| 2205 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2227 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2206 new ZoneGrowableArray<PushArgumentInstr*>(2); | 2228 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 2207 ValueGraphVisitor for_array(owner(), temp_index()); | 2229 ValueGraphVisitor for_array(owner(), temp_index()); |
| 2208 node->array()->Visit(&for_array); | 2230 node->array()->Visit(&for_array); |
| 2209 Append(for_array); | 2231 Append(for_array); |
| 2210 arguments->Add(PushArgument(for_array.value())); | 2232 arguments->Add(PushArgument(for_array.value())); |
| 2211 | 2233 |
| 2212 ValueGraphVisitor for_index(owner(), temp_index()); | 2234 ValueGraphVisitor for_index(owner(), temp_index()); |
| 2213 node->index_expr()->Visit(&for_index); | 2235 node->index_expr()->Visit(&for_index); |
| 2214 Append(for_index); | 2236 Append(for_index); |
| 2215 arguments->Add(PushArgument(for_index.value())); | 2237 arguments->Add(PushArgument(for_index.value())); |
| 2216 | 2238 |
| 2217 const intptr_t checked_argument_count = 1; | 2239 const intptr_t checked_argument_count = 1; |
| 2218 const String& name = | 2240 const String& name = |
| 2219 String::ZoneHandle(Symbols::New(Token::Str(Token::kINDEX))); | 2241 String::ZoneHandle(Symbols::New(Token::Str(Token::kINDEX))); |
| 2220 InstanceCallInstr* load = new InstanceCallInstr(node->token_pos(), | 2242 InstanceCallInstr* load = new InstanceCallInstr(node->token_pos(), |
| 2221 name, | 2243 name, |
| 2222 Token::kINDEX, | 2244 Token::kINDEX, |
| 2223 arguments, | 2245 arguments, |
| 2224 Array::ZoneHandle(), | 2246 Array::ZoneHandle(), |
| 2225 checked_argument_count); | 2247 checked_argument_count); |
| 2226 ReturnDefinition(load); | 2248 ReturnDefinition(load); |
| 2227 } | 2249 } |
| 2228 | 2250 |
| 2229 | 2251 |
| 2230 Definition* EffectGraphVisitor::BuildStoreIndexedValues( | 2252 Definition* EffectGraphVisitor::BuildStoreIndexedValues( |
| 2231 StoreIndexedNode* node, | 2253 StoreIndexedNode* node, |
| 2232 bool result_is_needed) { | 2254 bool result_is_needed) { |
| 2255 InlineBailout("EffectGraphVisitor::BuildStoreIndexedValues (deopt)"); |
| 2233 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2256 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2234 new ZoneGrowableArray<PushArgumentInstr*>(3); | 2257 new ZoneGrowableArray<PushArgumentInstr*>(3); |
| 2235 ValueGraphVisitor for_array(owner(), temp_index()); | 2258 ValueGraphVisitor for_array(owner(), temp_index()); |
| 2236 node->array()->Visit(&for_array); | 2259 node->array()->Visit(&for_array); |
| 2237 Append(for_array); | 2260 Append(for_array); |
| 2238 arguments->Add(PushArgument(for_array.value())); | 2261 arguments->Add(PushArgument(for_array.value())); |
| 2239 | 2262 |
| 2240 ValueGraphVisitor for_index(owner(), temp_index()); | 2263 ValueGraphVisitor for_index(owner(), temp_index()); |
| 2241 node->index_expr()->Visit(&for_index); | 2264 node->index_expr()->Visit(&for_index); |
| 2242 Append(for_index); | 2265 Append(for_index); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2281 } | 2304 } |
| 2282 | 2305 |
| 2283 | 2306 |
| 2284 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { | 2307 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { |
| 2285 return (node == owner()->parsed_function().node_sequence()) && | 2308 return (node == owner()->parsed_function().node_sequence()) && |
| 2286 (owner()->parsed_function().saved_context_var() != NULL); | 2309 (owner()->parsed_function().saved_context_var() != NULL); |
| 2287 } | 2310 } |
| 2288 | 2311 |
| 2289 | 2312 |
| 2290 void EffectGraphVisitor::UnchainContext() { | 2313 void EffectGraphVisitor::UnchainContext() { |
| 2291 InlineBailout("EffectGraphVisitor::UnchainContext (context)"); | 2314 InlineBailout("EffectGraphVisitor::UnchainContext (deopt)"); |
| 2292 Value* context = Bind(new CurrentContextInstr()); | 2315 Value* context = Bind(new CurrentContextInstr()); |
| 2293 Value* parent = Bind( | 2316 Value* parent = Bind( |
| 2294 new LoadFieldInstr(context, | 2317 new LoadFieldInstr(context, |
| 2295 Context::parent_offset(), | 2318 Context::parent_offset(), |
| 2296 Type::ZoneHandle())); // Not an instance, no type. | 2319 Type::ZoneHandle())); // Not an instance, no type. |
| 2297 Do(new StoreContextInstr(parent)); | 2320 Do(new StoreContextInstr(parent)); |
| 2298 } | 2321 } |
| 2299 | 2322 |
| 2300 | 2323 |
| 2301 // <Statement> ::= Sequence { scope: LocalScope | 2324 // <Statement> ::= Sequence { scope: LocalScope |
| 2302 // nodes: <Statement>* | 2325 // nodes: <Statement>* |
| 2303 // label: SourceLabel } | 2326 // label: SourceLabel } |
| 2304 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { | 2327 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { |
| 2305 LocalScope* scope = node->scope(); | 2328 LocalScope* scope = node->scope(); |
| 2306 const intptr_t num_context_variables = | 2329 const intptr_t num_context_variables = |
| 2307 (scope != NULL) ? scope->num_context_variables() : 0; | 2330 (scope != NULL) ? scope->num_context_variables() : 0; |
| 2308 int previous_context_level = owner()->context_level(); | 2331 int previous_context_level = owner()->context_level(); |
| 2309 if (num_context_variables > 0) { | 2332 if (num_context_variables > 0) { |
| 2310 InlineBailout("EffectGraphVisitor::VisitSequenceNode (context)"); | 2333 InlineBailout("EffectGraphVisitor::VisitSequenceNode (deopt)"); |
| 2311 // The loop local scope declares variables that are captured. | 2334 // The loop local scope declares variables that are captured. |
| 2312 // Allocate and chain a new context. | 2335 // Allocate and chain a new context. |
| 2313 // Allocate context computation (uses current CTX) | 2336 // Allocate context computation (uses current CTX) |
| 2314 Value* allocated_context = | 2337 Value* allocated_context = |
| 2315 Bind(new AllocateContextInstr(node->token_pos(), | 2338 Bind(new AllocateContextInstr(node->token_pos(), |
| 2316 num_context_variables)); | 2339 num_context_variables)); |
| 2317 | 2340 |
| 2318 // If this node_sequence is the body of the function being compiled, and if | 2341 // If this node_sequence is the body of the function being compiled, and if |
| 2319 // this function is not a closure, do not link the current context as the | 2342 // this function is not a closure, do not link the current context as the |
| 2320 // parent of the newly allocated context, as it is not accessible. Instead, | 2343 // parent of the newly allocated context, as it is not accessible. Instead, |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2438 } | 2461 } |
| 2439 | 2462 |
| 2440 // The outermost function sequence cannot contain a label. | 2463 // The outermost function sequence cannot contain a label. |
| 2441 ASSERT((node->label() == NULL) || | 2464 ASSERT((node->label() == NULL) || |
| 2442 (node != owner()->parsed_function().node_sequence())); | 2465 (node != owner()->parsed_function().node_sequence())); |
| 2443 owner()->set_context_level(previous_context_level); | 2466 owner()->set_context_level(previous_context_level); |
| 2444 } | 2467 } |
| 2445 | 2468 |
| 2446 | 2469 |
| 2447 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { | 2470 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { |
| 2448 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)"); | 2471 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode"); |
| 2449 // NOTE: The implicit variables ':saved_context', ':exception_var' | 2472 // NOTE: The implicit variables ':saved_context', ':exception_var' |
| 2450 // and ':stacktrace_var' can never be captured variables. | 2473 // and ':stacktrace_var' can never be captured variables. |
| 2451 // Restores CTX from local variable ':saved_context'. | 2474 // Restores CTX from local variable ':saved_context'. |
| 2452 Do(new CatchEntryInstr(node->exception_var(), node->stacktrace_var())); | 2475 Do(new CatchEntryInstr(node->exception_var(), node->stacktrace_var())); |
| 2453 BuildLoadContext(node->context_var()); | 2476 BuildLoadContext(node->context_var()); |
| 2454 | 2477 |
| 2455 EffectGraphVisitor for_catch(owner(), temp_index()); | 2478 EffectGraphVisitor for_catch(owner(), temp_index()); |
| 2456 node->VisitChildren(&for_catch); | 2479 node->VisitChildren(&for_catch); |
| 2457 Append(for_catch); | 2480 Append(for_catch); |
| 2458 } | 2481 } |
| 2459 | 2482 |
| 2460 | 2483 |
| 2461 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { | 2484 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { |
| 2462 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); | 2485 InlineBailout("EffectGraphVisitor::VisitTryCatchNode"); |
| 2463 intptr_t old_try_index = owner()->try_index(); | 2486 intptr_t old_try_index = owner()->try_index(); |
| 2464 intptr_t try_index = owner()->AllocateTryIndex(); | 2487 intptr_t try_index = owner()->AllocateTryIndex(); |
| 2465 owner()->set_try_index(try_index); | 2488 owner()->set_try_index(try_index); |
| 2466 | 2489 |
| 2467 // Preserve CTX into local variable '%saved_context'. | 2490 // Preserve CTX into local variable '%saved_context'. |
| 2468 BuildStoreContext(node->context_var()); | 2491 BuildStoreContext(node->context_var()); |
| 2469 | 2492 |
| 2470 EffectGraphVisitor for_try_block(owner(), temp_index()); | 2493 EffectGraphVisitor for_try_block(owner(), temp_index()); |
| 2471 node->try_block()->Visit(&for_try_block); | 2494 node->try_block()->Visit(&for_try_block); |
| 2472 | 2495 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2544 // A throw cannot be part of an expression, however, the parser may replace | 2567 // A throw cannot be part of an expression, however, the parser may replace |
| 2545 // certain expression nodes with a throw. In that case generate a literal null | 2568 // certain expression nodes with a throw. In that case generate a literal null |
| 2546 // so that the fragment is not closed in the middle of an expression. | 2569 // so that the fragment is not closed in the middle of an expression. |
| 2547 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { | 2570 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { |
| 2548 BuildThrowNode(node); | 2571 BuildThrowNode(node); |
| 2549 ReturnDefinition(new ConstantInstr(Instance::ZoneHandle())); | 2572 ReturnDefinition(new ConstantInstr(Instance::ZoneHandle())); |
| 2550 } | 2573 } |
| 2551 | 2574 |
| 2552 | 2575 |
| 2553 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { | 2576 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { |
| 2554 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode (exception)"); | 2577 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode"); |
| 2555 const intptr_t try_index = owner()->try_index(); | 2578 const intptr_t try_index = owner()->try_index(); |
| 2556 if (try_index >= 0) { | 2579 if (try_index >= 0) { |
| 2557 // We are about to generate code for an inlined finally block. Exceptions | 2580 // We are about to generate code for an inlined finally block. Exceptions |
| 2558 // thrown in this block of code should be treated as though they are | 2581 // thrown in this block of code should be treated as though they are |
| 2559 // thrown not from the current try block but the outer try block if any. | 2582 // thrown not from the current try block but the outer try block if any. |
| 2560 owner()->set_try_index((try_index - 1)); | 2583 owner()->set_try_index((try_index - 1)); |
| 2561 } | 2584 } |
| 2562 BuildLoadContext(node->context_var()); | 2585 BuildLoadContext(node->context_var()); |
| 2563 | 2586 |
| 2564 JoinEntryInstr* finally_entry = new JoinEntryInstr(owner()->try_index()); | 2587 JoinEntryInstr* finally_entry = new JoinEntryInstr(owner()->try_index()); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2589 // Set the inlining context. | 2612 // Set the inlining context. |
| 2590 ASSERT(inlining_context_ == kNotInlining); | 2613 ASSERT(inlining_context_ == kNotInlining); |
| 2591 inlining_context_ = context; | 2614 inlining_context_ = context; |
| 2592 if (InInliningContext()) exits_ = new ZoneGrowableArray<ReturnInstr*>(); | 2615 if (InInliningContext()) exits_ = new ZoneGrowableArray<ReturnInstr*>(); |
| 2593 // Compilation can be nested, preserve the computation-id. | 2616 // Compilation can be nested, preserve the computation-id. |
| 2594 const Function& function = parsed_function().function(); | 2617 const Function& function = parsed_function().function(); |
| 2595 TargetEntryInstr* normal_entry = new TargetEntryInstr( | 2618 TargetEntryInstr* normal_entry = new TargetEntryInstr( |
| 2596 CatchClauseNode::kInvalidTryIndex); | 2619 CatchClauseNode::kInvalidTryIndex); |
| 2597 graph_entry_ = new GraphEntryInstr(normal_entry); | 2620 graph_entry_ = new GraphEntryInstr(normal_entry); |
| 2598 EffectGraphVisitor for_effect(this, 0); | 2621 EffectGraphVisitor for_effect(this, 0); |
| 2599 if (InInliningContext()) { | |
| 2600 exits_ = new ZoneGrowableArray<ReturnInstr*>(); | |
| 2601 } | |
| 2602 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the | 2622 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the |
| 2603 // stack check on entry for leaf routines). | 2623 // stack check on entry for leaf routines). |
| 2604 for_effect.Do(new CheckStackOverflowInstr(function.token_pos())); | 2624 for_effect.Do(new CheckStackOverflowInstr(function.token_pos())); |
| 2605 parsed_function().node_sequence()->Visit(&for_effect); | 2625 parsed_function().node_sequence()->Visit(&for_effect); |
| 2606 AppendFragment(normal_entry, for_effect); | 2626 AppendFragment(normal_entry, for_effect); |
| 2607 // Check that the graph is properly terminated. | 2627 // Check that the graph is properly terminated. |
| 2608 ASSERT(!for_effect.is_open()); | 2628 ASSERT(!for_effect.is_open()); |
| 2609 FlowGraph* graph = new FlowGraph(*this, graph_entry_); | 2629 FlowGraph* graph = new FlowGraph(*this, graph_entry_); |
| 2610 if (InInliningContext()) graph->set_exits(exits_); | 2630 if (InInliningContext()) graph->set_exits(exits_); |
| 2611 return graph; | 2631 return graph; |
| 2612 } | 2632 } |
| 2613 | 2633 |
| 2614 | 2634 |
| 2615 void FlowGraphBuilder::Bailout(const char* reason) { | 2635 void FlowGraphBuilder::Bailout(const char* reason) { |
| 2616 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; | 2636 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; |
| 2617 const char* function_name = parsed_function_.function().ToCString(); | 2637 const char* function_name = parsed_function_.function().ToCString(); |
| 2618 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 2638 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 2619 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 2639 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 2620 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2640 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2621 const Error& error = Error::Handle( | 2641 const Error& error = Error::Handle( |
| 2622 LanguageError::New(String::Handle(String::New(chars)))); | 2642 LanguageError::New(String::Handle(String::New(chars)))); |
| 2623 Isolate::Current()->long_jump_base()->Jump(1, error); | 2643 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2624 } | 2644 } |
| 2625 | 2645 |
| 2626 | 2646 |
| 2627 } // namespace dart | 2647 } // namespace dart |
| OLD | NEW |