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

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

Issue 883263004: Allows turning on checked mode on a per-isolate basis (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_builder.h" 5 #include "vm/flow_graph_builder.h"
6 6
7 #include "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 871 matching lines...) Expand 10 before | Expand all | Expand 10 after
882 return CreateSuccessorFor(true_successor_addresses_); 882 return CreateSuccessorFor(true_successor_addresses_);
883 } 883 }
884 884
885 885
886 BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const { 886 BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const {
887 return CreateSuccessorFor(false_successor_addresses_); 887 return CreateSuccessorFor(false_successor_addresses_);
888 } 888 }
889 889
890 890
891 void TestGraphVisitor::ReturnValue(Value* value) { 891 void TestGraphVisitor::ReturnValue(Value* value) {
892 if (FLAG_enable_type_checks || FLAG_enable_asserts) { 892 if (Isolate::Current()->TypeChecksEnabled() ||
893 Isolate::Current()->AssertsEnabled()) {
893 value = Bind(new(I) AssertBooleanInstr(condition_token_pos(), value)); 894 value = Bind(new(I) AssertBooleanInstr(condition_token_pos(), value));
894 } 895 }
895 Value* constant_true = Bind(new(I) ConstantInstr(Bool::True())); 896 Value* constant_true = Bind(new(I) ConstantInstr(Bool::True()));
896 StrictCompareInstr* comp = 897 StrictCompareInstr* comp =
897 new(I) StrictCompareInstr(condition_token_pos(), 898 new(I) StrictCompareInstr(condition_token_pos(),
898 Token::kEQ_STRICT, 899 Token::kEQ_STRICT,
899 value, 900 value,
900 constant_true, 901 constant_true,
901 false); // No number check. 902 false); // No number check.
902 BranchInstr* branch = new(I) BranchInstr(comp); 903 BranchInstr* branch = new(I) BranchInstr(comp);
(...skipping 14 matching lines...) Expand all
917 (comp->left()->BindsToConstantNull() || 918 (comp->left()->BindsToConstantNull() ||
918 comp->right()->BindsToConstantNull())) { 919 comp->right()->BindsToConstantNull())) {
919 branch = new(I) BranchInstr(new(I) StrictCompareInstr( 920 branch = new(I) BranchInstr(new(I) StrictCompareInstr(
920 comp->token_pos(), 921 comp->token_pos(),
921 (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT, 922 (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT,
922 comp->left(), 923 comp->left(),
923 comp->right(), 924 comp->right(),
924 false)); // No number check. 925 false)); // No number check.
925 } else { 926 } else {
926 branch = new(I) BranchInstr(comp); 927 branch = new(I) BranchInstr(comp);
927 branch->set_is_checked(FLAG_enable_type_checks); 928 branch->set_is_checked(Isolate::Current()->TypeChecksEnabled());
928 } 929 }
929 AddInstruction(branch); 930 AddInstruction(branch);
930 CloseFragment(); 931 CloseFragment();
931 true_successor_addresses_.Add(branch->true_successor_address()); 932 true_successor_addresses_.Add(branch->true_successor_address());
932 false_successor_addresses_.Add(branch->false_successor_address()); 933 false_successor_addresses_.Add(branch->false_successor_address());
933 } 934 }
934 935
935 936
936 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) { 937 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) {
937 ASSERT(!FLAG_enable_type_checks); 938 ASSERT(!Isolate::Current()->TypeChecksEnabled());
938 Value* constant_true = Bind(new(I) ConstantInstr(Bool::True())); 939 Value* constant_true = Bind(new(I) ConstantInstr(Bool::True()));
939 StrictCompareInstr* comp = 940 StrictCompareInstr* comp =
940 new(I) StrictCompareInstr(condition_token_pos(), 941 new(I) StrictCompareInstr(condition_token_pos(),
941 Token::kNE_STRICT, 942 Token::kNE_STRICT,
942 neg->value(), 943 neg->value(),
943 constant_true, 944 constant_true,
944 false); // No number check. 945 false); // No number check.
945 BranchInstr* branch = new(I) BranchInstr(comp); 946 BranchInstr* branch = new(I) BranchInstr(comp);
946 AddInstruction(branch); 947 AddInstruction(branch);
947 CloseFragment(); 948 CloseFragment();
948 true_successor_addresses_.Add(branch->true_successor_address()); 949 true_successor_addresses_.Add(branch->true_successor_address());
949 false_successor_addresses_.Add(branch->false_successor_address()); 950 false_successor_addresses_.Add(branch->false_successor_address());
950 } 951 }
951 952
952 953
953 void TestGraphVisitor::ReturnDefinition(Definition* definition) { 954 void TestGraphVisitor::ReturnDefinition(Definition* definition) {
954 ComparisonInstr* comp = definition->AsComparison(); 955 ComparisonInstr* comp = definition->AsComparison();
955 if (comp != NULL) { 956 if (comp != NULL) {
956 MergeBranchWithComparison(comp); 957 MergeBranchWithComparison(comp);
957 return; 958 return;
958 } 959 }
959 if (!FLAG_enable_type_checks) { 960 if (!Isolate::Current()->TypeChecksEnabled()) {
960 BooleanNegateInstr* neg = definition->AsBooleanNegate(); 961 BooleanNegateInstr* neg = definition->AsBooleanNegate();
961 if (neg != NULL) { 962 if (neg != NULL) {
962 MergeBranchWithNegate(neg); 963 MergeBranchWithNegate(neg);
963 return; 964 return;
964 } 965 }
965 } 966 }
966 ReturnValue(Bind(definition)); 967 ReturnValue(Bind(definition));
967 } 968 }
968 969
969 970
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1038 // step mode. This call must happen before the contexts are 1039 // step mode. This call must happen before the contexts are
1039 // unchained so that captured variables can be inspected. 1040 // unchained so that captured variables can be inspected.
1040 // No debugger check is done in native functions or for return 1041 // No debugger check is done in native functions or for return
1041 // statements for which there is no associated source position. 1042 // statements for which there is no associated source position.
1042 const Function& function = owner()->function(); 1043 const Function& function = owner()->function();
1043 if ((node->token_pos() != Scanner::kNoSourcePos) && !function.is_native()) { 1044 if ((node->token_pos() != Scanner::kNoSourcePos) && !function.is_native()) {
1044 AddInstruction(new(I) DebugStepCheckInstr(node->token_pos(), 1045 AddInstruction(new(I) DebugStepCheckInstr(node->token_pos(),
1045 RawPcDescriptors::kRuntimeCall)); 1046 RawPcDescriptors::kRuntimeCall));
1046 } 1047 }
1047 1048
1048 if (FLAG_enable_type_checks) { 1049 if (Isolate::Current()->TypeChecksEnabled()) {
1049 const bool is_implicit_dynamic_getter = 1050 const bool is_implicit_dynamic_getter =
1050 (!function.is_static() && 1051 (!function.is_static() &&
1051 ((function.kind() == RawFunction::kImplicitGetter) || 1052 ((function.kind() == RawFunction::kImplicitGetter) ||
1052 (function.kind() == RawFunction::kImplicitStaticFinalGetter))); 1053 (function.kind() == RawFunction::kImplicitStaticFinalGetter)));
1053 // Implicit getters do not need a type check at return, unless they compute 1054 // Implicit getters do not need a type check at return, unless they compute
1054 // the initial value of a static field. 1055 // the initial value of a static field.
1055 // The body of a constructor cannot modify the type of the 1056 // The body of a constructor cannot modify the type of the
1056 // constructed instance, which is passed in as an implicit parameter. 1057 // constructed instance, which is passed in as an implicit parameter.
1057 // However, factories may create an instance of the wrong type. 1058 // However, factories may create an instance of the wrong type.
1058 if (!is_implicit_dynamic_getter && !function.IsConstructor()) { 1059 if (!is_implicit_dynamic_getter && !function.IsConstructor()) {
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1237 // left: <Expression> 1238 // left: <Expression>
1238 // right: <Expression> } 1239 // right: <Expression> }
1239 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { 1240 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
1240 // Operators "&&" and "||" cannot be overloaded therefore do not call 1241 // Operators "&&" and "||" cannot be overloaded therefore do not call
1241 // operator. 1242 // operator.
1242 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { 1243 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
1243 // See ValueGraphVisitor::VisitBinaryOpNode. 1244 // See ValueGraphVisitor::VisitBinaryOpNode.
1244 TestGraphVisitor for_left(owner(), node->left()->token_pos()); 1245 TestGraphVisitor for_left(owner(), node->left()->token_pos());
1245 node->left()->Visit(&for_left); 1246 node->left()->Visit(&for_left);
1246 EffectGraphVisitor empty(owner()); 1247 EffectGraphVisitor empty(owner());
1247 if (FLAG_enable_type_checks || FLAG_enable_asserts) { 1248 if (Isolate::Current()->TypeChecksEnabled() ||
1249 Isolate::Current()->AssertsEnabled()) {
1248 ValueGraphVisitor for_right(owner()); 1250 ValueGraphVisitor for_right(owner());
1249 node->right()->Visit(&for_right); 1251 node->right()->Visit(&for_right);
1250 Value* right_value = for_right.value(); 1252 Value* right_value = for_right.value();
1251 for_right.Do(new(I) AssertBooleanInstr(node->right()->token_pos(), 1253 for_right.Do(new(I) AssertBooleanInstr(node->right()->token_pos(),
1252 right_value)); 1254 right_value));
1253 if (node->kind() == Token::kAND) { 1255 if (node->kind() == Token::kAND) {
1254 Join(for_left, for_right, empty); 1256 Join(for_left, for_right, empty);
1255 } else { 1257 } else {
1256 Join(for_left, empty, for_right); 1258 Join(for_left, empty, for_right);
1257 } 1259 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1302 // of left is sufficient. 1304 // of left is sufficient.
1303 // AND: left ? right === true : false; 1305 // AND: left ? right === true : false;
1304 // OR: left ? true : right === true; 1306 // OR: left ? true : right === true;
1305 1307
1306 TestGraphVisitor for_test(owner(), node->left()->token_pos()); 1308 TestGraphVisitor for_test(owner(), node->left()->token_pos());
1307 node->left()->Visit(&for_test); 1309 node->left()->Visit(&for_test);
1308 1310
1309 ValueGraphVisitor for_right(owner()); 1311 ValueGraphVisitor for_right(owner());
1310 node->right()->Visit(&for_right); 1312 node->right()->Visit(&for_right);
1311 Value* right_value = for_right.value(); 1313 Value* right_value = for_right.value();
1312 if (FLAG_enable_type_checks|| FLAG_enable_asserts) { 1314 if (Isolate::Current()->TypeChecksEnabled() ||
1315 Isolate::Current()->AssertsEnabled()) {
1313 right_value = 1316 right_value =
1314 for_right.Bind(new(I) AssertBooleanInstr(node->right()->token_pos(), 1317 for_right.Bind(new(I) AssertBooleanInstr(node->right()->token_pos(),
1315 right_value)); 1318 right_value));
1316 } 1319 }
1317 Value* constant_true = for_right.Bind(new(I) ConstantInstr(Bool::True())); 1320 Value* constant_true = for_right.Bind(new(I) ConstantInstr(Bool::True()));
1318 Value* compare = 1321 Value* compare =
1319 for_right.Bind(new(I) StrictCompareInstr(node->token_pos(), 1322 for_right.Bind(new(I) StrictCompareInstr(node->token_pos(),
1320 Token::kEQ_STRICT, 1323 Token::kEQ_STRICT,
1321 right_value, 1324 right_value,
1322 constant_true, 1325 constant_true,
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
1761 1764
1762 Definition* result = new(I) InstanceCallInstr( 1765 Definition* result = new(I) InstanceCallInstr(
1763 node->token_pos(), 1766 node->token_pos(),
1764 Symbols::EqualOperator(), 1767 Symbols::EqualOperator(),
1765 Token::kEQ, // Result is negated later for kNE. 1768 Token::kEQ, // Result is negated later for kNE.
1766 arguments, 1769 arguments,
1767 Object::null_array(), 1770 Object::null_array(),
1768 2, 1771 2,
1769 owner()->ic_data_array()); 1772 owner()->ic_data_array());
1770 if (node->kind() == Token::kNE) { 1773 if (node->kind() == Token::kNE) {
1771 if (FLAG_enable_type_checks || FLAG_enable_asserts) { 1774 if (Isolate::Current()->TypeChecksEnabled() ||
1775 Isolate::Current()->AssertsEnabled()) {
1772 Value* value = Bind(result); 1776 Value* value = Bind(result);
1773 result = new(I) AssertBooleanInstr(node->token_pos(), value); 1777 result = new(I) AssertBooleanInstr(node->token_pos(), value);
1774 } 1778 }
1775 Value* value = Bind(result); 1779 Value* value = Bind(result);
1776 result = new(I) BooleanNegateInstr(value); 1780 result = new(I) BooleanNegateInstr(value);
1777 } 1781 }
1778 ReturnDefinition(result); 1782 ReturnDefinition(result);
1779 return; 1783 return;
1780 } 1784 }
1781 1785
(...skipping 25 matching lines...) Expand all
1807 } 1811 }
1808 1812
1809 1813
1810 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { 1814 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
1811 // "!" cannot be overloaded, therefore do not call operator. 1815 // "!" cannot be overloaded, therefore do not call operator.
1812 if (node->kind() == Token::kNOT) { 1816 if (node->kind() == Token::kNOT) {
1813 ValueGraphVisitor for_value(owner()); 1817 ValueGraphVisitor for_value(owner());
1814 node->operand()->Visit(&for_value); 1818 node->operand()->Visit(&for_value);
1815 Append(for_value); 1819 Append(for_value);
1816 Value* value = for_value.value(); 1820 Value* value = for_value.value();
1817 if (FLAG_enable_type_checks || FLAG_enable_asserts) { 1821 if (Isolate::Current()->TypeChecksEnabled() ||
1822 Isolate::Current()->AssertsEnabled()) {
1818 value = 1823 value =
1819 Bind(new(I) AssertBooleanInstr(node->operand()->token_pos(), value)); 1824 Bind(new(I) AssertBooleanInstr(node->operand()->token_pos(), value));
1820 } 1825 }
1821 BooleanNegateInstr* negate = new(I) BooleanNegateInstr(value); 1826 BooleanNegateInstr* negate = new(I) BooleanNegateInstr(value);
1822 ReturnDefinition(negate); 1827 ReturnDefinition(negate);
1823 return; 1828 return;
1824 } 1829 }
1825 1830
1826 ValueGraphVisitor for_value(owner()); 1831 ValueGraphVisitor for_value(owner());
1827 node->operand()->Visit(&for_value); 1832 node->operand()->Visit(&for_value);
(...skipping 1582 matching lines...) Expand 10 before | Expand all | Expand 10 after
3410 node->value()->IsLoadLocalNode() || 3415 node->value()->IsLoadLocalNode() ||
3411 node->value()->IsClosureNode()) { 3416 node->value()->IsClosureNode()) {
3412 AddInstruction(new(I) DebugStepCheckInstr( 3417 AddInstruction(new(I) DebugStepCheckInstr(
3413 node->token_pos(), RawPcDescriptors::kRuntimeCall)); 3418 node->token_pos(), RawPcDescriptors::kRuntimeCall));
3414 } 3419 }
3415 3420
3416 ValueGraphVisitor for_value(owner()); 3421 ValueGraphVisitor for_value(owner());
3417 node->value()->Visit(&for_value); 3422 node->value()->Visit(&for_value);
3418 Append(for_value); 3423 Append(for_value);
3419 Value* store_value = for_value.value(); 3424 Value* store_value = for_value.value();
3420 if (FLAG_enable_type_checks) { 3425 if (Isolate::Current()->TypeChecksEnabled()) {
3421 store_value = BuildAssignableValue(node->value()->token_pos(), 3426 store_value = BuildAssignableValue(node->value()->token_pos(),
3422 store_value, 3427 store_value,
3423 node->local().type(), 3428 node->local().type(),
3424 node->local().name()); 3429 node->local().name());
3425 } 3430 }
3426 Definition* store = BuildStoreLocal(node->local(), store_value); 3431 Definition* store = BuildStoreLocal(node->local(), store_value);
3427 ReturnDefinition(store); 3432 ReturnDefinition(store);
3428 } 3433 }
3429 3434
3430 3435
(...skipping 20 matching lines...) Expand all
3451 3456
3452 void EffectGraphVisitor::VisitStoreInstanceFieldNode( 3457 void EffectGraphVisitor::VisitStoreInstanceFieldNode(
3453 StoreInstanceFieldNode* node) { 3458 StoreInstanceFieldNode* node) {
3454 ValueGraphVisitor for_instance(owner()); 3459 ValueGraphVisitor for_instance(owner());
3455 node->instance()->Visit(&for_instance); 3460 node->instance()->Visit(&for_instance);
3456 Append(for_instance); 3461 Append(for_instance);
3457 ValueGraphVisitor for_value(owner()); 3462 ValueGraphVisitor for_value(owner());
3458 node->value()->Visit(&for_value); 3463 node->value()->Visit(&for_value);
3459 Append(for_value); 3464 Append(for_value);
3460 Value* store_value = for_value.value(); 3465 Value* store_value = for_value.value();
3461 if (FLAG_enable_type_checks) { 3466 if (Isolate::Current()->TypeChecksEnabled()) {
3462 const AbstractType& type = 3467 const AbstractType& type =
3463 AbstractType::ZoneHandle(I, node->field().type()); 3468 AbstractType::ZoneHandle(I, node->field().type());
3464 const String& dst_name = String::ZoneHandle(I, node->field().name()); 3469 const String& dst_name = String::ZoneHandle(I, node->field().name());
3465 store_value = BuildAssignableValue(node->value()->token_pos(), 3470 store_value = BuildAssignableValue(node->value()->token_pos(),
3466 store_value, 3471 store_value,
3467 type, 3472 type,
3468 dst_name); 3473 dst_name);
3469 } 3474 }
3470 3475
3471 store_value = Bind(BuildStoreExprTemp(store_value)); 3476 store_value = Bind(BuildStoreExprTemp(store_value));
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
3813 CheckStackOverflowInstr* check = 3818 CheckStackOverflowInstr* check =
3814 new(I) CheckStackOverflowInstr(function.token_pos(), 0); 3819 new(I) CheckStackOverflowInstr(function.token_pos(), 0);
3815 // If we are inlining don't actually attach the stack check. We must still 3820 // If we are inlining don't actually attach the stack check. We must still
3816 // create the stack check in order to allocate a deopt id. 3821 // create the stack check in order to allocate a deopt id.
3817 if (!owner()->IsInlining()) { 3822 if (!owner()->IsInlining()) {
3818 AddInstruction(check); 3823 AddInstruction(check);
3819 } 3824 }
3820 } 3825 }
3821 } 3826 }
3822 3827
3823 if (FLAG_enable_type_checks && is_top_level_sequence) { 3828 if (Isolate::Current()->TypeChecksEnabled() && is_top_level_sequence) {
3824 const Function& function = owner()->function(); 3829 const Function& function = owner()->function();
3825 const int num_params = function.NumParameters(); 3830 const int num_params = function.NumParameters();
3826 int pos = 0; 3831 int pos = 0;
3827 if (function.IsConstructor()) { 3832 if (function.IsConstructor()) {
3828 // Skip type checking of receiver and phase for constructor functions. 3833 // Skip type checking of receiver and phase for constructor functions.
3829 pos = 2; 3834 pos = 2;
3830 } else if (function.IsFactory() || function.IsDynamicFunction()) { 3835 } else if (function.IsFactory() || function.IsDynamicFunction()) {
3831 // Skip type checking of type arguments for factory functions. 3836 // Skip type checking of type arguments for factory functions.
3832 // Skip type checking of receiver for instance functions. 3837 // Skip type checking of receiver for instance functions.
3833 pos = 1; 3838 pos = 1;
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after
4311 Report::MessageF(Report::kBailout, 4316 Report::MessageF(Report::kBailout,
4312 Script::Handle(function.script()), 4317 Script::Handle(function.script()),
4313 function.token_pos(), 4318 function.token_pos(),
4314 "FlowGraphBuilder Bailout: %s %s", 4319 "FlowGraphBuilder Bailout: %s %s",
4315 String::Handle(function.name()).ToCString(), 4320 String::Handle(function.name()).ToCString(),
4316 reason); 4321 reason);
4317 UNREACHABLE(); 4322 UNREACHABLE();
4318 } 4323 }
4319 4324
4320 } // namespace dart 4325 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698