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

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
« no previous file with comments | « runtime/vm/dart_api_impl_test.cc ('k') | runtime/vm/flow_graph_compiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
1775 1778
1776 Definition* result = new(I) InstanceCallInstr( 1779 Definition* result = new(I) InstanceCallInstr(
1777 node->token_pos(), 1780 node->token_pos(),
1778 Symbols::EqualOperator(), 1781 Symbols::EqualOperator(),
1779 Token::kEQ, // Result is negated later for kNE. 1782 Token::kEQ, // Result is negated later for kNE.
1780 arguments, 1783 arguments,
1781 Object::null_array(), 1784 Object::null_array(),
1782 2, 1785 2,
1783 owner()->ic_data_array()); 1786 owner()->ic_data_array());
1784 if (node->kind() == Token::kNE) { 1787 if (node->kind() == Token::kNE) {
1785 if (FLAG_enable_type_checks || FLAG_enable_asserts) { 1788 if (Isolate::Current()->TypeChecksEnabled() ||
1789 Isolate::Current()->AssertsEnabled()) {
1786 Value* value = Bind(result); 1790 Value* value = Bind(result);
1787 result = new(I) AssertBooleanInstr(node->token_pos(), value); 1791 result = new(I) AssertBooleanInstr(node->token_pos(), value);
1788 } 1792 }
1789 Value* value = Bind(result); 1793 Value* value = Bind(result);
1790 result = new(I) BooleanNegateInstr(value); 1794 result = new(I) BooleanNegateInstr(value);
1791 } 1795 }
1792 ReturnDefinition(result); 1796 ReturnDefinition(result);
1793 return; 1797 return;
1794 } 1798 }
1795 1799
(...skipping 25 matching lines...) Expand all
1821 } 1825 }
1822 1826
1823 1827
1824 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { 1828 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
1825 // "!" cannot be overloaded, therefore do not call operator. 1829 // "!" cannot be overloaded, therefore do not call operator.
1826 if (node->kind() == Token::kNOT) { 1830 if (node->kind() == Token::kNOT) {
1827 ValueGraphVisitor for_value(owner()); 1831 ValueGraphVisitor for_value(owner());
1828 node->operand()->Visit(&for_value); 1832 node->operand()->Visit(&for_value);
1829 Append(for_value); 1833 Append(for_value);
1830 Value* value = for_value.value(); 1834 Value* value = for_value.value();
1831 if (FLAG_enable_type_checks || FLAG_enable_asserts) { 1835 if (Isolate::Current()->TypeChecksEnabled() ||
1836 Isolate::Current()->AssertsEnabled()) {
1832 value = 1837 value =
1833 Bind(new(I) AssertBooleanInstr(node->operand()->token_pos(), value)); 1838 Bind(new(I) AssertBooleanInstr(node->operand()->token_pos(), value));
1834 } 1839 }
1835 BooleanNegateInstr* negate = new(I) BooleanNegateInstr(value); 1840 BooleanNegateInstr* negate = new(I) BooleanNegateInstr(value);
1836 ReturnDefinition(negate); 1841 ReturnDefinition(negate);
1837 return; 1842 return;
1838 } 1843 }
1839 1844
1840 ValueGraphVisitor for_value(owner()); 1845 ValueGraphVisitor for_value(owner());
1841 node->operand()->Visit(&for_value); 1846 node->operand()->Visit(&for_value);
(...skipping 1582 matching lines...) Expand 10 before | Expand all | Expand 10 after
3424 node->value()->IsLoadLocalNode() || 3429 node->value()->IsLoadLocalNode() ||
3425 node->value()->IsClosureNode()) { 3430 node->value()->IsClosureNode()) {
3426 AddInstruction(new(I) DebugStepCheckInstr( 3431 AddInstruction(new(I) DebugStepCheckInstr(
3427 node->token_pos(), RawPcDescriptors::kRuntimeCall)); 3432 node->token_pos(), RawPcDescriptors::kRuntimeCall));
3428 } 3433 }
3429 3434
3430 ValueGraphVisitor for_value(owner()); 3435 ValueGraphVisitor for_value(owner());
3431 node->value()->Visit(&for_value); 3436 node->value()->Visit(&for_value);
3432 Append(for_value); 3437 Append(for_value);
3433 Value* store_value = for_value.value(); 3438 Value* store_value = for_value.value();
3434 if (FLAG_enable_type_checks) { 3439 if (Isolate::Current()->TypeChecksEnabled()) {
3435 store_value = BuildAssignableValue(node->value()->token_pos(), 3440 store_value = BuildAssignableValue(node->value()->token_pos(),
3436 store_value, 3441 store_value,
3437 node->local().type(), 3442 node->local().type(),
3438 node->local().name()); 3443 node->local().name());
3439 } 3444 }
3440 Definition* store = BuildStoreLocal(node->local(), store_value); 3445 Definition* store = BuildStoreLocal(node->local(), store_value);
3441 ReturnDefinition(store); 3446 ReturnDefinition(store);
3442 } 3447 }
3443 3448
3444 3449
(...skipping 20 matching lines...) Expand all
3465 3470
3466 void EffectGraphVisitor::VisitStoreInstanceFieldNode( 3471 void EffectGraphVisitor::VisitStoreInstanceFieldNode(
3467 StoreInstanceFieldNode* node) { 3472 StoreInstanceFieldNode* node) {
3468 ValueGraphVisitor for_instance(owner()); 3473 ValueGraphVisitor for_instance(owner());
3469 node->instance()->Visit(&for_instance); 3474 node->instance()->Visit(&for_instance);
3470 Append(for_instance); 3475 Append(for_instance);
3471 ValueGraphVisitor for_value(owner()); 3476 ValueGraphVisitor for_value(owner());
3472 node->value()->Visit(&for_value); 3477 node->value()->Visit(&for_value);
3473 Append(for_value); 3478 Append(for_value);
3474 Value* store_value = for_value.value(); 3479 Value* store_value = for_value.value();
3475 if (FLAG_enable_type_checks) { 3480 if (Isolate::Current()->TypeChecksEnabled()) {
3476 const AbstractType& type = 3481 const AbstractType& type =
3477 AbstractType::ZoneHandle(I, node->field().type()); 3482 AbstractType::ZoneHandle(I, node->field().type());
3478 const String& dst_name = String::ZoneHandle(I, node->field().name()); 3483 const String& dst_name = String::ZoneHandle(I, node->field().name());
3479 store_value = BuildAssignableValue(node->value()->token_pos(), 3484 store_value = BuildAssignableValue(node->value()->token_pos(),
3480 store_value, 3485 store_value,
3481 type, 3486 type,
3482 dst_name); 3487 dst_name);
3483 } 3488 }
3484 3489
3485 store_value = Bind(BuildStoreExprTemp(store_value)); 3490 store_value = Bind(BuildStoreExprTemp(store_value));
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
3827 CheckStackOverflowInstr* check = 3832 CheckStackOverflowInstr* check =
3828 new(I) CheckStackOverflowInstr(function.token_pos(), 0); 3833 new(I) CheckStackOverflowInstr(function.token_pos(), 0);
3829 // If we are inlining don't actually attach the stack check. We must still 3834 // If we are inlining don't actually attach the stack check. We must still
3830 // create the stack check in order to allocate a deopt id. 3835 // create the stack check in order to allocate a deopt id.
3831 if (!owner()->IsInlining()) { 3836 if (!owner()->IsInlining()) {
3832 AddInstruction(check); 3837 AddInstruction(check);
3833 } 3838 }
3834 } 3839 }
3835 } 3840 }
3836 3841
3837 if (FLAG_enable_type_checks && is_top_level_sequence) { 3842 if (Isolate::Current()->TypeChecksEnabled() && is_top_level_sequence) {
3838 const Function& function = owner()->function(); 3843 const Function& function = owner()->function();
3839 const int num_params = function.NumParameters(); 3844 const int num_params = function.NumParameters();
3840 int pos = 0; 3845 int pos = 0;
3841 if (function.IsConstructor()) { 3846 if (function.IsConstructor()) {
3842 // Skip type checking of receiver and phase for constructor functions. 3847 // Skip type checking of receiver and phase for constructor functions.
3843 pos = 2; 3848 pos = 2;
3844 } else if (function.IsFactory() || function.IsDynamicFunction()) { 3849 } else if (function.IsFactory() || function.IsDynamicFunction()) {
3845 // Skip type checking of type arguments for factory functions. 3850 // Skip type checking of type arguments for factory functions.
3846 // Skip type checking of receiver for instance functions. 3851 // Skip type checking of receiver for instance functions.
3847 pos = 1; 3852 pos = 1;
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after
4328 Report::MessageF(Report::kBailout, 4333 Report::MessageF(Report::kBailout,
4329 Script::Handle(function.script()), 4334 Script::Handle(function.script()),
4330 function.token_pos(), 4335 function.token_pos(),
4331 "FlowGraphBuilder Bailout: %s %s", 4336 "FlowGraphBuilder Bailout: %s %s",
4332 String::Handle(function.name()).ToCString(), 4337 String::Handle(function.name()).ToCString(),
4333 reason); 4338 reason);
4334 UNREACHABLE(); 4339 UNREACHABLE();
4335 } 4340 }
4336 4341
4337 } // namespace dart 4342 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/dart_api_impl_test.cc ('k') | runtime/vm/flow_graph_compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698