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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
986 } | 986 } |
987 | 987 |
988 | 988 |
989 BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const { | 989 BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const { |
990 return CreateSuccessorFor(false_successor_addresses_); | 990 return CreateSuccessorFor(false_successor_addresses_); |
991 } | 991 } |
992 | 992 |
993 | 993 |
994 void TestGraphVisitor::ReturnValue(Value* value) { | 994 void TestGraphVisitor::ReturnValue(Value* value) { |
995 Isolate* isolate = Isolate::Current(); | 995 Isolate* isolate = Isolate::Current(); |
996 if (isolate->flags().type_checks() || isolate->flags().asserts()) { | 996 if (isolate->type_checks() || isolate->asserts()) { |
997 value = Bind(new(Z) AssertBooleanInstr(condition_token_pos(), value)); | 997 value = Bind(new(Z) AssertBooleanInstr(condition_token_pos(), value)); |
998 } | 998 } |
999 Value* constant_true = Bind(new(Z) ConstantInstr(Bool::True())); | 999 Value* constant_true = Bind(new(Z) ConstantInstr(Bool::True())); |
1000 StrictCompareInstr* comp = | 1000 StrictCompareInstr* comp = |
1001 new(Z) StrictCompareInstr(condition_token_pos(), | 1001 new(Z) StrictCompareInstr(condition_token_pos(), |
1002 Token::kEQ_STRICT, | 1002 Token::kEQ_STRICT, |
1003 value, | 1003 value, |
1004 constant_true, | 1004 constant_true, |
1005 false); // No number check. | 1005 false); // No number check. |
1006 BranchInstr* branch = new(Z) BranchInstr(comp); | 1006 BranchInstr* branch = new(Z) BranchInstr(comp); |
(...skipping 14 matching lines...) Expand all Loading... |
1021 (comp->left()->BindsToConstantNull() || | 1021 (comp->left()->BindsToConstantNull() || |
1022 comp->right()->BindsToConstantNull())) { | 1022 comp->right()->BindsToConstantNull())) { |
1023 branch = new(Z) BranchInstr(new(Z) StrictCompareInstr( | 1023 branch = new(Z) BranchInstr(new(Z) StrictCompareInstr( |
1024 comp->token_pos(), | 1024 comp->token_pos(), |
1025 (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT, | 1025 (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT, |
1026 comp->left(), | 1026 comp->left(), |
1027 comp->right(), | 1027 comp->right(), |
1028 false)); // No number check. | 1028 false)); // No number check. |
1029 } else { | 1029 } else { |
1030 branch = new(Z) BranchInstr(comp); | 1030 branch = new(Z) BranchInstr(comp); |
1031 branch->set_is_checked(Isolate::Current()->flags().type_checks()); | 1031 branch->set_is_checked(Isolate::Current()->type_checks()); |
1032 } | 1032 } |
1033 AddInstruction(branch); | 1033 AddInstruction(branch); |
1034 CloseFragment(); | 1034 CloseFragment(); |
1035 true_successor_addresses_.Add(branch->true_successor_address()); | 1035 true_successor_addresses_.Add(branch->true_successor_address()); |
1036 false_successor_addresses_.Add(branch->false_successor_address()); | 1036 false_successor_addresses_.Add(branch->false_successor_address()); |
1037 } | 1037 } |
1038 | 1038 |
1039 | 1039 |
1040 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) { | 1040 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) { |
1041 ASSERT(!Isolate::Current()->flags().type_checks()); | 1041 ASSERT(!Isolate::Current()->type_checks()); |
1042 Value* constant_true = Bind(new(Z) ConstantInstr(Bool::True())); | 1042 Value* constant_true = Bind(new(Z) ConstantInstr(Bool::True())); |
1043 StrictCompareInstr* comp = | 1043 StrictCompareInstr* comp = |
1044 new(Z) StrictCompareInstr(condition_token_pos(), | 1044 new(Z) StrictCompareInstr(condition_token_pos(), |
1045 Token::kNE_STRICT, | 1045 Token::kNE_STRICT, |
1046 neg->value(), | 1046 neg->value(), |
1047 constant_true, | 1047 constant_true, |
1048 false); // No number check. | 1048 false); // No number check. |
1049 BranchInstr* branch = new(Z) BranchInstr(comp); | 1049 BranchInstr* branch = new(Z) BranchInstr(comp); |
1050 AddInstruction(branch); | 1050 AddInstruction(branch); |
1051 CloseFragment(); | 1051 CloseFragment(); |
1052 true_successor_addresses_.Add(branch->true_successor_address()); | 1052 true_successor_addresses_.Add(branch->true_successor_address()); |
1053 false_successor_addresses_.Add(branch->false_successor_address()); | 1053 false_successor_addresses_.Add(branch->false_successor_address()); |
1054 } | 1054 } |
1055 | 1055 |
1056 | 1056 |
1057 void TestGraphVisitor::ReturnDefinition(Definition* definition) { | 1057 void TestGraphVisitor::ReturnDefinition(Definition* definition) { |
1058 ComparisonInstr* comp = definition->AsComparison(); | 1058 ComparisonInstr* comp = definition->AsComparison(); |
1059 if (comp != NULL) { | 1059 if (comp != NULL) { |
1060 MergeBranchWithComparison(comp); | 1060 MergeBranchWithComparison(comp); |
1061 return; | 1061 return; |
1062 } | 1062 } |
1063 if (!Isolate::Current()->flags().type_checks()) { | 1063 if (!Isolate::Current()->type_checks()) { |
1064 BooleanNegateInstr* neg = definition->AsBooleanNegate(); | 1064 BooleanNegateInstr* neg = definition->AsBooleanNegate(); |
1065 if (neg != NULL) { | 1065 if (neg != NULL) { |
1066 MergeBranchWithNegate(neg); | 1066 MergeBranchWithNegate(neg); |
1067 return; | 1067 return; |
1068 } | 1068 } |
1069 } | 1069 } |
1070 ReturnValue(Bind(definition)); | 1070 ReturnValue(Bind(definition)); |
1071 } | 1071 } |
1072 | 1072 |
1073 | 1073 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1146 EffectGraphVisitor for_effect(owner()); | 1146 EffectGraphVisitor for_effect(owner()); |
1147 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); | 1147 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
1148 Append(for_effect); | 1148 Append(for_effect); |
1149 if (!is_open()) { | 1149 if (!is_open()) { |
1150 return; | 1150 return; |
1151 } | 1151 } |
1152 } | 1152 } |
1153 return_value = Bind(BuildLoadLocal(*temp, node->token_pos())); | 1153 return_value = Bind(BuildLoadLocal(*temp, node->token_pos())); |
1154 } | 1154 } |
1155 | 1155 |
1156 if (Isolate::Current()->flags().type_checks()) { | 1156 if (Isolate::Current()->type_checks()) { |
1157 const bool is_implicit_dynamic_getter = | 1157 const bool is_implicit_dynamic_getter = |
1158 (!function.is_static() && | 1158 (!function.is_static() && |
1159 ((function.kind() == RawFunction::kImplicitGetter) || | 1159 ((function.kind() == RawFunction::kImplicitGetter) || |
1160 (function.kind() == RawFunction::kImplicitStaticFinalGetter))); | 1160 (function.kind() == RawFunction::kImplicitStaticFinalGetter))); |
1161 // Implicit getters do not need a type check at return, unless they compute | 1161 // Implicit getters do not need a type check at return, unless they compute |
1162 // the initial value of a static field. | 1162 // the initial value of a static field. |
1163 // The body of a constructor cannot modify the type of the | 1163 // The body of a constructor cannot modify the type of the |
1164 // constructed instance, which is passed in as an implicit parameter. | 1164 // constructed instance, which is passed in as an implicit parameter. |
1165 // However, factories may create an instance of the wrong type. | 1165 // However, factories may create an instance of the wrong type. |
1166 if (!is_implicit_dynamic_getter && !function.IsGenerativeConstructor()) { | 1166 if (!is_implicit_dynamic_getter && !function.IsGenerativeConstructor()) { |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1347 // right: <Expression> } | 1347 // right: <Expression> } |
1348 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 1348 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
1349 // Operators "&&" and "||" cannot be overloaded therefore do not call | 1349 // Operators "&&" and "||" cannot be overloaded therefore do not call |
1350 // operator. | 1350 // operator. |
1351 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 1351 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
1352 // See ValueGraphVisitor::VisitBinaryOpNode. | 1352 // See ValueGraphVisitor::VisitBinaryOpNode. |
1353 TestGraphVisitor for_left(owner(), node->left()->token_pos()); | 1353 TestGraphVisitor for_left(owner(), node->left()->token_pos()); |
1354 node->left()->Visit(&for_left); | 1354 node->left()->Visit(&for_left); |
1355 EffectGraphVisitor empty(owner()); | 1355 EffectGraphVisitor empty(owner()); |
1356 Isolate* isolate = Isolate::Current(); | 1356 Isolate* isolate = Isolate::Current(); |
1357 if (isolate->flags().type_checks() || isolate->flags().asserts()) { | 1357 if (isolate->type_checks() || isolate->asserts()) { |
1358 ValueGraphVisitor for_right(owner()); | 1358 ValueGraphVisitor for_right(owner()); |
1359 node->right()->Visit(&for_right); | 1359 node->right()->Visit(&for_right); |
1360 Value* right_value = for_right.value(); | 1360 Value* right_value = for_right.value(); |
1361 for_right.Do(new(Z) AssertBooleanInstr(node->right()->token_pos(), | 1361 for_right.Do(new(Z) AssertBooleanInstr(node->right()->token_pos(), |
1362 right_value)); | 1362 right_value)); |
1363 if (node->kind() == Token::kAND) { | 1363 if (node->kind() == Token::kAND) { |
1364 Join(for_left, for_right, empty); | 1364 Join(for_left, for_right, empty); |
1365 } else { | 1365 } else { |
1366 Join(for_left, empty, for_right); | 1366 Join(for_left, empty, for_right); |
1367 } | 1367 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1414 // AND: left ? right === true : false; | 1414 // AND: left ? right === true : false; |
1415 // OR: left ? true : right === true; | 1415 // OR: left ? true : right === true; |
1416 | 1416 |
1417 TestGraphVisitor for_test(owner(), node->left()->token_pos()); | 1417 TestGraphVisitor for_test(owner(), node->left()->token_pos()); |
1418 node->left()->Visit(&for_test); | 1418 node->left()->Visit(&for_test); |
1419 | 1419 |
1420 ValueGraphVisitor for_right(owner()); | 1420 ValueGraphVisitor for_right(owner()); |
1421 node->right()->Visit(&for_right); | 1421 node->right()->Visit(&for_right); |
1422 Value* right_value = for_right.value(); | 1422 Value* right_value = for_right.value(); |
1423 Isolate* isolate = Isolate::Current(); | 1423 Isolate* isolate = Isolate::Current(); |
1424 if (isolate->flags().type_checks() || isolate->flags().asserts()) { | 1424 if (isolate->type_checks() || isolate->asserts()) { |
1425 right_value = | 1425 right_value = |
1426 for_right.Bind(new(Z) AssertBooleanInstr(node->right()->token_pos(), | 1426 for_right.Bind(new(Z) AssertBooleanInstr(node->right()->token_pos(), |
1427 right_value)); | 1427 right_value)); |
1428 } | 1428 } |
1429 Value* constant_true = for_right.Bind(new(Z) ConstantInstr(Bool::True())); | 1429 Value* constant_true = for_right.Bind(new(Z) ConstantInstr(Bool::True())); |
1430 Value* compare = | 1430 Value* compare = |
1431 for_right.Bind(new(Z) StrictCompareInstr(node->token_pos(), | 1431 for_right.Bind(new(Z) StrictCompareInstr(node->token_pos(), |
1432 Token::kEQ_STRICT, | 1432 Token::kEQ_STRICT, |
1433 right_value, | 1433 right_value, |
1434 constant_true, | 1434 constant_true, |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1793 Definition* result = new(Z) InstanceCallInstr( | 1793 Definition* result = new(Z) InstanceCallInstr( |
1794 node->token_pos(), | 1794 node->token_pos(), |
1795 Symbols::EqualOperator(), | 1795 Symbols::EqualOperator(), |
1796 Token::kEQ, // Result is negated later for kNE. | 1796 Token::kEQ, // Result is negated later for kNE. |
1797 arguments, | 1797 arguments, |
1798 Object::null_array(), | 1798 Object::null_array(), |
1799 kNumArgsChecked, | 1799 kNumArgsChecked, |
1800 owner()->ic_data_array()); | 1800 owner()->ic_data_array()); |
1801 if (node->kind() == Token::kNE) { | 1801 if (node->kind() == Token::kNE) { |
1802 Isolate* isolate = Isolate::Current(); | 1802 Isolate* isolate = Isolate::Current(); |
1803 if (isolate->flags().type_checks() || isolate->flags().asserts()) { | 1803 if (isolate->type_checks() || isolate->asserts()) { |
1804 Value* value = Bind(result); | 1804 Value* value = Bind(result); |
1805 result = new(Z) AssertBooleanInstr(node->token_pos(), value); | 1805 result = new(Z) AssertBooleanInstr(node->token_pos(), value); |
1806 } | 1806 } |
1807 Value* value = Bind(result); | 1807 Value* value = Bind(result); |
1808 result = new(Z) BooleanNegateInstr(value); | 1808 result = new(Z) BooleanNegateInstr(value); |
1809 } | 1809 } |
1810 ReturnDefinition(result); | 1810 ReturnDefinition(result); |
1811 return; | 1811 return; |
1812 } | 1812 } |
1813 | 1813 |
(...skipping 26 matching lines...) Expand all Loading... |
1840 | 1840 |
1841 | 1841 |
1842 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { | 1842 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { |
1843 // "!" cannot be overloaded, therefore do not call operator. | 1843 // "!" cannot be overloaded, therefore do not call operator. |
1844 if (node->kind() == Token::kNOT) { | 1844 if (node->kind() == Token::kNOT) { |
1845 ValueGraphVisitor for_value(owner()); | 1845 ValueGraphVisitor for_value(owner()); |
1846 node->operand()->Visit(&for_value); | 1846 node->operand()->Visit(&for_value); |
1847 Append(for_value); | 1847 Append(for_value); |
1848 Value* value = for_value.value(); | 1848 Value* value = for_value.value(); |
1849 Isolate* isolate = Isolate::Current(); | 1849 Isolate* isolate = Isolate::Current(); |
1850 if (isolate->flags().type_checks() || isolate->flags().asserts()) { | 1850 if (isolate->type_checks() || isolate->asserts()) { |
1851 value = | 1851 value = |
1852 Bind(new(Z) AssertBooleanInstr(node->operand()->token_pos(), value)); | 1852 Bind(new(Z) AssertBooleanInstr(node->operand()->token_pos(), value)); |
1853 } | 1853 } |
1854 BooleanNegateInstr* negate = new(Z) BooleanNegateInstr(value); | 1854 BooleanNegateInstr* negate = new(Z) BooleanNegateInstr(value); |
1855 ReturnDefinition(negate); | 1855 ReturnDefinition(negate); |
1856 return; | 1856 return; |
1857 } | 1857 } |
1858 | 1858 |
1859 ValueGraphVisitor for_value(owner()); | 1859 ValueGraphVisitor for_value(owner()); |
1860 node->operand()->Visit(&for_value); | 1860 node->operand()->Visit(&for_value); |
(...skipping 1774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3635 node->token_pos().IsDebugPause()) { | 3635 node->token_pos().IsDebugPause()) { |
3636 AddInstruction(new(Z) DebugStepCheckInstr( | 3636 AddInstruction(new(Z) DebugStepCheckInstr( |
3637 node->token_pos(), RawPcDescriptors::kRuntimeCall)); | 3637 node->token_pos(), RawPcDescriptors::kRuntimeCall)); |
3638 } | 3638 } |
3639 } | 3639 } |
3640 | 3640 |
3641 ValueGraphVisitor for_value(owner()); | 3641 ValueGraphVisitor for_value(owner()); |
3642 node->value()->Visit(&for_value); | 3642 node->value()->Visit(&for_value); |
3643 Append(for_value); | 3643 Append(for_value); |
3644 Value* store_value = for_value.value(); | 3644 Value* store_value = for_value.value(); |
3645 if (Isolate::Current()->flags().type_checks()) { | 3645 if (Isolate::Current()->type_checks()) { |
3646 store_value = BuildAssignableValue(node->value()->token_pos(), | 3646 store_value = BuildAssignableValue(node->value()->token_pos(), |
3647 store_value, | 3647 store_value, |
3648 node->local().type(), | 3648 node->local().type(), |
3649 node->local().name()); | 3649 node->local().name()); |
3650 } | 3650 } |
3651 Definition* store = BuildStoreLocal(node->local(), | 3651 Definition* store = BuildStoreLocal(node->local(), |
3652 store_value, | 3652 store_value, |
3653 node->token_pos()); | 3653 node->token_pos()); |
3654 ReturnDefinition(store); | 3654 ReturnDefinition(store); |
3655 } | 3655 } |
(...skipping 23 matching lines...) Expand all Loading... |
3679 void EffectGraphVisitor::VisitStoreInstanceFieldNode( | 3679 void EffectGraphVisitor::VisitStoreInstanceFieldNode( |
3680 StoreInstanceFieldNode* node) { | 3680 StoreInstanceFieldNode* node) { |
3681 const TokenPosition token_pos = node->token_pos(); | 3681 const TokenPosition token_pos = node->token_pos(); |
3682 ValueGraphVisitor for_instance(owner()); | 3682 ValueGraphVisitor for_instance(owner()); |
3683 node->instance()->Visit(&for_instance); | 3683 node->instance()->Visit(&for_instance); |
3684 Append(for_instance); | 3684 Append(for_instance); |
3685 ValueGraphVisitor for_value(owner()); | 3685 ValueGraphVisitor for_value(owner()); |
3686 node->value()->Visit(&for_value); | 3686 node->value()->Visit(&for_value); |
3687 Append(for_value); | 3687 Append(for_value); |
3688 Value* store_value = for_value.value(); | 3688 Value* store_value = for_value.value(); |
3689 if (Isolate::Current()->flags().type_checks()) { | 3689 if (Isolate::Current()->type_checks()) { |
3690 const AbstractType& type = | 3690 const AbstractType& type = |
3691 AbstractType::ZoneHandle(Z, node->field().type()); | 3691 AbstractType::ZoneHandle(Z, node->field().type()); |
3692 const String& dst_name = String::ZoneHandle(Z, node->field().name()); | 3692 const String& dst_name = String::ZoneHandle(Z, node->field().name()); |
3693 store_value = BuildAssignableValue(node->value()->token_pos(), | 3693 store_value = BuildAssignableValue(node->value()->token_pos(), |
3694 store_value, | 3694 store_value, |
3695 type, | 3695 type, |
3696 dst_name); | 3696 dst_name); |
3697 } | 3697 } |
3698 | 3698 |
3699 if (FLAG_use_field_guards) { | 3699 if (FLAG_use_field_guards) { |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4109 CheckStackOverflowInstr* check = | 4109 CheckStackOverflowInstr* check = |
4110 new(Z) CheckStackOverflowInstr(node->token_pos(), 0); | 4110 new(Z) CheckStackOverflowInstr(node->token_pos(), 0); |
4111 // If we are inlining don't actually attach the stack check. We must still | 4111 // If we are inlining don't actually attach the stack check. We must still |
4112 // create the stack check in order to allocate a deopt id. | 4112 // create the stack check in order to allocate a deopt id. |
4113 if (!owner()->IsInlining()) { | 4113 if (!owner()->IsInlining()) { |
4114 AddInstruction(check); | 4114 AddInstruction(check); |
4115 } | 4115 } |
4116 } | 4116 } |
4117 } | 4117 } |
4118 | 4118 |
4119 if (Isolate::Current()->flags().type_checks() && is_top_level_sequence) { | 4119 if (Isolate::Current()->type_checks() && is_top_level_sequence) { |
4120 const int num_params = function.NumParameters(); | 4120 const int num_params = function.NumParameters(); |
4121 int pos = 0; | 4121 int pos = 0; |
4122 if (function.IsFactory() || | 4122 if (function.IsFactory() || |
4123 function.IsDynamicFunction() || | 4123 function.IsDynamicFunction() || |
4124 function.IsGenerativeConstructor()) { | 4124 function.IsGenerativeConstructor()) { |
4125 // Skip type checking of type arguments for factory functions. | 4125 // Skip type checking of type arguments for factory functions. |
4126 // Skip type checking of receiver for instance functions and constructors. | 4126 // Skip type checking of receiver for instance functions and constructors. |
4127 pos = 1; | 4127 pos = 1; |
4128 } | 4128 } |
4129 while (pos < num_params) { | 4129 while (pos < num_params) { |
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4649 Script::Handle(function.script()), | 4649 Script::Handle(function.script()), |
4650 function.token_pos(), | 4650 function.token_pos(), |
4651 Report::AtLocation, | 4651 Report::AtLocation, |
4652 "FlowGraphBuilder Bailout: %s %s", | 4652 "FlowGraphBuilder Bailout: %s %s", |
4653 String::Handle(function.name()).ToCString(), | 4653 String::Handle(function.name()).ToCString(), |
4654 reason); | 4654 reason); |
4655 UNREACHABLE(); | 4655 UNREACHABLE(); |
4656 } | 4656 } |
4657 | 4657 |
4658 } // namespace dart | 4658 } // namespace dart |
OLD | NEW |