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

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

Issue 1162033005: Fix http://dartbug.com/23578: (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Update to ToT. Created 5 years, 6 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
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 "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/class_finalizer.h" 10 #include "vm/class_finalizer.h"
(...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 return CreateSuccessorFor(true_successor_addresses_); 944 return CreateSuccessorFor(true_successor_addresses_);
945 } 945 }
946 946
947 947
948 BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const { 948 BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const {
949 return CreateSuccessorFor(false_successor_addresses_); 949 return CreateSuccessorFor(false_successor_addresses_);
950 } 950 }
951 951
952 952
953 void TestGraphVisitor::ReturnValue(Value* value) { 953 void TestGraphVisitor::ReturnValue(Value* value) {
954 if (Isolate::Current()->TypeChecksEnabled() || 954 Isolate* isolate = Isolate::Current();
955 Isolate::Current()->AssertsEnabled()) { 955 if (isolate->flags().type_checks() ||
956 isolate->flags().asserts()) {
956 value = Bind(new(Z) AssertBooleanInstr(condition_token_pos(), value)); 957 value = Bind(new(Z) AssertBooleanInstr(condition_token_pos(), value));
957 } 958 }
958 Value* constant_true = Bind(new(Z) ConstantInstr(Bool::True())); 959 Value* constant_true = Bind(new(Z) ConstantInstr(Bool::True()));
959 StrictCompareInstr* comp = 960 StrictCompareInstr* comp =
960 new(Z) StrictCompareInstr(condition_token_pos(), 961 new(Z) StrictCompareInstr(condition_token_pos(),
961 Token::kEQ_STRICT, 962 Token::kEQ_STRICT,
962 value, 963 value,
963 constant_true, 964 constant_true,
964 false); // No number check. 965 false); // No number check.
965 BranchInstr* branch = new(Z) BranchInstr(comp); 966 BranchInstr* branch = new(Z) BranchInstr(comp);
(...skipping 14 matching lines...) Expand all
980 (comp->left()->BindsToConstantNull() || 981 (comp->left()->BindsToConstantNull() ||
981 comp->right()->BindsToConstantNull())) { 982 comp->right()->BindsToConstantNull())) {
982 branch = new(Z) BranchInstr(new(Z) StrictCompareInstr( 983 branch = new(Z) BranchInstr(new(Z) StrictCompareInstr(
983 comp->token_pos(), 984 comp->token_pos(),
984 (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT, 985 (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT,
985 comp->left(), 986 comp->left(),
986 comp->right(), 987 comp->right(),
987 false)); // No number check. 988 false)); // No number check.
988 } else { 989 } else {
989 branch = new(Z) BranchInstr(comp); 990 branch = new(Z) BranchInstr(comp);
990 branch->set_is_checked(Isolate::Current()->TypeChecksEnabled()); 991 branch->set_is_checked(Isolate::Current()->flags().type_checks());
991 } 992 }
992 AddInstruction(branch); 993 AddInstruction(branch);
993 CloseFragment(); 994 CloseFragment();
994 true_successor_addresses_.Add(branch->true_successor_address()); 995 true_successor_addresses_.Add(branch->true_successor_address());
995 false_successor_addresses_.Add(branch->false_successor_address()); 996 false_successor_addresses_.Add(branch->false_successor_address());
996 } 997 }
997 998
998 999
999 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) { 1000 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) {
1000 ASSERT(!Isolate::Current()->TypeChecksEnabled()); 1001 ASSERT(!Isolate::Current()->flags().type_checks());
1001 Value* constant_true = Bind(new(Z) ConstantInstr(Bool::True())); 1002 Value* constant_true = Bind(new(Z) ConstantInstr(Bool::True()));
1002 StrictCompareInstr* comp = 1003 StrictCompareInstr* comp =
1003 new(Z) StrictCompareInstr(condition_token_pos(), 1004 new(Z) StrictCompareInstr(condition_token_pos(),
1004 Token::kNE_STRICT, 1005 Token::kNE_STRICT,
1005 neg->value(), 1006 neg->value(),
1006 constant_true, 1007 constant_true,
1007 false); // No number check. 1008 false); // No number check.
1008 BranchInstr* branch = new(Z) BranchInstr(comp); 1009 BranchInstr* branch = new(Z) BranchInstr(comp);
1009 AddInstruction(branch); 1010 AddInstruction(branch);
1010 CloseFragment(); 1011 CloseFragment();
1011 true_successor_addresses_.Add(branch->true_successor_address()); 1012 true_successor_addresses_.Add(branch->true_successor_address());
1012 false_successor_addresses_.Add(branch->false_successor_address()); 1013 false_successor_addresses_.Add(branch->false_successor_address());
1013 } 1014 }
1014 1015
1015 1016
1016 void TestGraphVisitor::ReturnDefinition(Definition* definition) { 1017 void TestGraphVisitor::ReturnDefinition(Definition* definition) {
1017 ComparisonInstr* comp = definition->AsComparison(); 1018 ComparisonInstr* comp = definition->AsComparison();
1018 if (comp != NULL) { 1019 if (comp != NULL) {
1019 MergeBranchWithComparison(comp); 1020 MergeBranchWithComparison(comp);
1020 return; 1021 return;
1021 } 1022 }
1022 if (!Isolate::Current()->TypeChecksEnabled()) { 1023 if (!Isolate::Current()->flags().type_checks()) {
1023 BooleanNegateInstr* neg = definition->AsBooleanNegate(); 1024 BooleanNegateInstr* neg = definition->AsBooleanNegate();
1024 if (neg != NULL) { 1025 if (neg != NULL) {
1025 MergeBranchWithNegate(neg); 1026 MergeBranchWithNegate(neg);
1026 return; 1027 return;
1027 } 1028 }
1028 } 1029 }
1029 ReturnValue(Bind(definition)); 1030 ReturnValue(Bind(definition));
1030 } 1031 }
1031 1032
1032 1033
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1104 EffectGraphVisitor for_effect(owner()); 1105 EffectGraphVisitor for_effect(owner());
1105 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); 1106 node->InlinedFinallyNodeAt(i)->Visit(&for_effect);
1106 Append(for_effect); 1107 Append(for_effect);
1107 if (!is_open()) { 1108 if (!is_open()) {
1108 return; 1109 return;
1109 } 1110 }
1110 } 1111 }
1111 return_value = Bind(BuildLoadLocal(*temp)); 1112 return_value = Bind(BuildLoadLocal(*temp));
1112 } 1113 }
1113 1114
1114 if (Isolate::Current()->TypeChecksEnabled()) { 1115 if (Isolate::Current()->flags().type_checks()) {
1115 const bool is_implicit_dynamic_getter = 1116 const bool is_implicit_dynamic_getter =
1116 (!function.is_static() && 1117 (!function.is_static() &&
1117 ((function.kind() == RawFunction::kImplicitGetter) || 1118 ((function.kind() == RawFunction::kImplicitGetter) ||
1118 (function.kind() == RawFunction::kImplicitStaticFinalGetter))); 1119 (function.kind() == RawFunction::kImplicitStaticFinalGetter)));
1119 // Implicit getters do not need a type check at return, unless they compute 1120 // Implicit getters do not need a type check at return, unless they compute
1120 // the initial value of a static field. 1121 // the initial value of a static field.
1121 // The body of a constructor cannot modify the type of the 1122 // The body of a constructor cannot modify the type of the
1122 // constructed instance, which is passed in as an implicit parameter. 1123 // constructed instance, which is passed in as an implicit parameter.
1123 // However, factories may create an instance of the wrong type. 1124 // However, factories may create an instance of the wrong type.
1124 if (!is_implicit_dynamic_getter && !function.IsGenerativeConstructor()) { 1125 if (!is_implicit_dynamic_getter && !function.IsGenerativeConstructor()) {
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1304 // left: <Expression> 1305 // left: <Expression>
1305 // right: <Expression> } 1306 // right: <Expression> }
1306 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { 1307 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
1307 // Operators "&&" and "||" cannot be overloaded therefore do not call 1308 // Operators "&&" and "||" cannot be overloaded therefore do not call
1308 // operator. 1309 // operator.
1309 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { 1310 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
1310 // See ValueGraphVisitor::VisitBinaryOpNode. 1311 // See ValueGraphVisitor::VisitBinaryOpNode.
1311 TestGraphVisitor for_left(owner(), node->left()->token_pos()); 1312 TestGraphVisitor for_left(owner(), node->left()->token_pos());
1312 node->left()->Visit(&for_left); 1313 node->left()->Visit(&for_left);
1313 EffectGraphVisitor empty(owner()); 1314 EffectGraphVisitor empty(owner());
1314 if (Isolate::Current()->TypeChecksEnabled() || 1315 Isolate* isolate = Isolate::Current();
1315 Isolate::Current()->AssertsEnabled()) { 1316 if (isolate->flags().type_checks() ||
1317 isolate->flags().asserts()) {
1316 ValueGraphVisitor for_right(owner()); 1318 ValueGraphVisitor for_right(owner());
1317 node->right()->Visit(&for_right); 1319 node->right()->Visit(&for_right);
1318 Value* right_value = for_right.value(); 1320 Value* right_value = for_right.value();
1319 for_right.Do(new(Z) AssertBooleanInstr(node->right()->token_pos(), 1321 for_right.Do(new(Z) AssertBooleanInstr(node->right()->token_pos(),
1320 right_value)); 1322 right_value));
1321 if (node->kind() == Token::kAND) { 1323 if (node->kind() == Token::kAND) {
1322 Join(for_left, for_right, empty); 1324 Join(for_left, for_right, empty);
1323 } else { 1325 } else {
1324 Join(for_left, empty, for_right); 1326 Join(for_left, empty, for_right);
1325 } 1327 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1370 // of left is sufficient. 1372 // of left is sufficient.
1371 // AND: left ? right === true : false; 1373 // AND: left ? right === true : false;
1372 // OR: left ? true : right === true; 1374 // OR: left ? true : right === true;
1373 1375
1374 TestGraphVisitor for_test(owner(), node->left()->token_pos()); 1376 TestGraphVisitor for_test(owner(), node->left()->token_pos());
1375 node->left()->Visit(&for_test); 1377 node->left()->Visit(&for_test);
1376 1378
1377 ValueGraphVisitor for_right(owner()); 1379 ValueGraphVisitor for_right(owner());
1378 node->right()->Visit(&for_right); 1380 node->right()->Visit(&for_right);
1379 Value* right_value = for_right.value(); 1381 Value* right_value = for_right.value();
1380 if (Isolate::Current()->TypeChecksEnabled() || 1382 Isolate* isolate = Isolate::Current();
1381 Isolate::Current()->AssertsEnabled()) { 1383 if (isolate->flags().type_checks() ||
1384 isolate->flags().asserts()) {
1382 right_value = 1385 right_value =
1383 for_right.Bind(new(Z) AssertBooleanInstr(node->right()->token_pos(), 1386 for_right.Bind(new(Z) AssertBooleanInstr(node->right()->token_pos(),
1384 right_value)); 1387 right_value));
1385 } 1388 }
1386 Value* constant_true = for_right.Bind(new(Z) ConstantInstr(Bool::True())); 1389 Value* constant_true = for_right.Bind(new(Z) ConstantInstr(Bool::True()));
1387 Value* compare = 1390 Value* compare =
1388 for_right.Bind(new(Z) StrictCompareInstr(node->token_pos(), 1391 for_right.Bind(new(Z) StrictCompareInstr(node->token_pos(),
1389 Token::kEQ_STRICT, 1392 Token::kEQ_STRICT,
1390 right_value, 1393 right_value,
1391 constant_true, 1394 constant_true,
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after
1907 const intptr_t kNumArgsChecked = 2; 1910 const intptr_t kNumArgsChecked = 2;
1908 Definition* result = new(Z) InstanceCallInstr( 1911 Definition* result = new(Z) InstanceCallInstr(
1909 node->token_pos(), 1912 node->token_pos(),
1910 Symbols::EqualOperator(), 1913 Symbols::EqualOperator(),
1911 Token::kEQ, // Result is negated later for kNE. 1914 Token::kEQ, // Result is negated later for kNE.
1912 arguments, 1915 arguments,
1913 Object::null_array(), 1916 Object::null_array(),
1914 kNumArgsChecked, 1917 kNumArgsChecked,
1915 owner()->ic_data_array()); 1918 owner()->ic_data_array());
1916 if (node->kind() == Token::kNE) { 1919 if (node->kind() == Token::kNE) {
1917 if (Isolate::Current()->TypeChecksEnabled() || 1920 Isolate* isolate = Isolate::Current();
1918 Isolate::Current()->AssertsEnabled()) { 1921 if (isolate->flags().type_checks() ||
1922 isolate->flags().asserts()) {
1919 Value* value = Bind(result); 1923 Value* value = Bind(result);
1920 result = new(Z) AssertBooleanInstr(node->token_pos(), value); 1924 result = new(Z) AssertBooleanInstr(node->token_pos(), value);
1921 } 1925 }
1922 Value* value = Bind(result); 1926 Value* value = Bind(result);
1923 result = new(Z) BooleanNegateInstr(value); 1927 result = new(Z) BooleanNegateInstr(value);
1924 } 1928 }
1925 ReturnDefinition(result); 1929 ReturnDefinition(result);
1926 return; 1930 return;
1927 } 1931 }
1928 1932
(...skipping 25 matching lines...) Expand all
1954 } 1958 }
1955 1959
1956 1960
1957 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { 1961 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
1958 // "!" cannot be overloaded, therefore do not call operator. 1962 // "!" cannot be overloaded, therefore do not call operator.
1959 if (node->kind() == Token::kNOT) { 1963 if (node->kind() == Token::kNOT) {
1960 ValueGraphVisitor for_value(owner()); 1964 ValueGraphVisitor for_value(owner());
1961 node->operand()->Visit(&for_value); 1965 node->operand()->Visit(&for_value);
1962 Append(for_value); 1966 Append(for_value);
1963 Value* value = for_value.value(); 1967 Value* value = for_value.value();
1964 if (Isolate::Current()->TypeChecksEnabled() || 1968 Isolate* isolate = Isolate::Current();
1965 Isolate::Current()->AssertsEnabled()) { 1969 if (isolate->flags().type_checks() ||
1970 isolate->flags().asserts()) {
1966 value = 1971 value =
1967 Bind(new(Z) AssertBooleanInstr(node->operand()->token_pos(), value)); 1972 Bind(new(Z) AssertBooleanInstr(node->operand()->token_pos(), value));
1968 } 1973 }
1969 BooleanNegateInstr* negate = new(Z) BooleanNegateInstr(value); 1974 BooleanNegateInstr* negate = new(Z) BooleanNegateInstr(value);
1970 ReturnDefinition(negate); 1975 ReturnDefinition(negate);
1971 return; 1976 return;
1972 } 1977 }
1973 1978
1974 ValueGraphVisitor for_value(owner()); 1979 ValueGraphVisitor for_value(owner());
1975 node->operand()->Visit(&for_value); 1980 node->operand()->Visit(&for_value);
(...skipping 1582 matching lines...) Expand 10 before | Expand all | Expand 10 after
3558 (node->token_pos() != Scanner::kNoSourcePos)) { 3563 (node->token_pos() != Scanner::kNoSourcePos)) {
3559 AddInstruction(new(Z) DebugStepCheckInstr( 3564 AddInstruction(new(Z) DebugStepCheckInstr(
3560 node->token_pos(), RawPcDescriptors::kRuntimeCall)); 3565 node->token_pos(), RawPcDescriptors::kRuntimeCall));
3561 } 3566 }
3562 } 3567 }
3563 3568
3564 ValueGraphVisitor for_value(owner()); 3569 ValueGraphVisitor for_value(owner());
3565 node->value()->Visit(&for_value); 3570 node->value()->Visit(&for_value);
3566 Append(for_value); 3571 Append(for_value);
3567 Value* store_value = for_value.value(); 3572 Value* store_value = for_value.value();
3568 if (Isolate::Current()->TypeChecksEnabled()) { 3573 if (Isolate::Current()->flags().type_checks()) {
3569 store_value = BuildAssignableValue(node->value()->token_pos(), 3574 store_value = BuildAssignableValue(node->value()->token_pos(),
3570 store_value, 3575 store_value,
3571 node->local().type(), 3576 node->local().type(),
3572 node->local().name()); 3577 node->local().name());
3573 } 3578 }
3574 Definition* store = BuildStoreLocal(node->local(), store_value); 3579 Definition* store = BuildStoreLocal(node->local(), store_value);
3575 ReturnDefinition(store); 3580 ReturnDefinition(store);
3576 } 3581 }
3577 3582
3578 3583
(...skipping 20 matching lines...) Expand all
3599 3604
3600 void EffectGraphVisitor::VisitStoreInstanceFieldNode( 3605 void EffectGraphVisitor::VisitStoreInstanceFieldNode(
3601 StoreInstanceFieldNode* node) { 3606 StoreInstanceFieldNode* node) {
3602 ValueGraphVisitor for_instance(owner()); 3607 ValueGraphVisitor for_instance(owner());
3603 node->instance()->Visit(&for_instance); 3608 node->instance()->Visit(&for_instance);
3604 Append(for_instance); 3609 Append(for_instance);
3605 ValueGraphVisitor for_value(owner()); 3610 ValueGraphVisitor for_value(owner());
3606 node->value()->Visit(&for_value); 3611 node->value()->Visit(&for_value);
3607 Append(for_value); 3612 Append(for_value);
3608 Value* store_value = for_value.value(); 3613 Value* store_value = for_value.value();
3609 if (Isolate::Current()->TypeChecksEnabled()) { 3614 if (Isolate::Current()->flags().type_checks()) {
3610 const AbstractType& type = 3615 const AbstractType& type =
3611 AbstractType::ZoneHandle(Z, node->field().type()); 3616 AbstractType::ZoneHandle(Z, node->field().type());
3612 const String& dst_name = String::ZoneHandle(Z, node->field().name()); 3617 const String& dst_name = String::ZoneHandle(Z, node->field().name());
3613 store_value = BuildAssignableValue(node->value()->token_pos(), 3618 store_value = BuildAssignableValue(node->value()->token_pos(),
3614 store_value, 3619 store_value,
3615 type, 3620 type,
3616 dst_name); 3621 dst_name);
3617 } 3622 }
3618 3623
3619 if (FLAG_use_field_guards) { 3624 if (FLAG_use_field_guards) {
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
3990 CheckStackOverflowInstr* check = 3995 CheckStackOverflowInstr* check =
3991 new(Z) CheckStackOverflowInstr(function.token_pos(), 0); 3996 new(Z) CheckStackOverflowInstr(function.token_pos(), 0);
3992 // If we are inlining don't actually attach the stack check. We must still 3997 // If we are inlining don't actually attach the stack check. We must still
3993 // create the stack check in order to allocate a deopt id. 3998 // create the stack check in order to allocate a deopt id.
3994 if (!owner()->IsInlining()) { 3999 if (!owner()->IsInlining()) {
3995 AddInstruction(check); 4000 AddInstruction(check);
3996 } 4001 }
3997 } 4002 }
3998 } 4003 }
3999 4004
4000 if (Isolate::Current()->TypeChecksEnabled() && is_top_level_sequence) { 4005 if (Isolate::Current()->flags().type_checks() && is_top_level_sequence) {
4001 const int num_params = function.NumParameters(); 4006 const int num_params = function.NumParameters();
4002 int pos = 0; 4007 int pos = 0;
4003 if (function.IsGenerativeConstructor()) { 4008 if (function.IsGenerativeConstructor()) {
4004 // Skip type checking of receiver and phase for constructor functions. 4009 // Skip type checking of receiver and phase for constructor functions.
4005 pos = 2; 4010 pos = 2;
4006 } else if (function.IsFactory() || function.IsDynamicFunction()) { 4011 } else if (function.IsFactory() || function.IsDynamicFunction()) {
4007 // Skip type checking of type arguments for factory functions. 4012 // Skip type checking of type arguments for factory functions.
4008 // Skip type checking of receiver for instance functions. 4013 // Skip type checking of receiver for instance functions.
4009 pos = 1; 4014 pos = 1;
4010 } 4015 }
(...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after
4522 Report::MessageF(Report::kBailout, 4527 Report::MessageF(Report::kBailout,
4523 Script::Handle(function.script()), 4528 Script::Handle(function.script()),
4524 function.token_pos(), 4529 function.token_pos(),
4525 "FlowGraphBuilder Bailout: %s %s", 4530 "FlowGraphBuilder Bailout: %s %s",
4526 String::Handle(function.name()).ToCString(), 4531 String::Handle(function.name()).ToCString(),
4527 reason); 4532 reason);
4528 UNREACHABLE(); 4533 UNREACHABLE();
4529 } 4534 }
4530 4535
4531 } // namespace dart 4536 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698