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

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

Issue 9969192: Implement condition type checks in new compiler, thereby removing last bailouts. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 8 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/flow_graph_builder.h ('k') | runtime/vm/flow_graph_compiler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Deleted: svn:eol-style
- LF
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 "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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 new LoadLocalComp(variable, owner()->context_level()); 153 new LoadLocalComp(variable, owner()->context_level());
154 AddInstruction(new BindInstr(start_index, load_saved_context)); 154 AddInstruction(new BindInstr(start_index, load_saved_context));
155 StoreContextComp* store_context = 155 StoreContextComp* store_context =
156 new StoreContextComp(new TempVal(start_index)); 156 new StoreContextComp(new TempVal(start_index));
157 AddInstruction(new DoInstr(store_context)); 157 AddInstruction(new DoInstr(store_context));
158 } 158 }
159 159
160 160
161 161
162 void TestGraphVisitor::ReturnValue(Value* value) { 162 void TestGraphVisitor::ReturnValue(Value* value) {
163 if (FLAG_enable_type_checks) {
164 AssertBooleanComp* assert_boolean =
165 new AssertBooleanComp(condition_node_id(),
166 condition_token_index(),
167 owner()->try_index(),
168 value);
169 AddInstruction(new BindInstr(temp_index(), assert_boolean));
170 value = new TempVal(temp_index());
171 }
163 BranchInstr* branch = new BranchInstr(value); 172 BranchInstr* branch = new BranchInstr(value);
164 AddInstruction(branch); 173 AddInstruction(branch);
165 CloseFragment(); 174 CloseFragment();
166 true_successor_address_ = branch->true_successor_address(); 175 true_successor_address_ = branch->true_successor_address();
167 false_successor_address_ = branch->false_successor_address(); 176 false_successor_address_ = branch->false_successor_address();
168 } 177 }
169 178
170 179
171 void ArgumentGraphVisitor::ReturnValue(Value* value) { 180 void ArgumentGraphVisitor::ReturnValue(Value* value) {
172 value_ = value; 181 value_ = value;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 300
292 301
293 // <Expression> :: BinaryOp { kind: Token::Kind 302 // <Expression> :: BinaryOp { kind: Token::Kind
294 // left: <Expression> 303 // left: <Expression>
295 // right: <Expression> } 304 // right: <Expression> }
296 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { 305 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
297 // Operators "&&" and "||" cannot be overloaded therefore do not call 306 // Operators "&&" and "||" cannot be overloaded therefore do not call
298 // operator. 307 // operator.
299 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { 308 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
300 // See ValueGraphVisitor::VisitBinaryOpNode. 309 // See ValueGraphVisitor::VisitBinaryOpNode.
301 TestGraphVisitor for_left(owner(), temp_index()); 310 TestGraphVisitor for_left(owner(),
311 temp_index(),
312 node->left()->id(),
313 node->left()->token_index());
302 node->left()->Visit(&for_left); 314 node->left()->Visit(&for_left);
303 EffectGraphVisitor for_right(owner(), temp_index()); 315 EffectGraphVisitor for_right(owner(), temp_index());
304 node->right()->Visit(&for_right); 316 node->right()->Visit(&for_right);
305 EffectGraphVisitor empty(owner(), temp_index()); 317 EffectGraphVisitor empty(owner(), temp_index());
306 if (node->kind() == Token::kAND) { 318 if (node->kind() == Token::kAND) {
307 Join(for_left, for_right, empty); 319 Join(for_left, for_right, empty);
308 } else { 320 } else {
309 Join(for_left, empty, for_right); 321 Join(for_left, empty, for_right);
310 } 322 }
311 return; 323 return;
(...skipping 24 matching lines...) Expand all
336 // Operators "&&" and "||" cannot be overloaded therefore do not call 348 // Operators "&&" and "||" cannot be overloaded therefore do not call
337 // operator. 349 // operator.
338 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { 350 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
339 // Implement short-circuit logic: do not evaluate right if evaluation 351 // Implement short-circuit logic: do not evaluate right if evaluation
340 // of left is sufficient. 352 // of left is sufficient.
341 // AND: left ? right === true : false; 353 // AND: left ? right === true : false;
342 // OR: left ? true : right === true; 354 // OR: left ? true : right === true;
343 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 355 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
344 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 356 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
345 357
346 TestGraphVisitor for_test(owner(), temp_index()); 358 TestGraphVisitor for_test(owner(),
359 temp_index(),
360 node->left()->id(),
361 node->left()->token_index());
347 node->left()->Visit(&for_test); 362 node->left()->Visit(&for_test);
348 if (FLAG_enable_type_checks) {
349 Bailout("GenerateConditionTypeCheck in kAND/kOR");
350 }
351 363
352 ValueGraphVisitor for_right(owner(), temp_index()); 364 ValueGraphVisitor for_right(owner(), temp_index());
353 node->right()->Visit(&for_right); 365 node->right()->Visit(&for_right);
366 Value* right_value = for_right.value();
354 if (FLAG_enable_type_checks) { 367 if (FLAG_enable_type_checks) {
355 Bailout("GenerateConditionTypeCheck in kAND/kOR"); 368 AssertBooleanComp* assert_boolean =
369 new AssertBooleanComp(node->right()->id(),
370 node->right()->token_index(),
371 owner()->try_index(),
372 right_value);
373 for_right.AddInstruction(new BindInstr(temp_index(), assert_boolean));
374 right_value = new TempVal(temp_index());
356 } 375 }
357 StrictCompareComp* comp = new StrictCompareComp(Token::kEQ_STRICT, 376 StrictCompareComp* comp = new StrictCompareComp(Token::kEQ_STRICT,
358 for_right.value(), new ConstantVal(bool_true)); 377 right_value, new ConstantVal(bool_true));
359 for_right.AddInstruction(new BindInstr(temp_index(), comp)); 378 for_right.AddInstruction(new BindInstr(temp_index(), comp));
360 379
361 if (node->kind() == Token::kAND) { 380 if (node->kind() == Token::kAND) {
362 ValueGraphVisitor for_false(owner(), temp_index()); 381 ValueGraphVisitor for_false(owner(), temp_index());
363 for_false.AddInstruction( 382 for_false.AddInstruction(
364 new BindInstr(temp_index(), new ConstantVal(bool_false))); 383 new BindInstr(temp_index(), new ConstantVal(bool_false)));
365 Join(for_test, for_right, for_false); 384 Join(for_test, for_right, for_false);
366 } else { 385 } else {
367 ASSERT(node->kind() == Token::kOR); 386 ASSERT(node->kind() == Token::kOR);
368 ValueGraphVisitor for_true(owner(), temp_index()); 387 ValueGraphVisitor for_true(owner(), temp_index());
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 node->right()->Visit(&for_right_value); 581 node->right()->Visit(&for_right_value);
563 Append(for_right_value); 582 Append(for_right_value);
564 EqualityCompareComp* comp = new EqualityCompareComp( 583 EqualityCompareComp* comp = new EqualityCompareComp(
565 node->id(), node->token_index(), owner()->try_index(), 584 node->id(), node->token_index(), owner()->try_index(),
566 for_left_value.value(), for_right_value.value()); 585 for_left_value.value(), for_right_value.value());
567 if (node->kind() == Token::kEQ) { 586 if (node->kind() == Token::kEQ) {
568 ReturnComputation(comp); 587 ReturnComputation(comp);
569 } else { 588 } else {
570 AddInstruction(new BindInstr(temp_index(), comp)); 589 AddInstruction(new BindInstr(temp_index(), comp));
571 Value* eq_result = new TempVal(temp_index()); 590 Value* eq_result = new TempVal(temp_index());
591 if (FLAG_enable_type_checks) {
592 AssertBooleanComp* assert_boolean =
593 new AssertBooleanComp(node->id(),
594 node->token_index(),
595 owner()->try_index(),
596 eq_result);
597 AddInstruction(new BindInstr(temp_index(), assert_boolean));
598 eq_result = new TempVal(temp_index());
599 }
572 BooleanNegateComp* negate = new BooleanNegateComp(eq_result); 600 BooleanNegateComp* negate = new BooleanNegateComp(eq_result);
573 ReturnComputation(negate); 601 ReturnComputation(negate);
574 } 602 }
575 return; 603 return;
576 } 604 }
577 605
578 ArgumentGraphVisitor for_left_value(owner(), temp_index()); 606 ArgumentGraphVisitor for_left_value(owner(), temp_index());
579 node->left()->Visit(&for_left_value); 607 node->left()->Visit(&for_left_value);
580 Append(for_left_value); 608 Append(for_left_value);
581 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index()); 609 ArgumentGraphVisitor for_right_value(owner(), for_left_value.temp_index());
582 node->right()->Visit(&for_right_value); 610 node->right()->Visit(&for_right_value);
583 Append(for_right_value); 611 Append(for_right_value);
584 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); 612 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2);
585 arguments->Add(for_left_value.value()); 613 arguments->Add(for_left_value.value());
586 arguments->Add(for_right_value.value()); 614 arguments->Add(for_right_value.value());
587 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); 615 const String& name = String::ZoneHandle(String::NewSymbol(node->Name()));
588 InstanceCallComp* call = new InstanceCallComp( 616 InstanceCallComp* call = new InstanceCallComp(
589 node->id(), node->token_index(), owner()->try_index(), name, 617 node->id(), node->token_index(), owner()->try_index(), name,
590 arguments, Array::ZoneHandle(), 2); 618 arguments, Array::ZoneHandle(), 2);
591 ReturnComputation(call); 619 ReturnComputation(call);
592 } 620 }
593 621
594 622
595 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { 623 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
596 // "!" cannot be overloaded, therefore do not call operator. 624 // "!" cannot be overloaded, therefore do not call operator.
597 if (node->kind() == Token::kNOT) { 625 if (node->kind() == Token::kNOT) {
598 ValueGraphVisitor for_value(owner(), temp_index()); 626 ValueGraphVisitor for_value(owner(), temp_index());
599 node->operand()->Visit(&for_value); 627 node->operand()->Visit(&for_value);
600 Append(for_value); 628 Append(for_value);
629 Value* value = for_value.value();
601 if (FLAG_enable_type_checks) { 630 if (FLAG_enable_type_checks) {
602 Bailout("GenerateConditionTypeCheck in kNOT"); 631 AssertBooleanComp* assert_boolean =
632 new AssertBooleanComp(node->operand()->id(),
633 node->operand()->token_index(),
634 owner()->try_index(),
635 value);
636 AddInstruction(new BindInstr(temp_index(), assert_boolean));
637 value = new TempVal(temp_index());
603 } 638 }
604 BooleanNegateComp* negate = new BooleanNegateComp(for_value.value()); 639 BooleanNegateComp* negate = new BooleanNegateComp(value);
605 ReturnComputation(negate); 640 ReturnComputation(negate);
606 return; 641 return;
607 } 642 }
608 ArgumentGraphVisitor for_value(owner(), temp_index()); 643 ArgumentGraphVisitor for_value(owner(), temp_index());
609 node->operand()->Visit(&for_value); 644 node->operand()->Visit(&for_value);
610 Append(for_value); 645 Append(for_value);
611 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); 646 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1);
612 arguments->Add(for_value.value()); 647 arguments->Add(for_value.value());
613 const String& name = 648 const String& name =
614 String::ZoneHandle(String::NewSymbol((node->kind() == Token::kSUB) 649 String::ZoneHandle(String::NewSymbol((node->kind() == Token::kSUB)
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 arguments->Add(new TempVal(value_index)); 893 arguments->Add(new TempVal(value_index));
859 InstanceCallComp* store = new InstanceCallComp( 894 InstanceCallComp* store = new InstanceCallComp(
860 node->store_id(), node->token_index(), owner()->try_index(), 895 node->store_id(), node->token_index(), owner()->try_index(),
861 store_name, arguments, Array::ZoneHandle(), 1); 896 store_name, arguments, Array::ZoneHandle(), 1);
862 AddInstruction(new DoInstr(store)); 897 AddInstruction(new DoInstr(store));
863 ReturnValue(new TempVal(AllocateTempIndex())); 898 ReturnValue(new TempVal(AllocateTempIndex()));
864 } 899 }
865 900
866 901
867 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { 902 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
868 TestGraphVisitor for_test(owner(), temp_index()); 903 TestGraphVisitor for_test(owner(),
904 temp_index(),
905 node->condition()->id(),
906 node->condition()->token_index());
869 node->condition()->Visit(&for_test); 907 node->condition()->Visit(&for_test);
870 if (FLAG_enable_type_checks) {
871 Bailout("GenerateConditionTypeCheck in conditional expr");
872 }
873 908
874 // Translate the subexpressions for their effects. 909 // Translate the subexpressions for their effects.
875 EffectGraphVisitor for_true(owner(), temp_index()); 910 EffectGraphVisitor for_true(owner(), temp_index());
876 node->true_expr()->Visit(&for_true); 911 node->true_expr()->Visit(&for_true);
877 EffectGraphVisitor for_false(owner(), temp_index()); 912 EffectGraphVisitor for_false(owner(), temp_index());
878 node->false_expr()->Visit(&for_false); 913 node->false_expr()->Visit(&for_false);
879 914
880 Join(for_test, for_true, for_false); 915 Join(for_test, for_true, for_false);
881 } 916 }
882 917
883 918
884 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { 919 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
885 TestGraphVisitor for_test(owner(), temp_index()); 920 TestGraphVisitor for_test(owner(),
921 temp_index(),
922 node->condition()->id(),
923 node->condition()->token_index());
886 node->condition()->Visit(&for_test); 924 node->condition()->Visit(&for_test);
887 if (FLAG_enable_type_checks) {
888 Bailout("GenerateConditionTypeCheck in conditional expr");
889 }
890 925
891 // Ensure that the value of the true/false subexpressions are named with 926 // Ensure that the value of the true/false subexpressions are named with
892 // the same temporary name. 927 // the same temporary name.
893 ValueGraphVisitor for_true(owner(), temp_index()); 928 ValueGraphVisitor for_true(owner(), temp_index());
894 node->true_expr()->Visit(&for_true); 929 node->true_expr()->Visit(&for_true);
895 ASSERT(for_true.is_open()); 930 ASSERT(for_true.is_open());
896 if (for_true.value()->IsTemp()) { 931 if (for_true.value()->IsTemp()) {
897 ASSERT(for_true.value()->AsTemp()->index() == temp_index()); 932 ASSERT(for_true.value()->AsTemp()->index() == temp_index());
898 } else { 933 } else {
899 for_true.AddInstruction(new BindInstr(temp_index(), for_true.value())); 934 for_true.AddInstruction(new BindInstr(temp_index(), for_true.value()));
(...skipping 10 matching lines...) Expand all
910 945
911 Join(for_test, for_true, for_false); 946 Join(for_test, for_true, for_false);
912 ReturnValue(new TempVal(AllocateTempIndex())); 947 ReturnValue(new TempVal(AllocateTempIndex()));
913 } 948 }
914 949
915 950
916 // <Statement> ::= If { condition: <Expression> 951 // <Statement> ::= If { condition: <Expression>
917 // true_branch: <Sequence> 952 // true_branch: <Sequence>
918 // false_branch: <Sequence> } 953 // false_branch: <Sequence> }
919 void EffectGraphVisitor::VisitIfNode(IfNode* node) { 954 void EffectGraphVisitor::VisitIfNode(IfNode* node) {
920 TestGraphVisitor for_test(owner(), temp_index()); 955 TestGraphVisitor for_test(owner(),
956 temp_index(),
957 node->condition()->id(),
958 node->condition()->token_index());
921 node->condition()->Visit(&for_test); 959 node->condition()->Visit(&for_test);
922 if (FLAG_enable_type_checks) {
923 Bailout("GenerateConditionTypeCheck in if");
924 }
925 960
926 EffectGraphVisitor for_true(owner(), temp_index()); 961 EffectGraphVisitor for_true(owner(), temp_index());
927 EffectGraphVisitor for_false(owner(), temp_index()); 962 EffectGraphVisitor for_false(owner(), temp_index());
928 963
929 node->true_branch()->Visit(&for_true); 964 node->true_branch()->Visit(&for_true);
930 // The for_false graph fragment will be empty (default graph fragment) if 965 // The for_false graph fragment will be empty (default graph fragment) if
931 // we do not call Visit. 966 // we do not call Visit.
932 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false); 967 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false);
933 Join(for_test, for_true, for_false); 968 Join(for_test, for_true, for_false);
934 } 969 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1001 return; 1036 return;
1002 } 1037 }
1003 1038
1004 // Generate instructions for all case expressions and collect data to 1039 // Generate instructions for all case expressions and collect data to
1005 // connect them. 1040 // connect them.
1006 GrowableArray<TargetEntryInstr**> case_true_addresses; 1041 GrowableArray<TargetEntryInstr**> case_true_addresses;
1007 GrowableArray<TargetEntryInstr**> case_false_addresses; 1042 GrowableArray<TargetEntryInstr**> case_false_addresses;
1008 GrowableArray<TargetEntryInstr*> case_entries; 1043 GrowableArray<TargetEntryInstr*> case_entries;
1009 for (intptr_t i = 0; i < len; i++) { 1044 for (intptr_t i = 0; i < len; i++) {
1010 AstNode* case_expr = node->case_expressions()->NodeAt(i); 1045 AstNode* case_expr = node->case_expressions()->NodeAt(i);
1011 TestGraphVisitor for_case_expression(owner(), temp_index()); 1046 TestGraphVisitor for_case_expression(owner(),
1047 temp_index(),
1048 case_expr->id(),
1049 case_expr->token_index());
1012 if (i == 0) { 1050 if (i == 0) {
1013 case_entries.Add(NULL); // Not to be used 1051 case_entries.Add(NULL); // Not to be used
1014 case_expr->Visit(&for_case_expression); 1052 case_expr->Visit(&for_case_expression);
1015 // Append only the first one, everything else is connected from it. 1053 // Append only the first one, everything else is connected from it.
1016 Append(for_case_expression); 1054 Append(for_case_expression);
1017 } else { 1055 } else {
1018 TargetEntryInstr* case_entry_target = new TargetEntryInstr(); 1056 TargetEntryInstr* case_entry_target = new TargetEntryInstr();
1019 case_entries.Add(case_entry_target); 1057 case_entries.Add(case_entry_target);
1020 for_case_expression.AddInstruction(case_entry_target); 1058 for_case_expression.AddInstruction(case_entry_target);
1021 case_expr->Visit(&for_case_expression); 1059 case_expr->Visit(&for_case_expression);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 // body: <Sequence> } 1119 // body: <Sequence> }
1082 // The fragment is composed as follows: 1120 // The fragment is composed as follows:
1083 // a) continue-join (optional) 1121 // a) continue-join (optional)
1084 // b) loop-join 1122 // b) loop-join
1085 // c) [ test ] -> (body-entry-target, loop-exit-target) 1123 // c) [ test ] -> (body-entry-target, loop-exit-target)
1086 // d) body-entry-target 1124 // d) body-entry-target
1087 // e) [ body ] -> (loop-join) 1125 // e) [ body ] -> (loop-join)
1088 // f) loop-exit-target 1126 // f) loop-exit-target
1089 // g) break-join (optional) 1127 // g) break-join (optional)
1090 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { 1128 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) {
1091 TestGraphVisitor for_test(owner(), temp_index()); 1129 TestGraphVisitor for_test(owner(),
1130 temp_index(),
1131 node->condition()->id(),
1132 node->condition()->token_index());
1092 node->condition()->Visit(&for_test); 1133 node->condition()->Visit(&for_test);
1093 ASSERT(!for_test.is_empty()); // Language spec. 1134 ASSERT(!for_test.is_empty()); // Language spec.
1094 1135
1095 if (FLAG_enable_type_checks) {
1096 Bailout("GenerateConditionTypeCheck in while");
1097 }
1098
1099 EffectGraphVisitor for_body(owner(), temp_index()); 1136 EffectGraphVisitor for_body(owner(), temp_index());
1100 node->body()->Visit(&for_body); 1137 node->body()->Visit(&for_body);
1101 1138
1102 // Labels are set after body traversal. 1139 // Labels are set after body traversal.
1103 SourceLabel* lbl = node->label(); 1140 SourceLabel* lbl = node->label();
1104 ASSERT(lbl != NULL); 1141 ASSERT(lbl != NULL);
1105 if (lbl->join_for_continue() != NULL) { 1142 if (lbl->join_for_continue() != NULL) {
1106 AddInstruction(lbl->join_for_continue()); 1143 AddInstruction(lbl->join_for_continue());
1107 } 1144 }
1108 TieLoop(for_test, for_body); 1145 TieLoop(for_test, for_body);
1109 if (lbl->join_for_break() != NULL) { 1146 if (lbl->join_for_break() != NULL) {
1110 AddInstruction(lbl->join_for_break()); 1147 AddInstruction(lbl->join_for_break());
1111 } 1148 }
1112 } 1149 }
1113 1150
1114 1151
1115 // The fragment is composed as follows: 1152 // The fragment is composed as follows:
1116 // a) body-entry-join 1153 // a) body-entry-join
1117 // b) [ body ] 1154 // b) [ body ]
1118 // c) test-entry (continue-join or body-exit-target) 1155 // c) test-entry (continue-join or body-exit-target)
1119 // d) [ test-entry ] -> (back-target, loop-exit-target) 1156 // d) [ test-entry ] -> (back-target, loop-exit-target)
1120 // e) back-target -> (body-entry-join) 1157 // e) back-target -> (body-entry-join)
1121 // f) loop-exit-target 1158 // f) loop-exit-target
1122 // g) break-join 1159 // g) break-join
1123 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { 1160 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) {
1124 // Traverse body first in order to generate continue and break labels. 1161 // Traverse body first in order to generate continue and break labels.
1125 EffectGraphVisitor for_body(owner(), temp_index()); 1162 EffectGraphVisitor for_body(owner(), temp_index());
1126 node->body()->Visit(&for_body); 1163 node->body()->Visit(&for_body);
1127 1164
1128 TestGraphVisitor for_test(owner(), temp_index()); 1165 TestGraphVisitor for_test(owner(),
1166 temp_index(),
1167 node->condition()->id(),
1168 node->condition()->token_index());
1129 node->condition()->Visit(&for_test); 1169 node->condition()->Visit(&for_test);
1130 ASSERT(is_open()); 1170 ASSERT(is_open());
1131 1171
1132 if (FLAG_enable_type_checks) {
1133 Bailout("GenerateConditionTypeCheck in do while");
1134 }
1135
1136 // Tie do-while loop (test is after the body). 1172 // Tie do-while loop (test is after the body).
1137 JoinEntryInstr* body_entry_join = new JoinEntryInstr(); 1173 JoinEntryInstr* body_entry_join = new JoinEntryInstr();
1138 AddInstruction(body_entry_join); 1174 AddInstruction(body_entry_join);
1139 body_entry_join->SetSuccessor(for_body.entry()); 1175 body_entry_join->SetSuccessor(for_body.entry());
1140 Instruction* body_exit = 1176 Instruction* body_exit =
1141 for_body.is_empty() ? body_entry_join : for_body.exit(); 1177 for_body.is_empty() ? body_entry_join : for_body.exit();
1142 1178
1143 if (for_body.is_open() || (node->label()->join_for_continue() != NULL)) { 1179 if (for_body.is_open() || (node->label()->join_for_continue() != NULL)) {
1144 BlockEntryInstr* test_entry = NULL; 1180 BlockEntryInstr* test_entry = NULL;
1145 if (node->label()->join_for_continue() == NULL) { 1181 if (node->label()->join_for_continue() == NULL) {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1228 // Endless loop, no test. 1264 // Endless loop, no test.
1229 Append(for_body); 1265 Append(for_body);
1230 if (node->label()->join_for_break() == NULL) { 1266 if (node->label()->join_for_break() == NULL) {
1231 CloseFragment(); 1267 CloseFragment();
1232 } else { 1268 } else {
1233 // Control flow of ForLoop continues into join_for_break. 1269 // Control flow of ForLoop continues into join_for_break.
1234 exit_ = node->label()->join_for_break(); 1270 exit_ = node->label()->join_for_break();
1235 } 1271 }
1236 } else { 1272 } else {
1237 TargetEntryInstr* loop_exit = new TargetEntryInstr(); 1273 TargetEntryInstr* loop_exit = new TargetEntryInstr();
1238 TestGraphVisitor for_test(owner(), temp_index()); 1274 TestGraphVisitor for_test(owner(),
1275 temp_index(),
1276 node->condition()->id(),
1277 node->condition()->token_index());
1239 node->condition()->Visit(&for_test); 1278 node->condition()->Visit(&for_test);
1240 Append(for_test); 1279 Append(for_test);
1241 if (FLAG_enable_type_checks) {
1242 Bailout("GenerateConditionTypeCheck in for");
1243 }
1244 *for_test.true_successor_address() = body_entry; 1280 *for_test.true_successor_address() = body_entry;
1245 *for_test.false_successor_address() = loop_exit; 1281 *for_test.false_successor_address() = loop_exit;
1246 if (node->label()->join_for_break() == NULL) { 1282 if (node->label()->join_for_break() == NULL) {
1247 exit_ = loop_exit; 1283 exit_ = loop_exit;
1248 } else { 1284 } else {
1249 loop_exit->SetSuccessor(node->label()->join_for_break()); 1285 loop_exit->SetSuccessor(node->label()->join_for_break());
1250 exit_ = node->label()->join_for_break(); 1286 exit_ = node->label()->join_for_break();
1251 } 1287 }
1252 } 1288 }
1253 } 1289 }
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after
1764 1800
1765 Value* value = for_value.value(); 1801 Value* value = for_value.value();
1766 if (FLAG_enable_type_checks) { 1802 if (FLAG_enable_type_checks) {
1767 Value* type_arguments = NULL; 1803 Value* type_arguments = NULL;
1768 if (!node->local().type().IsInstantiated()) { 1804 if (!node->local().type().IsInstantiated()) {
1769 type_arguments = BuildInstantiatorTypeArguments( 1805 type_arguments = BuildInstantiatorTypeArguments(
1770 node->token_index(), for_value.temp_index()); 1806 node->token_index(), for_value.temp_index());
1771 } 1807 }
1772 AssertAssignableComp* assert_assignable = 1808 AssertAssignableComp* assert_assignable =
1773 new AssertAssignableComp(node->id(), 1809 new AssertAssignableComp(node->id(),
1774 node->local().token_index(), 1810 node->value()->token_index(),
1775 owner()->try_index(), 1811 owner()->try_index(),
1776 value, 1812 value,
1777 type_arguments, 1813 type_arguments,
1778 node->local().type(), 1814 node->local().type(),
1779 node->local().name()); 1815 node->local().name());
1780 AddInstruction(new BindInstr(temp_index(), assert_assignable)); 1816 AddInstruction(new BindInstr(temp_index(), assert_assignable));
1781 value = new TempVal(temp_index()); 1817 value = new TempVal(temp_index());
1782 } 1818 }
1783 1819
1784 StoreLocalComp* store = 1820 StoreLocalComp* store =
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1844 Value* store_value = for_value.value(); 1880 Value* store_value = for_value.value();
1845 if (FLAG_enable_type_checks) { 1881 if (FLAG_enable_type_checks) {
1846 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); 1882 const AbstractType& type = AbstractType::ZoneHandle(node->field().type());
1847 Value* type_arguments = NULL; 1883 Value* type_arguments = NULL;
1848 if (!type.IsInstantiated()) { 1884 if (!type.IsInstantiated()) {
1849 type_arguments = BuildInstantiatorTypeArguments( 1885 type_arguments = BuildInstantiatorTypeArguments(
1850 node->token_index(), for_value.temp_index()); 1886 node->token_index(), for_value.temp_index());
1851 } 1887 }
1852 AssertAssignableComp* assert_assignable = 1888 AssertAssignableComp* assert_assignable =
1853 new AssertAssignableComp(node->id(), 1889 new AssertAssignableComp(node->id(),
1854 node->field().token_index(), 1890 node->value()->token_index(),
1855 owner()->try_index(), 1891 owner()->try_index(),
1856 store_value, 1892 store_value,
1857 type_arguments, 1893 type_arguments,
1858 type, 1894 type,
1859 String::ZoneHandle(node->field().name())); 1895 String::ZoneHandle(node->field().name()));
1860 AddInstruction(new BindInstr(temp_index(), assert_assignable)); 1896 AddInstruction(new BindInstr(temp_index(), assert_assignable));
1861 store_value = new TempVal(temp_index()); 1897 store_value = new TempVal(temp_index());
1862 } 1898 }
1863 StoreStaticFieldComp* store = 1899 StoreStaticFieldComp* store =
1864 new StoreStaticFieldComp(node->field(), store_value); 1900 new StoreStaticFieldComp(node->field(), store_value);
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
2261 2297
2262 void FlowGraphPrinter::VisitConstant(ConstantVal* val) { 2298 void FlowGraphPrinter::VisitConstant(ConstantVal* val) {
2263 OS::Print("#%s", val->value().ToCString()); 2299 OS::Print("#%s", val->value().ToCString());
2264 } 2300 }
2265 2301
2266 2302
2267 void FlowGraphPrinter::VisitAssertAssignable(AssertAssignableComp* comp) { 2303 void FlowGraphPrinter::VisitAssertAssignable(AssertAssignableComp* comp) {
2268 OS::Print("AssertAssignable("); 2304 OS::Print("AssertAssignable(");
2269 comp->value()->Accept(this); 2305 comp->value()->Accept(this);
2270 OS::Print(", %s, '%s'", 2306 OS::Print(", %s, '%s'",
2271 comp->dst_type().ToCString(), 2307 String::Handle(comp->dst_type().Name()).ToCString(),
2272 comp->dst_name().ToCString()); 2308 comp->dst_name().ToCString());
2273 if (comp->type_arguments() != NULL) { 2309 if (comp->type_arguments() != NULL) {
2274 OS::Print(" (type-arg:"); 2310 OS::Print(" (type-arg:");
2275 comp->type_arguments()->Accept(this); 2311 comp->type_arguments()->Accept(this);
2276 } 2312 }
2277 OS::Print(")"); 2313 OS::Print(")");
2278 } 2314 }
2279 2315
2280 2316
2281 void FlowGraphPrinter::VisitAssertBoolean(AssertBooleanComp* comp) { 2317 void FlowGraphPrinter::VisitAssertBoolean(AssertBooleanComp* comp) {
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
2734 char* chars = reinterpret_cast<char*>( 2770 char* chars = reinterpret_cast<char*>(
2735 Isolate::Current()->current_zone()->Allocate(len)); 2771 Isolate::Current()->current_zone()->Allocate(len));
2736 OS::SNPrint(chars, len, kFormat, function_name, reason); 2772 OS::SNPrint(chars, len, kFormat, function_name, reason);
2737 const Error& error = Error::Handle( 2773 const Error& error = Error::Handle(
2738 LanguageError::New(String::Handle(String::New(chars)))); 2774 LanguageError::New(String::Handle(String::New(chars))));
2739 Isolate::Current()->long_jump_base()->Jump(1, error); 2775 Isolate::Current()->long_jump_base()->Jump(1, error);
2740 } 2776 }
2741 2777
2742 2778
2743 } // namespace dart 2779 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_compiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698