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

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

Issue 10892037: Stop attaching try_index to individual instructions put it at block entry instead. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address Srdjan's comment, make meaning of CatchTryIndex clear Created 8 years, 3 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 | « no previous file | 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 "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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 // and a pair of effect graph fragments with zero or one available exits. 142 // and a pair of effect graph fragments with zero or one available exits.
143 // We want to append the branch and (if necessary) a join node to this 143 // We want to append the branch and (if necessary) a join node to this
144 // graph fragment. 144 // graph fragment.
145 ASSERT(is_open()); 145 ASSERT(is_open());
146 146
147 // 1. Connect the test to this graph. 147 // 1. Connect the test to this graph.
148 Append(test_fragment); 148 Append(test_fragment);
149 149
150 // 2. Connect the true and false bodies to the test and record their exits 150 // 2. Connect the true and false bodies to the test and record their exits
151 // (if any). 151 // (if any).
152 TargetEntryInstr* true_entry = new TargetEntryInstr(); 152 TargetEntryInstr* true_entry = new TargetEntryInstr(owner()->try_index());
153 *test_fragment.true_successor_address() = true_entry; 153 *test_fragment.true_successor_address() = true_entry;
154 Instruction* true_exit = AppendFragment(true_entry, true_fragment); 154 Instruction* true_exit = AppendFragment(true_entry, true_fragment);
155 155
156 TargetEntryInstr* false_entry = new TargetEntryInstr(); 156 TargetEntryInstr* false_entry = new TargetEntryInstr(owner()->try_index());
157 *test_fragment.false_successor_address() = false_entry; 157 *test_fragment.false_successor_address() = false_entry;
158 Instruction* false_exit = AppendFragment(false_entry, false_fragment); 158 Instruction* false_exit = AppendFragment(false_entry, false_fragment);
159 159
160 // 3. Add a join or select one (or neither) of the arms as exit. 160 // 3. Add a join or select one (or neither) of the arms as exit.
161 if (true_exit == NULL) { 161 if (true_exit == NULL) {
162 exit_ = false_exit; // May be NULL. 162 exit_ = false_exit; // May be NULL.
163 if (false_exit != NULL) temp_index_ = false_fragment.temp_index(); 163 if (false_exit != NULL) temp_index_ = false_fragment.temp_index();
164 } else if (false_exit == NULL) { 164 } else if (false_exit == NULL) {
165 exit_ = true_exit; 165 exit_ = true_exit;
166 temp_index_ = true_fragment.temp_index(); 166 temp_index_ = true_fragment.temp_index();
167 } else { 167 } else {
168 JoinEntryInstr* join = new JoinEntryInstr(); 168 JoinEntryInstr* join = new JoinEntryInstr(owner()->try_index());
169 true_exit->Goto(join); 169 true_exit->Goto(join);
170 false_exit->Goto(join); 170 false_exit->Goto(join);
171 exit_ = join; 171 exit_ = join;
172 ASSERT(true_fragment.temp_index() == false_fragment.temp_index()); 172 ASSERT(true_fragment.temp_index() == false_fragment.temp_index());
173 temp_index_ = true_fragment.temp_index(); 173 temp_index_ = true_fragment.temp_index();
174 } 174 }
175 } 175 }
176 176
177 177
178 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment, 178 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment,
179 const EffectGraphVisitor& body_fragment) { 179 const EffectGraphVisitor& body_fragment) {
180 // We have: a test graph fragment with zero, one, or two available exits; 180 // We have: a test graph fragment with zero, one, or two available exits;
181 // and an effect graph fragment with zero or one available exits. We want 181 // and an effect graph fragment with zero or one available exits. We want
182 // to append the 'while loop' consisting of the test graph fragment as 182 // to append the 'while loop' consisting of the test graph fragment as
183 // condition and the effect graph fragment as body. 183 // condition and the effect graph fragment as body.
184 ASSERT(is_open()); 184 ASSERT(is_open());
185 185
186 // 1. Connect the body to the test if it is reachable, and if so record 186 // 1. Connect the body to the test if it is reachable, and if so record
187 // its exit (if any). 187 // its exit (if any).
188 TargetEntryInstr* body_entry = new TargetEntryInstr(); 188 TargetEntryInstr* body_entry = new TargetEntryInstr(owner()->try_index());
189 *test_fragment.true_successor_address() = body_entry; 189 *test_fragment.true_successor_address() = body_entry;
190 Instruction* body_exit = AppendFragment(body_entry, body_fragment); 190 Instruction* body_exit = AppendFragment(body_entry, body_fragment);
191 191
192 // 2. Connect the test to this graph, including the body if reachable and 192 // 2. Connect the test to this graph, including the body if reachable and
193 // using a fresh join node if the body is reachable and has an open exit. 193 // using a fresh join node if the body is reachable and has an open exit.
194 if (body_exit == NULL) { 194 if (body_exit == NULL) {
195 Append(test_fragment); 195 Append(test_fragment);
196 } else { 196 } else {
197 JoinEntryInstr* join = new JoinEntryInstr(); 197 JoinEntryInstr* join = new JoinEntryInstr(owner()->try_index());
198 join->set_next(test_fragment.entry()); 198 join->set_next(test_fragment.entry());
199 Goto(join); 199 Goto(join);
200 body_exit->Goto(join); 200 body_exit->Goto(join);
201 } 201 }
202 202
203 // 3. Set the exit to the graph to be the false successor of the test, a 203 // 3. Set the exit to the graph to be the false successor of the test, a
204 // fresh target node 204 // fresh target node
205 exit_ = *test_fragment.false_successor_address() = new TargetEntryInstr(); 205 exit_ = *test_fragment.false_successor_address() =
206 new TargetEntryInstr(owner()->try_index());
206 } 207 }
207 208
208 209
209 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) { 210 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) {
210 PushArgumentInstr* result = new PushArgumentInstr(value); 211 PushArgumentInstr* result = new PushArgumentInstr(value);
211 AddInstruction(result); 212 AddInstruction(result);
212 return result; 213 return result;
213 } 214 }
214 215
215 216
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 264
264 // Loads context saved in 'context_variable' into the current context. 265 // Loads context saved in 'context_variable' into the current context.
265 void EffectGraphVisitor::BuildLoadContext(const LocalVariable& variable) { 266 void EffectGraphVisitor::BuildLoadContext(const LocalVariable& variable) {
266 Value* load_saved_context = Bind(BuildLoadLocal(variable)); 267 Value* load_saved_context = Bind(BuildLoadLocal(variable));
267 Do(new StoreContextComp(load_saved_context)); 268 Do(new StoreContextComp(load_saved_context));
268 } 269 }
269 270
270 271
271 void TestGraphVisitor::ReturnValue(Value* value) { 272 void TestGraphVisitor::ReturnValue(Value* value) {
272 if (FLAG_enable_type_checks) { 273 if (FLAG_enable_type_checks) {
273 value = Bind(new AssertBooleanComp(condition_token_pos(), 274 value = Bind(new AssertBooleanComp(condition_token_pos(), value));
274 owner()->try_index(),
275 value));
276 } 275 }
277 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 276 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
278 Value* constant_true = Bind(Constant(bool_true)); 277 Value* constant_true = Bind(Constant(bool_true));
279 StrictCompareComp* comp = 278 StrictCompareComp* comp =
280 new StrictCompareComp(Token::kEQ_STRICT, value, constant_true); 279 new StrictCompareComp(Token::kEQ_STRICT, value, constant_true);
281 BranchInstr* branch = new BranchInstr(comp); 280 BranchInstr* branch = new BranchInstr(comp);
282 AddInstruction(branch); 281 AddInstruction(branch);
283 CloseFragment(); 282 CloseFragment();
284 true_successor_address_ = branch->true_successor_address(); 283 true_successor_address_ = branch->true_successor_address();
285 false_successor_address_ = branch->false_successor_address(); 284 false_successor_address_ = branch->false_successor_address();
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 node->right()->Visit(&for_right_value); 515 node->right()->Visit(&for_right_value);
517 Append(for_right_value); 516 Append(for_right_value);
518 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); 517 PushArgumentInstr* push_right = PushArgument(for_right_value.value());
519 518
520 ZoneGrowableArray<PushArgumentInstr*>* arguments = 519 ZoneGrowableArray<PushArgumentInstr*>* arguments =
521 new ZoneGrowableArray<PushArgumentInstr*>(2); 520 new ZoneGrowableArray<PushArgumentInstr*>(2);
522 arguments->Add(push_left); 521 arguments->Add(push_left);
523 arguments->Add(push_right); 522 arguments->Add(push_right);
524 const String& name = String::ZoneHandle(Symbols::New(node->Name())); 523 const String& name = String::ZoneHandle(Symbols::New(node->Name()));
525 InstanceCallComp* call = new InstanceCallComp(node->token_pos(), 524 InstanceCallComp* call = new InstanceCallComp(node->token_pos(),
526 owner()->try_index(),
527 name, 525 name,
528 node->kind(), 526 node->kind(),
529 arguments, 527 arguments,
530 Array::ZoneHandle(), 528 Array::ZoneHandle(),
531 2); 529 2);
532 ReturnComputation(call); 530 ReturnComputation(call);
533 } 531 }
534 532
535 533
536 // Special handling for AND/OR. 534 // Special handling for AND/OR.
(...skipping 12 matching lines...) Expand all
549 temp_index(), 547 temp_index(),
550 node->left()->token_pos()); 548 node->left()->token_pos());
551 node->left()->Visit(&for_test); 549 node->left()->Visit(&for_test);
552 550
553 ValueGraphVisitor for_right(owner(), temp_index()); 551 ValueGraphVisitor for_right(owner(), temp_index());
554 node->right()->Visit(&for_right); 552 node->right()->Visit(&for_right);
555 Value* right_value = for_right.value(); 553 Value* right_value = for_right.value();
556 if (FLAG_enable_type_checks) { 554 if (FLAG_enable_type_checks) {
557 right_value = 555 right_value =
558 for_right.Bind(new AssertBooleanComp(node->right()->token_pos(), 556 for_right.Bind(new AssertBooleanComp(node->right()->token_pos(),
559 owner()->try_index(),
560 right_value)); 557 right_value));
561 } 558 }
562 Value* constant_true = for_right.Bind(Constant(bool_true)); 559 Value* constant_true = for_right.Bind(Constant(bool_true));
563 Value* compare = 560 Value* compare =
564 for_right.Bind(new StrictCompareComp(Token::kEQ_STRICT, 561 for_right.Bind(new StrictCompareComp(Token::kEQ_STRICT,
565 right_value, 562 right_value,
566 constant_true)); 563 constant_true));
567 for_right.Do(BuildStoreLocal( 564 for_right.Do(BuildStoreLocal(
568 *owner()->parsed_function().expression_temp_var(), 565 *owner()->parsed_function().expression_temp_var(),
569 compare)); 566 compare));
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 Value* instantiator_type_arguments = NULL; 635 Value* instantiator_type_arguments = NULL;
639 if (dst_type.IsInstantiated()) { 636 if (dst_type.IsInstantiated()) {
640 instantiator = BuildNullValue(); 637 instantiator = BuildNullValue();
641 instantiator_type_arguments = BuildNullValue(); 638 instantiator_type_arguments = BuildNullValue();
642 } else { 639 } else {
643 BuildTypecheckArguments(token_pos, 640 BuildTypecheckArguments(token_pos,
644 &instantiator, 641 &instantiator,
645 &instantiator_type_arguments); 642 &instantiator_type_arguments);
646 } 643 }
647 return new AssertAssignableComp(token_pos, 644 return new AssertAssignableComp(token_pos,
648 owner()->try_index(),
649 value, 645 value,
650 instantiator, 646 instantiator,
651 instantiator_type_arguments, 647 instantiator_type_arguments,
652 dst_type, 648 dst_type,
653 dst_name); 649 dst_name);
654 } 650 }
655 651
656 652
657 // Used for type casts and to test assignments. 653 // Used for type casts and to test assignments.
658 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos, 654 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos,
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 if (type.IsInstantiated()) { 736 if (type.IsInstantiated()) {
741 instantiator = BuildNullValue(); 737 instantiator = BuildNullValue();
742 instantiator_type_arguments = BuildNullValue(); 738 instantiator_type_arguments = BuildNullValue();
743 } else { 739 } else {
744 BuildTypecheckArguments(node->token_pos(), 740 BuildTypecheckArguments(node->token_pos(),
745 &instantiator, 741 &instantiator,
746 &instantiator_type_arguments); 742 &instantiator_type_arguments);
747 } 743 }
748 InstanceOfComp* instance_of = 744 InstanceOfComp* instance_of =
749 new InstanceOfComp(node->token_pos(), 745 new InstanceOfComp(node->token_pos(),
750 owner()->try_index(),
751 for_left_value.value(), 746 for_left_value.value(),
752 instantiator, 747 instantiator,
753 instantiator_type_arguments, 748 instantiator_type_arguments,
754 node->right()->AsTypeNode()->type(), 749 node->right()->AsTypeNode()->type(),
755 (node->kind() == Token::kISNOT)); 750 (node->kind() == Token::kISNOT));
756 ReturnComputation(instance_of); 751 ReturnComputation(instance_of);
757 } 752 }
758 753
759 754
760 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { 755 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 797
803 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { 798 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) {
804 ValueGraphVisitor for_left_value(owner(), temp_index()); 799 ValueGraphVisitor for_left_value(owner(), temp_index());
805 node->left()->Visit(&for_left_value); 800 node->left()->Visit(&for_left_value);
806 Append(for_left_value); 801 Append(for_left_value);
807 ValueGraphVisitor for_right_value(owner(), temp_index()); 802 ValueGraphVisitor for_right_value(owner(), temp_index());
808 node->right()->Visit(&for_right_value); 803 node->right()->Visit(&for_right_value);
809 Append(for_right_value); 804 Append(for_right_value);
810 if (FLAG_enable_type_checks) { 805 if (FLAG_enable_type_checks) {
811 EqualityCompareComp* comp = new EqualityCompareComp( 806 EqualityCompareComp* comp = new EqualityCompareComp(
812 node->token_pos(), owner()->try_index(), 807 node->token_pos(),
813 Token::kEQ, for_left_value.value(), for_right_value.value()); 808 Token::kEQ,
809 for_left_value.value(),
810 for_right_value.value());
814 if (node->kind() == Token::kEQ) { 811 if (node->kind() == Token::kEQ) {
815 ReturnComputation(comp); 812 ReturnComputation(comp);
816 } else { 813 } else {
817 Value* eq_result = Bind(comp); 814 Value* eq_result = Bind(comp);
818 eq_result = Bind(new AssertBooleanComp(node->token_pos(), 815 eq_result = Bind(new AssertBooleanComp(node->token_pos(), eq_result));
819 owner()->try_index(),
820 eq_result));
821 ReturnComputation(new BooleanNegateComp(eq_result)); 816 ReturnComputation(new BooleanNegateComp(eq_result));
822 } 817 }
823 } else { 818 } else {
824 EqualityCompareComp* comp = new EqualityCompareComp( 819 EqualityCompareComp* comp = new EqualityCompareComp(
825 node->token_pos(), owner()->try_index(), 820 node->token_pos(),
826 node->kind(), for_left_value.value(), for_right_value.value()); 821 node->kind(),
822 for_left_value.value(),
823 for_right_value.value());
827 ReturnComputation(comp); 824 ReturnComputation(comp);
828 } 825 }
829 return; 826 return;
830 } 827 }
831 828
832 ValueGraphVisitor for_left_value(owner(), temp_index()); 829 ValueGraphVisitor for_left_value(owner(), temp_index());
833 node->left()->Visit(&for_left_value); 830 node->left()->Visit(&for_left_value);
834 Append(for_left_value); 831 Append(for_left_value);
835 ValueGraphVisitor for_right_value(owner(), temp_index()); 832 ValueGraphVisitor for_right_value(owner(), temp_index());
836 node->right()->Visit(&for_right_value); 833 node->right()->Visit(&for_right_value);
837 Append(for_right_value); 834 Append(for_right_value);
838 RelationalOpComp* comp = new RelationalOpComp(node->token_pos(), 835 RelationalOpComp* comp = new RelationalOpComp(node->token_pos(),
839 owner()->try_index(),
840 node->kind(), 836 node->kind(),
841 for_left_value.value(), 837 for_left_value.value(),
842 for_right_value.value()); 838 for_right_value.value());
843 ReturnComputation(comp); 839 ReturnComputation(comp);
844 } 840 }
845 841
846 842
847 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { 843 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
848 // "!" cannot be overloaded, therefore do not call operator. 844 // "!" cannot be overloaded, therefore do not call operator.
849 if (node->kind() == Token::kNOT) { 845 if (node->kind() == Token::kNOT) {
850 ValueGraphVisitor for_value(owner(), temp_index()); 846 ValueGraphVisitor for_value(owner(), temp_index());
851 node->operand()->Visit(&for_value); 847 node->operand()->Visit(&for_value);
852 Append(for_value); 848 Append(for_value);
853 Value* value = for_value.value(); 849 Value* value = for_value.value();
854 if (FLAG_enable_type_checks) { 850 if (FLAG_enable_type_checks) {
855 value = 851 value =
856 Bind(new AssertBooleanComp(node->operand()->token_pos(), 852 Bind(new AssertBooleanComp(node->operand()->token_pos(), value));
857 owner()->try_index(),
858 value));
859 } 853 }
860 BooleanNegateComp* negate = new BooleanNegateComp(value); 854 BooleanNegateComp* negate = new BooleanNegateComp(value);
861 ReturnComputation(negate); 855 ReturnComputation(negate);
862 return; 856 return;
863 } 857 }
864 ValueGraphVisitor for_value(owner(), temp_index()); 858 ValueGraphVisitor for_value(owner(), temp_index());
865 node->operand()->Visit(&for_value); 859 node->operand()->Visit(&for_value);
866 Append(for_value); 860 Append(for_value);
867 PushArgumentInstr* push_value = PushArgument(for_value.value()); 861 PushArgumentInstr* push_value = PushArgument(for_value.value());
868 ZoneGrowableArray<PushArgumentInstr*>* arguments = 862 ZoneGrowableArray<PushArgumentInstr*>* arguments =
869 new ZoneGrowableArray<PushArgumentInstr*>(1); 863 new ZoneGrowableArray<PushArgumentInstr*>(1);
870 arguments->Add(push_value); 864 arguments->Add(push_value);
871 String& name = String::ZoneHandle(); 865 String& name = String::ZoneHandle();
872 if (node->kind() == Token::kSUB) { 866 if (node->kind() == Token::kSUB) {
873 name = Symbols::New("unary-"); 867 name = Symbols::New("unary-");
874 } else { 868 } else {
875 name = Symbols::New(Token::Str(node->kind())); 869 name = Symbols::New(Token::Str(node->kind()));
876 } 870 }
877 InstanceCallComp* call = new InstanceCallComp( 871 InstanceCallComp* call = new InstanceCallComp(
878 node->token_pos(), owner()->try_index(), name, node->kind(), 872 node->token_pos(), name, node->kind(),
879 arguments, Array::ZoneHandle(), 1); 873 arguments, Array::ZoneHandle(), 1);
880 ReturnComputation(call); 874 ReturnComputation(call);
881 } 875 }
882 876
883 877
884 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { 878 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
885 TestGraphVisitor for_test(owner(), 879 TestGraphVisitor for_test(owner(),
886 temp_index(), 880 temp_index(),
887 node->condition()->token_pos()); 881 node->condition()->token_pos());
888 node->condition()->Visit(&for_test); 882 node->condition()->Visit(&for_test);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
980 const intptr_t len = node->case_expressions()->length(); 974 const intptr_t len = node->case_expressions()->length();
981 // Create case statements instructions. 975 // Create case statements instructions.
982 EffectGraphVisitor for_case_statements(owner(), temp_index()); 976 EffectGraphVisitor for_case_statements(owner(), temp_index());
983 // Compute start of statements fragment. 977 // Compute start of statements fragment.
984 JoinEntryInstr* statement_start = NULL; 978 JoinEntryInstr* statement_start = NULL;
985 if ((node->label() != NULL) && node->label()->is_continue_target()) { 979 if ((node->label() != NULL) && node->label()->is_continue_target()) {
986 // Since a labeled jump continue statement occur in a different case node, 980 // Since a labeled jump continue statement occur in a different case node,
987 // allocate JoinNode here and use it as statement start. 981 // allocate JoinNode here and use it as statement start.
988 statement_start = node->label()->join_for_continue(); 982 statement_start = node->label()->join_for_continue();
989 if (statement_start == NULL) { 983 if (statement_start == NULL) {
990 statement_start = new JoinEntryInstr(); 984 statement_start = new JoinEntryInstr(owner()->try_index());
991 node->label()->set_join_for_continue(statement_start); 985 node->label()->set_join_for_continue(statement_start);
992 } 986 }
993 } else { 987 } else {
994 statement_start = new JoinEntryInstr(); 988 statement_start = new JoinEntryInstr(owner()->try_index());
995 } 989 }
996 node->statements()->Visit(&for_case_statements); 990 node->statements()->Visit(&for_case_statements);
997 Instruction* statement_exit = 991 Instruction* statement_exit =
998 AppendFragment(statement_start, for_case_statements); 992 AppendFragment(statement_start, for_case_statements);
999 if (is_open() && (len == 0)) { 993 if (is_open() && (len == 0)) {
1000 ASSERT(node->contains_default()); 994 ASSERT(node->contains_default());
1001 // Default only case node. 995 // Default only case node.
1002 Goto(statement_start); 996 Goto(statement_start);
1003 exit_ = statement_exit; 997 exit_ = statement_exit;
1004 return; 998 return;
1005 } 999 }
1006 1000
1007 // Generate instructions for all case expressions. 1001 // Generate instructions for all case expressions.
1008 TargetEntryInstr** previous_false_address = NULL; 1002 TargetEntryInstr** previous_false_address = NULL;
1009 for (intptr_t i = 0; i < len; i++) { 1003 for (intptr_t i = 0; i < len; i++) {
1010 AstNode* case_expr = node->case_expressions()->NodeAt(i); 1004 AstNode* case_expr = node->case_expressions()->NodeAt(i);
1011 TestGraphVisitor for_case_expression(owner(), 1005 TestGraphVisitor for_case_expression(owner(),
1012 temp_index(), 1006 temp_index(),
1013 case_expr->token_pos()); 1007 case_expr->token_pos());
1014 case_expr->Visit(&for_case_expression); 1008 case_expr->Visit(&for_case_expression);
1015 if (i == 0) { 1009 if (i == 0) {
1016 // Append only the first one, everything else is connected from it. 1010 // Append only the first one, everything else is connected from it.
1017 Append(for_case_expression); 1011 Append(for_case_expression);
1018 } else { 1012 } else {
1019 TargetEntryInstr* case_entry_target = new TargetEntryInstr(); 1013 TargetEntryInstr* case_entry_target =
1014 new TargetEntryInstr(owner()->try_index());
1020 AppendFragment(case_entry_target, for_case_expression); 1015 AppendFragment(case_entry_target, for_case_expression);
1021 *previous_false_address = case_entry_target; 1016 *previous_false_address = case_entry_target;
1022 } 1017 }
1023 TargetEntryInstr* true_target = new TargetEntryInstr(); 1018 TargetEntryInstr* true_target =
1019 new TargetEntryInstr(owner()->try_index());
1024 *for_case_expression.true_successor_address() = true_target; 1020 *for_case_expression.true_successor_address() = true_target;
1025 true_target->Goto(statement_start); 1021 true_target->Goto(statement_start);
1026 previous_false_address = for_case_expression.false_successor_address(); 1022 previous_false_address = for_case_expression.false_successor_address();
1027 } 1023 }
1028 1024
1029 // Once a test fragment has been added, this fragment is closed. 1025 // Once a test fragment has been added, this fragment is closed.
1030 ASSERT(!is_open()); 1026 ASSERT(!is_open());
1031 1027
1032 Instruction* exit_instruction = NULL; 1028 Instruction* exit_instruction = NULL;
1033 // Handle last (or only) case: false goes to exit or to statement if this 1029 // Handle last (or only) case: false goes to exit or to statement if this
1034 // node contains default. 1030 // node contains default.
1035 if (len > 0) { 1031 if (len > 0) {
1036 TargetEntryInstr* false_target = new TargetEntryInstr(); 1032 TargetEntryInstr* false_target =
1033 new TargetEntryInstr(owner()->try_index());
1037 *previous_false_address = false_target; 1034 *previous_false_address = false_target;
1038 if (node->contains_default()) { 1035 if (node->contains_default()) {
1039 // True and false go to statement start. 1036 // True and false go to statement start.
1040 false_target->Goto(statement_start); 1037 false_target->Goto(statement_start);
1041 exit_instruction = statement_exit; 1038 exit_instruction = statement_exit;
1042 } else { 1039 } else {
1043 if (statement_exit != NULL) { 1040 if (statement_exit != NULL) {
1044 JoinEntryInstr* join = new JoinEntryInstr(); 1041 JoinEntryInstr* join = new JoinEntryInstr(owner()->try_index());
1045 statement_exit->Goto(join); 1042 statement_exit->Goto(join);
1046 false_target->Goto(join); 1043 false_target->Goto(join);
1047 exit_instruction = join; 1044 exit_instruction = join;
1048 } else { 1045 } else {
1049 exit_instruction = false_target; 1046 exit_instruction = false_target;
1050 } 1047 }
1051 } 1048 }
1052 } else { 1049 } else {
1053 // A CaseNode without case expressions must contain default. 1050 // A CaseNode without case expressions must contain default.
1054 ASSERT(node->contains_default()); 1051 ASSERT(node->contains_default());
(...skipping 19 matching lines...) Expand all
1074 // g) break-join (optional) 1071 // g) break-join (optional)
1075 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { 1072 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) {
1076 TestGraphVisitor for_test(owner(), 1073 TestGraphVisitor for_test(owner(),
1077 temp_index(), 1074 temp_index(),
1078 node->condition()->token_pos()); 1075 node->condition()->token_pos());
1079 node->condition()->Visit(&for_test); 1076 node->condition()->Visit(&for_test);
1080 ASSERT(!for_test.is_empty()); // Language spec. 1077 ASSERT(!for_test.is_empty()); // Language spec.
1081 1078
1082 EffectGraphVisitor for_body(owner(), temp_index()); 1079 EffectGraphVisitor for_body(owner(), temp_index());
1083 for_body.Do( 1080 for_body.Do(
1084 new CheckStackOverflowComp(node->token_pos(), owner()->try_index())); 1081 new CheckStackOverflowComp(node->token_pos()));
1085 node->body()->Visit(&for_body); 1082 node->body()->Visit(&for_body);
1086 1083
1087 // Labels are set after body traversal. 1084 // Labels are set after body traversal.
1088 SourceLabel* lbl = node->label(); 1085 SourceLabel* lbl = node->label();
1089 ASSERT(lbl != NULL); 1086 ASSERT(lbl != NULL);
1090 JoinEntryInstr* join = lbl->join_for_continue(); 1087 JoinEntryInstr* join = lbl->join_for_continue();
1091 if (join != NULL) { 1088 if (join != NULL) {
1092 if (for_body.is_open()) for_body.Goto(join); 1089 if (for_body.is_open()) for_body.Goto(join);
1093 for_body.exit_ = join; 1090 for_body.exit_ = join;
1094 } 1091 }
(...skipping 11 matching lines...) Expand all
1106 // b) [ body ] 1103 // b) [ body ]
1107 // c) test-entry (continue-join or body-exit-target) 1104 // c) test-entry (continue-join or body-exit-target)
1108 // d) [ test-entry ] -> (back-target, loop-exit-target) 1105 // d) [ test-entry ] -> (back-target, loop-exit-target)
1109 // e) back-target -> (body-entry-join) 1106 // e) back-target -> (body-entry-join)
1110 // f) loop-exit-target 1107 // f) loop-exit-target
1111 // g) break-join 1108 // g) break-join
1112 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { 1109 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) {
1113 // Traverse body first in order to generate continue and break labels. 1110 // Traverse body first in order to generate continue and break labels.
1114 EffectGraphVisitor for_body(owner(), temp_index()); 1111 EffectGraphVisitor for_body(owner(), temp_index());
1115 for_body.Do( 1112 for_body.Do(
1116 new CheckStackOverflowComp(node->token_pos(), owner()->try_index())); 1113 new CheckStackOverflowComp(node->token_pos()));
1117 node->body()->Visit(&for_body); 1114 node->body()->Visit(&for_body);
1118 1115
1119 TestGraphVisitor for_test(owner(), 1116 TestGraphVisitor for_test(owner(),
1120 temp_index(), 1117 temp_index(),
1121 node->condition()->token_pos()); 1118 node->condition()->token_pos());
1122 node->condition()->Visit(&for_test); 1119 node->condition()->Visit(&for_test);
1123 ASSERT(is_open()); 1120 ASSERT(is_open());
1124 1121
1125 // Tie do-while loop (test is after the body). 1122 // Tie do-while loop (test is after the body).
1126 JoinEntryInstr* body_entry_join = new JoinEntryInstr(); 1123 JoinEntryInstr* body_entry_join = new JoinEntryInstr(owner()->try_index());
1127 Goto(body_entry_join); 1124 Goto(body_entry_join);
1128 Instruction* body_exit = AppendFragment(body_entry_join, for_body); 1125 Instruction* body_exit = AppendFragment(body_entry_join, for_body);
1129 1126
1130 JoinEntryInstr* join = node->label()->join_for_continue(); 1127 JoinEntryInstr* join = node->label()->join_for_continue();
1131 if ((body_exit != NULL) || (join != NULL)) { 1128 if ((body_exit != NULL) || (join != NULL)) {
1132 if (join == NULL) join = new JoinEntryInstr(); 1129 if (join == NULL) join = new JoinEntryInstr(owner()->try_index());
1133 join->set_next(for_test.entry()); 1130 join->set_next(for_test.entry());
1134 if (body_exit != NULL) { 1131 if (body_exit != NULL) {
1135 body_exit->Goto(join); 1132 body_exit->Goto(join);
1136 } 1133 }
1137 } 1134 }
1138 1135
1139 TargetEntryInstr* back_target_entry = new TargetEntryInstr(); 1136 TargetEntryInstr* back_target_entry =
1137 new TargetEntryInstr(owner()->try_index());
1140 *for_test.true_successor_address() = back_target_entry; 1138 *for_test.true_successor_address() = back_target_entry;
1141 back_target_entry->Goto(body_entry_join); 1139 back_target_entry->Goto(body_entry_join);
1142 TargetEntryInstr* loop_exit_target = new TargetEntryInstr(); 1140 TargetEntryInstr* loop_exit_target =
1141 new TargetEntryInstr(owner()->try_index());
1143 *for_test.false_successor_address() = loop_exit_target; 1142 *for_test.false_successor_address() = loop_exit_target;
1144 if (node->label()->join_for_break() == NULL) { 1143 if (node->label()->join_for_break() == NULL) {
1145 exit_ = loop_exit_target; 1144 exit_ = loop_exit_target;
1146 } else { 1145 } else {
1147 loop_exit_target->Goto(node->label()->join_for_break()); 1146 loop_exit_target->Goto(node->label()->join_for_break());
1148 exit_ = node->label()->join_for_break(); 1147 exit_ = node->label()->join_for_break();
1149 } 1148 }
1150 } 1149 }
1151 1150
1152 1151
(...skipping 11 matching lines...) Expand all
1164 // i) break-join 1163 // i) break-join
1165 void EffectGraphVisitor::VisitForNode(ForNode* node) { 1164 void EffectGraphVisitor::VisitForNode(ForNode* node) {
1166 EffectGraphVisitor for_initializer(owner(), temp_index()); 1165 EffectGraphVisitor for_initializer(owner(), temp_index());
1167 node->initializer()->Visit(&for_initializer); 1166 node->initializer()->Visit(&for_initializer);
1168 Append(for_initializer); 1167 Append(for_initializer);
1169 ASSERT(is_open()); 1168 ASSERT(is_open());
1170 1169
1171 // Compose body to set any jump labels. 1170 // Compose body to set any jump labels.
1172 EffectGraphVisitor for_body(owner(), temp_index()); 1171 EffectGraphVisitor for_body(owner(), temp_index());
1173 for_body.Do( 1172 for_body.Do(
1174 new CheckStackOverflowComp(node->token_pos(), owner()->try_index())); 1173 new CheckStackOverflowComp(node->token_pos()));
1175 node->body()->Visit(&for_body); 1174 node->body()->Visit(&for_body);
1176 1175
1177 // Join loop body, increment and compute their end instruction. 1176 // Join loop body, increment and compute their end instruction.
1178 ASSERT(!for_body.is_empty()); 1177 ASSERT(!for_body.is_empty());
1179 Instruction* loop_increment_end = NULL; 1178 Instruction* loop_increment_end = NULL;
1180 EffectGraphVisitor for_increment(owner(), temp_index()); 1179 EffectGraphVisitor for_increment(owner(), temp_index());
1181 node->increment()->Visit(&for_increment); 1180 node->increment()->Visit(&for_increment);
1182 JoinEntryInstr* join = node->label()->join_for_continue(); 1181 JoinEntryInstr* join = node->label()->join_for_continue();
1183 if (join != NULL) { 1182 if (join != NULL) {
1184 // Insert the join between the body and increment. 1183 // Insert the join between the body and increment.
1185 if (for_body.is_open()) for_body.Goto(join); 1184 if (for_body.is_open()) for_body.Goto(join);
1186 loop_increment_end = AppendFragment(join, for_increment); 1185 loop_increment_end = AppendFragment(join, for_increment);
1187 ASSERT(loop_increment_end != NULL); 1186 ASSERT(loop_increment_end != NULL);
1188 } else if (for_body.is_open()) { 1187 } else if (for_body.is_open()) {
1189 // Do not insert an extra basic block. 1188 // Do not insert an extra basic block.
1190 for_body.Append(for_increment); 1189 for_body.Append(for_increment);
1191 loop_increment_end = for_body.exit(); 1190 loop_increment_end = for_body.exit();
1192 // 'for_body' contains at least the stack check. 1191 // 'for_body' contains at least the stack check.
1193 ASSERT(loop_increment_end != NULL); 1192 ASSERT(loop_increment_end != NULL);
1194 } else { 1193 } else {
1195 loop_increment_end = NULL; 1194 loop_increment_end = NULL;
1196 } 1195 }
1197 1196
1198 // 'loop_increment_end' is NULL only if there is no join for continue and the 1197 // 'loop_increment_end' is NULL only if there is no join for continue and the
1199 // body is not open, i.e., no backward branch exists. 1198 // body is not open, i.e., no backward branch exists.
1200 if (loop_increment_end != NULL) { 1199 if (loop_increment_end != NULL) {
1201 JoinEntryInstr* loop_start = new JoinEntryInstr(); 1200 JoinEntryInstr* loop_start = new JoinEntryInstr(owner()->try_index());
1202 Goto(loop_start); 1201 Goto(loop_start);
1203 loop_increment_end->Goto(loop_start); 1202 loop_increment_end->Goto(loop_start);
1204 exit_ = loop_start; 1203 exit_ = loop_start;
1205 } 1204 }
1206 1205
1207 if (node->condition() == NULL) { 1206 if (node->condition() == NULL) {
1208 // Endless loop, no test. 1207 // Endless loop, no test.
1209 JoinEntryInstr* body_entry = new JoinEntryInstr(); 1208 JoinEntryInstr* body_entry = new JoinEntryInstr(owner()->try_index());
1210 AppendFragment(body_entry, for_body); 1209 AppendFragment(body_entry, for_body);
1211 Goto(body_entry); 1210 Goto(body_entry);
1212 if (node->label()->join_for_break() != NULL) { 1211 if (node->label()->join_for_break() != NULL) {
1213 // Control flow of ForLoop continues into join_for_break. 1212 // Control flow of ForLoop continues into join_for_break.
1214 exit_ = node->label()->join_for_break(); 1213 exit_ = node->label()->join_for_break();
1215 } 1214 }
1216 } else { 1215 } else {
1217 TargetEntryInstr* loop_exit = new TargetEntryInstr(); 1216 TargetEntryInstr* loop_exit = new TargetEntryInstr(owner()->try_index());
1218 TestGraphVisitor for_test(owner(), 1217 TestGraphVisitor for_test(owner(),
1219 temp_index(), 1218 temp_index(),
1220 node->condition()->token_pos()); 1219 node->condition()->token_pos());
1221 node->condition()->Visit(&for_test); 1220 node->condition()->Visit(&for_test);
1222 Append(for_test); 1221 Append(for_test);
1223 TargetEntryInstr* body_entry = new TargetEntryInstr(); 1222 TargetEntryInstr* body_entry = new TargetEntryInstr(owner()->try_index());
1224 AppendFragment(body_entry, for_body); 1223 AppendFragment(body_entry, for_body);
1225 *for_test.true_successor_address() = body_entry; 1224 *for_test.true_successor_address() = body_entry;
1226 *for_test.false_successor_address() = loop_exit; 1225 *for_test.false_successor_address() = loop_exit;
1227 if (node->label()->join_for_break() == NULL) { 1226 if (node->label()->join_for_break() == NULL) {
1228 exit_ = loop_exit; 1227 exit_ = loop_exit;
1229 } else { 1228 } else {
1230 loop_exit->Goto(node->label()->join_for_break()); 1229 loop_exit->Goto(node->label()->join_for_break());
1231 exit_ = node->label()->join_for_break(); 1230 exit_ = node->label()->join_for_break();
1232 } 1231 }
1233 } 1232 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1266 ASSERT(target_context_level >= 0); 1265 ASSERT(target_context_level >= 0);
1267 intptr_t current_context_level = owner()->context_level(); 1266 intptr_t current_context_level = owner()->context_level();
1268 ASSERT(current_context_level >= target_context_level); 1267 ASSERT(current_context_level >= target_context_level);
1269 while (current_context_level-- > target_context_level) { 1268 while (current_context_level-- > target_context_level) {
1270 UnchainContext(); 1269 UnchainContext();
1271 } 1270 }
1272 1271
1273 JoinEntryInstr* jump_target = NULL; 1272 JoinEntryInstr* jump_target = NULL;
1274 if (node->kind() == Token::kBREAK) { 1273 if (node->kind() == Token::kBREAK) {
1275 if (node->label()->join_for_break() == NULL) { 1274 if (node->label()->join_for_break() == NULL) {
1276 node->label()->set_join_for_break(new JoinEntryInstr()); 1275 node->label()->set_join_for_break(
1276 new JoinEntryInstr(owner()->try_index()));
1277 } 1277 }
1278 jump_target = node->label()->join_for_break(); 1278 jump_target = node->label()->join_for_break();
1279 } else { 1279 } else {
1280 if (node->label()->join_for_continue() == NULL) { 1280 if (node->label()->join_for_continue() == NULL) {
1281 node->label()->set_join_for_continue(new JoinEntryInstr()); 1281 node->label()->set_join_for_continue(
1282 new JoinEntryInstr(owner()->try_index()));
1282 } 1283 }
1283 jump_target = node->label()->join_for_continue(); 1284 jump_target = node->label()->join_for_continue();
1284 } 1285 }
1285 Goto(jump_target); 1286 Goto(jump_target);
1286 } 1287 }
1287 1288
1288 1289
1289 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { 1290 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) {
1290 UNREACHABLE(); 1291 UNREACHABLE();
1291 } 1292 }
1292 1293
1293 1294
1294 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { 1295 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) {
1295 // Translate the array elements and collect their values. 1296 // Translate the array elements and collect their values.
1296 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1297 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1297 new ZoneGrowableArray<PushArgumentInstr*>(node->length()); 1298 new ZoneGrowableArray<PushArgumentInstr*>(node->length());
1298 for (int i = 0; i < node->length(); ++i) { 1299 for (int i = 0; i < node->length(); ++i) {
1299 ValueGraphVisitor for_value(owner(), temp_index()); 1300 ValueGraphVisitor for_value(owner(), temp_index());
1300 node->ElementAt(i)->Visit(&for_value); 1301 node->ElementAt(i)->Visit(&for_value);
1301 Append(for_value); 1302 Append(for_value);
1302 arguments->Add(PushArgument(for_value.value())); 1303 arguments->Add(PushArgument(for_value.value()));
1303 } 1304 }
1304 const AbstractTypeArguments& type_args = 1305 const AbstractTypeArguments& type_args =
1305 AbstractTypeArguments::ZoneHandle(node->type().arguments()); 1306 AbstractTypeArguments::ZoneHandle(node->type().arguments());
1306 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), 1307 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(),
1307 type_args); 1308 type_args);
1308 CreateArrayComp* create = new CreateArrayComp(node->token_pos(), 1309 CreateArrayComp* create = new CreateArrayComp(node->token_pos(),
1309 owner()->try_index(),
1310 arguments, 1310 arguments,
1311 node->type(), 1311 node->type(),
1312 element_type); 1312 element_type);
1313 ReturnComputation(create); 1313 ReturnComputation(create);
1314 } 1314 }
1315 1315
1316 1316
1317 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { 1317 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) {
1318 const Function& function = node->function(); 1318 const Function& function = node->function();
1319 1319
(...skipping 30 matching lines...) Expand all
1350 const bool requires_type_arguments = cls.HasTypeArguments(); 1350 const bool requires_type_arguments = cls.HasTypeArguments();
1351 Value* type_arguments = NULL; 1351 Value* type_arguments = NULL;
1352 if (requires_type_arguments) { 1352 if (requires_type_arguments) {
1353 ASSERT(!function.IsImplicitStaticClosureFunction()); 1353 ASSERT(!function.IsImplicitStaticClosureFunction());
1354 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), NULL); 1354 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), NULL);
1355 } else { 1355 } else {
1356 type_arguments = BuildNullValue(); 1356 type_arguments = BuildNullValue();
1357 } 1357 }
1358 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments); 1358 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments);
1359 arguments->Add(push_type_arguments); 1359 arguments->Add(push_type_arguments);
1360 ReturnComputation( 1360 ReturnComputation(new CreateClosureComp(node, arguments));
1361 new CreateClosureComp(node, owner()->try_index(), arguments));
1362 } 1361 }
1363 1362
1364 1363
1365 void EffectGraphVisitor::TranslateArgumentList( 1364 void EffectGraphVisitor::TranslateArgumentList(
1366 const ArgumentListNode& node, 1365 const ArgumentListNode& node,
1367 ZoneGrowableArray<Value*>* values) { 1366 ZoneGrowableArray<Value*>* values) {
1368 for (intptr_t i = 0; i < node.length(); ++i) { 1367 for (intptr_t i = 0; i < node.length(); ++i) {
1369 ValueGraphVisitor for_argument(owner(), temp_index()); 1368 ValueGraphVisitor for_argument(owner(), temp_index());
1370 node.NodeAt(i)->Visit(&for_argument); 1369 node.NodeAt(i)->Visit(&for_argument);
1371 Append(for_argument); 1370 Append(for_argument);
(...skipping 20 matching lines...) Expand all
1392 node->receiver()->Visit(&for_receiver); 1391 node->receiver()->Visit(&for_receiver);
1393 Append(for_receiver); 1392 Append(for_receiver);
1394 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); 1393 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
1395 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1394 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1396 new ZoneGrowableArray<PushArgumentInstr*>( 1395 new ZoneGrowableArray<PushArgumentInstr*>(
1397 node->arguments()->length() + 1); 1396 node->arguments()->length() + 1);
1398 arguments->Add(push_receiver); 1397 arguments->Add(push_receiver);
1399 1398
1400 BuildPushArguments(*node->arguments(), arguments); 1399 BuildPushArguments(*node->arguments(), arguments);
1401 InstanceCallComp* call = new InstanceCallComp( 1400 InstanceCallComp* call = new InstanceCallComp(
1402 node->token_pos(), owner()->try_index(), 1401 node->token_pos(),
1403 node->function_name(), Token::kILLEGAL, arguments, 1402 node->function_name(), Token::kILLEGAL, arguments,
1404 node->arguments()->names(), 1); 1403 node->arguments()->names(), 1);
1405 ReturnComputation(call); 1404 ReturnComputation(call);
1406 } 1405 }
1407 1406
1408 1407
1409 // <Expression> ::= StaticCall { function: Function 1408 // <Expression> ::= StaticCall { function: Function
1410 // arguments: <ArgumentList> } 1409 // arguments: <ArgumentList> }
1411 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { 1410 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
1412 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1411 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1413 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); 1412 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length());
1414 BuildPushArguments(*node->arguments(), arguments); 1413 BuildPushArguments(*node->arguments(), arguments);
1415 StaticCallComp* call = 1414 StaticCallComp* call =
1416 new StaticCallComp(node->token_pos(), 1415 new StaticCallComp(node->token_pos(),
1417 owner()->try_index(),
1418 node->function(), 1416 node->function(),
1419 node->arguments()->names(), 1417 node->arguments()->names(),
1420 arguments); 1418 arguments);
1421 ReturnComputation(call); 1419 ReturnComputation(call);
1422 } 1420 }
1423 1421
1424 1422
1425 ClosureCallComp* EffectGraphVisitor::BuildClosureCall( 1423 ClosureCallComp* EffectGraphVisitor::BuildClosureCall(
1426 ClosureCallNode* node) { 1424 ClosureCallNode* node) {
1427 ValueGraphVisitor for_closure(owner(), temp_index()); 1425 ValueGraphVisitor for_closure(owner(), temp_index());
1428 node->closure()->Visit(&for_closure); 1426 node->closure()->Visit(&for_closure);
1429 Append(for_closure); 1427 Append(for_closure);
1430 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); 1428 PushArgumentInstr* push_closure = PushArgument(for_closure.value());
1431 1429
1432 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1430 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1433 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); 1431 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length());
1434 arguments->Add(push_closure); 1432 arguments->Add(push_closure);
1435 BuildPushArguments(*node->arguments(), arguments); 1433 BuildPushArguments(*node->arguments(), arguments);
1436 1434
1437 // Save context around the call. 1435 // Save context around the call.
1438 BuildStoreContext(*owner()->parsed_function().expression_temp_var()); 1436 BuildStoreContext(*owner()->parsed_function().expression_temp_var());
1439 return new ClosureCallComp(node, owner()->try_index(), arguments); 1437 return new ClosureCallComp(node, arguments);
1440 } 1438 }
1441 1439
1442 1440
1443 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { 1441 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
1444 Do(BuildClosureCall(node)); 1442 Do(BuildClosureCall(node));
1445 // Restore context from saved location. 1443 // Restore context from saved location.
1446 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); 1444 BuildLoadContext(*owner()->parsed_function().expression_temp_var());
1447 } 1445 }
1448 1446
1449 1447
1450 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { 1448 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
1451 Value* result = Bind(BuildClosureCall(node)); 1449 Value* result = Bind(BuildClosureCall(node));
1452 // Restore context from temp. 1450 // Restore context from temp.
1453 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); 1451 BuildLoadContext(*owner()->parsed_function().expression_temp_var());
1454 ReturnValue(result); 1452 ReturnValue(result);
1455 } 1453 }
1456 1454
1457 1455
1458 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { 1456 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
1459 Value* context = Bind(new CurrentContextComp()); 1457 Value* context = Bind(new CurrentContextComp());
1460 Value* clone = Bind(new CloneContextComp(node->token_pos(), 1458 Value* clone = Bind(new CloneContextComp(node->token_pos(), context));
1461 owner()->try_index(),
1462 context));
1463 ReturnComputation(new StoreContextComp(clone)); 1459 ReturnComputation(new StoreContextComp(clone));
1464 } 1460 }
1465 1461
1466 1462
1467 Value* EffectGraphVisitor::BuildObjectAllocation( 1463 Value* EffectGraphVisitor::BuildObjectAllocation(
1468 ConstructorCallNode* node) { 1464 ConstructorCallNode* node) {
1469 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); 1465 const Class& cls = Class::ZoneHandle(node->constructor().Owner());
1470 const bool requires_type_arguments = cls.HasTypeArguments(); 1466 const bool requires_type_arguments = cls.HasTypeArguments();
1471 1467
1472 // In checked mode, if the type arguments are uninstantiated, they may need to 1468 // In checked mode, if the type arguments are uninstantiated, they may need to
1473 // be checked against declared bounds at run time. 1469 // be checked against declared bounds at run time.
1474 Computation* allocate_comp = NULL; 1470 Computation* allocate_comp = NULL;
1475 if (FLAG_enable_type_checks && 1471 if (FLAG_enable_type_checks &&
1476 requires_type_arguments && 1472 requires_type_arguments &&
1477 !node->type_arguments().IsNull() && 1473 !node->type_arguments().IsNull() &&
1478 !node->type_arguments().IsInstantiated() && 1474 !node->type_arguments().IsInstantiated() &&
1479 !node->type_arguments().IsWithinBoundsOf(cls, 1475 !node->type_arguments().IsWithinBoundsOf(cls,
1480 node->type_arguments(), 1476 node->type_arguments(),
1481 NULL)) { 1477 NULL)) {
1482 Value* type_arguments = NULL; 1478 Value* type_arguments = NULL;
1483 Value* instantiator = NULL; 1479 Value* instantiator = NULL;
1484 BuildConstructorTypeArguments(node, &type_arguments, &instantiator, NULL); 1480 BuildConstructorTypeArguments(node, &type_arguments, &instantiator, NULL);
1485 1481
1486 // The uninstantiated type arguments cannot be verified to be within their 1482 // The uninstantiated type arguments cannot be verified to be within their
1487 // bounds at compile time, so verify them at runtime. 1483 // bounds at compile time, so verify them at runtime.
1488 // Although the type arguments may be uninstantiated at compile time, they 1484 // Although the type arguments may be uninstantiated at compile time, they
1489 // may represent the identity vector and may be replaced by the instantiated 1485 // may represent the identity vector and may be replaced by the instantiated
1490 // type arguments of the instantiator at run time. 1486 // type arguments of the instantiator at run time.
1491 allocate_comp = new AllocateObjectWithBoundsCheckComp(node, 1487 allocate_comp = new AllocateObjectWithBoundsCheckComp(node,
1492 owner()->try_index(),
1493 type_arguments, 1488 type_arguments,
1494 instantiator); 1489 instantiator);
1495 } else { 1490 } else {
1496 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = 1491 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments =
1497 new ZoneGrowableArray<PushArgumentInstr*>(); 1492 new ZoneGrowableArray<PushArgumentInstr*>();
1498 1493
1499 if (requires_type_arguments) { 1494 if (requires_type_arguments) {
1500 BuildConstructorTypeArguments(node, NULL, NULL, allocate_arguments); 1495 BuildConstructorTypeArguments(node, NULL, NULL, allocate_arguments);
1501 } 1496 }
1502 1497
1503 allocate_comp = new AllocateObjectComp(node, 1498 allocate_comp = new AllocateObjectComp(node, allocate_arguments);
1504 owner()->try_index(),
1505 allocate_arguments);
1506 } 1499 }
1507 return Bind(allocate_comp); 1500 return Bind(allocate_comp);
1508 } 1501 }
1509 1502
1510 1503
1511 void EffectGraphVisitor::BuildConstructorCall( 1504 void EffectGraphVisitor::BuildConstructorCall(
1512 ConstructorCallNode* node, 1505 ConstructorCallNode* node,
1513 PushArgumentInstr* push_alloc_value) { 1506 PushArgumentInstr* push_alloc_value) {
1514 Value* ctor_arg = Bind( 1507 Value* ctor_arg = Bind(
1515 Constant(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); 1508 Constant(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))));
1516 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); 1509 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg);
1517 1510
1518 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1511 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1519 new ZoneGrowableArray<PushArgumentInstr*>(2); 1512 new ZoneGrowableArray<PushArgumentInstr*>(2);
1520 arguments->Add(push_alloc_value); 1513 arguments->Add(push_alloc_value);
1521 arguments->Add(push_ctor_arg); 1514 arguments->Add(push_ctor_arg);
1522 1515
1523 BuildPushArguments(*node->arguments(), arguments); 1516 BuildPushArguments(*node->arguments(), arguments);
1524 Do(new StaticCallComp(node->token_pos(), 1517 Do(new StaticCallComp(node->token_pos(),
1525 owner()->try_index(),
1526 node->constructor(), 1518 node->constructor(),
1527 node->arguments()->names(), 1519 node->arguments()->names(),
1528 arguments)); 1520 arguments));
1529 } 1521 }
1530 1522
1531 1523
1532 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { 1524 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
1533 if (node->constructor().IsFactory()) { 1525 if (node->constructor().IsFactory()) {
1534 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1526 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1535 new ZoneGrowableArray<PushArgumentInstr*>(); 1527 new ZoneGrowableArray<PushArgumentInstr*>();
1536 PushArgumentInstr* push_type_arguments = PushArgument( 1528 PushArgumentInstr* push_type_arguments = PushArgument(
1537 BuildInstantiatedTypeArguments(node->token_pos(), 1529 BuildInstantiatedTypeArguments(node->token_pos(),
1538 node->type_arguments())); 1530 node->type_arguments()));
1539 arguments->Add(push_type_arguments); 1531 arguments->Add(push_type_arguments);
1540 ASSERT(arguments->length() == 1); 1532 ASSERT(arguments->length() == 1);
1541 BuildPushArguments(*node->arguments(), arguments); 1533 BuildPushArguments(*node->arguments(), arguments);
1542 StaticCallComp* call = 1534 StaticCallComp* call =
1543 new StaticCallComp(node->token_pos(), 1535 new StaticCallComp(node->token_pos(),
1544 owner()->try_index(),
1545 node->constructor(), 1536 node->constructor(),
1546 node->arguments()->names(), 1537 node->arguments()->names(),
1547 arguments); 1538 arguments);
1548 ReturnComputation(call); 1539 ReturnComputation(call);
1549 return; 1540 return;
1550 } 1541 }
1551 // t_n contains the allocated and initialized object. 1542 // t_n contains the allocated and initialized object.
1552 // t_n <- AllocateObject(class) 1543 // t_n <- AllocateObject(class)
1553 // t_n+1 <- ctor-arg 1544 // t_n+1 <- ctor-arg
1554 // t_n+2... <- constructor arguments start here 1545 // t_n+2... <- constructor arguments start here
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1637 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( 1628 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments(
1638 intptr_t token_pos, 1629 intptr_t token_pos,
1639 const AbstractTypeArguments& type_arguments) { 1630 const AbstractTypeArguments& type_arguments) {
1640 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { 1631 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) {
1641 return Bind(Constant(type_arguments)); 1632 return Bind(Constant(type_arguments));
1642 } 1633 }
1643 // The type arguments are uninstantiated. 1634 // The type arguments are uninstantiated.
1644 Value* instantiator_value = 1635 Value* instantiator_value =
1645 BuildInstantiatorTypeArguments(token_pos, NULL); 1636 BuildInstantiatorTypeArguments(token_pos, NULL);
1646 return Bind(new InstantiateTypeArgumentsComp(token_pos, 1637 return Bind(new InstantiateTypeArgumentsComp(token_pos,
1647 owner()->try_index(),
1648 type_arguments, 1638 type_arguments,
1649 instantiator_value)); 1639 instantiator_value));
1650 } 1640 }
1651 1641
1652 1642
1653 void EffectGraphVisitor::BuildConstructorTypeArguments( 1643 void EffectGraphVisitor::BuildConstructorTypeArguments(
1654 ConstructorCallNode* node, 1644 ConstructorCallNode* node,
1655 Value** type_arguments, 1645 Value** type_arguments,
1656 Value** instantiator, 1646 Value** instantiator,
1657 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) { 1647 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1694 Value* instantiator_type_arguments = BuildInstantiatorTypeArguments( 1684 Value* instantiator_type_arguments = BuildInstantiatorTypeArguments(
1695 node->token_pos(), NULL); 1685 node->token_pos(), NULL);
1696 ASSERT(instantiator_type_arguments->IsUse()); 1686 ASSERT(instantiator_type_arguments->IsUse());
1697 Value* stored_instantiator = 1687 Value* stored_instantiator =
1698 Bind(BuildStoreLocal(t1, instantiator_type_arguments)); 1688 Bind(BuildStoreLocal(t1, instantiator_type_arguments));
1699 // t1: instantiator type arguments. 1689 // t1: instantiator type arguments.
1700 1690
1701 Value* extract_type_arguments = Bind( 1691 Value* extract_type_arguments = Bind(
1702 new ExtractConstructorTypeArgumentsComp( 1692 new ExtractConstructorTypeArgumentsComp(
1703 node->token_pos(), 1693 node->token_pos(),
1704 owner()->try_index(),
1705 node->type_arguments(), 1694 node->type_arguments(),
1706 stored_instantiator)); 1695 stored_instantiator));
1707 1696
1708 Do(BuildStoreLocal(t2, extract_type_arguments)); 1697 Do(BuildStoreLocal(t2, extract_type_arguments));
1709 // t2: extracted constructor type arguments. 1698 // t2: extracted constructor type arguments.
1710 Value* load_instantiator = Bind(BuildLoadLocal(t1)); 1699 Value* load_instantiator = Bind(BuildLoadLocal(t1));
1711 1700
1712 Value* extract_instantiator = 1701 Value* extract_instantiator =
1713 Bind(new ExtractConstructorInstantiatorComp(node, load_instantiator)); 1702 Bind(new ExtractConstructorInstantiatorComp(node, load_instantiator));
1714 Do(BuildStoreLocal(t1, extract_instantiator)); 1703 Do(BuildStoreLocal(t1, extract_instantiator));
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1766 ValueGraphVisitor for_receiver(owner(), temp_index()); 1755 ValueGraphVisitor for_receiver(owner(), temp_index());
1767 node->receiver()->Visit(&for_receiver); 1756 node->receiver()->Visit(&for_receiver);
1768 Append(for_receiver); 1757 Append(for_receiver);
1769 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); 1758 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
1770 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1759 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1771 new ZoneGrowableArray<PushArgumentInstr*>(1); 1760 new ZoneGrowableArray<PushArgumentInstr*>(1);
1772 arguments->Add(push_receiver); 1761 arguments->Add(push_receiver);
1773 const String& name = 1762 const String& name =
1774 String::ZoneHandle(Field::GetterSymbol(node->field_name())); 1763 String::ZoneHandle(Field::GetterSymbol(node->field_name()));
1775 InstanceCallComp* call = new InstanceCallComp( 1764 InstanceCallComp* call = new InstanceCallComp(
1776 node->token_pos(), owner()->try_index(), name, Token::kGET, 1765 node->token_pos(), name, Token::kGET,
1777 arguments, Array::ZoneHandle(), 1); 1766 arguments, Array::ZoneHandle(), 1);
1778 ReturnComputation(call); 1767 ReturnComputation(call);
1779 } 1768 }
1780 1769
1781 1770
1782 void EffectGraphVisitor::BuildInstanceSetterArguments( 1771 void EffectGraphVisitor::BuildInstanceSetterArguments(
1783 InstanceSetterNode* node, 1772 InstanceSetterNode* node,
1784 ZoneGrowableArray<PushArgumentInstr*>* arguments, 1773 ZoneGrowableArray<PushArgumentInstr*>* arguments,
1785 bool result_is_needed) { 1774 bool result_is_needed) {
1786 ValueGraphVisitor for_receiver(owner(), temp_index()); 1775 ValueGraphVisitor for_receiver(owner(), temp_index());
(...skipping 17 matching lines...) Expand all
1804 } 1793 }
1805 1794
1806 1795
1807 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { 1796 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
1808 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1797 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1809 new ZoneGrowableArray<PushArgumentInstr*>(2); 1798 new ZoneGrowableArray<PushArgumentInstr*>(2);
1810 BuildInstanceSetterArguments(node, arguments, false); // Value not used. 1799 BuildInstanceSetterArguments(node, arguments, false); // Value not used.
1811 const String& name = 1800 const String& name =
1812 String::ZoneHandle(Field::SetterSymbol(node->field_name())); 1801 String::ZoneHandle(Field::SetterSymbol(node->field_name()));
1813 InstanceCallComp* call = new InstanceCallComp(node->token_pos(), 1802 InstanceCallComp* call = new InstanceCallComp(node->token_pos(),
1814 owner()->try_index(),
1815 name, 1803 name,
1816 Token::kSET, 1804 Token::kSET,
1817 arguments, 1805 arguments,
1818 Array::ZoneHandle(), 1806 Array::ZoneHandle(),
1819 1); // Checked argument count. 1807 1); // Checked argument count.
1820 ReturnComputation(call); 1808 ReturnComputation(call);
1821 } 1809 }
1822 1810
1823 1811
1824 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { 1812 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
1825 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1813 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1826 new ZoneGrowableArray<PushArgumentInstr*>(2); 1814 new ZoneGrowableArray<PushArgumentInstr*>(2);
1827 BuildInstanceSetterArguments(node, arguments, true); // Value used. 1815 BuildInstanceSetterArguments(node, arguments, true); // Value used.
1828 const String& name = 1816 const String& name =
1829 String::ZoneHandle(Field::SetterSymbol(node->field_name())); 1817 String::ZoneHandle(Field::SetterSymbol(node->field_name()));
1830 Do(new InstanceCallComp(node->token_pos(), 1818 Do(new InstanceCallComp(node->token_pos(),
1831 owner()->try_index(),
1832 name, 1819 name,
1833 Token::kSET, 1820 Token::kSET,
1834 arguments, 1821 arguments,
1835 Array::ZoneHandle(), 1822 Array::ZoneHandle(),
1836 1)); // Checked argument count. 1823 1)); // Checked argument count.
1837 ReturnComputation( 1824 ReturnComputation(
1838 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); 1825 BuildLoadLocal(*owner()->parsed_function().expression_temp_var()));
1839 } 1826 }
1840 1827
1841 1828
(...skipping 11 matching lines...) Expand all
1853 ASSERT(node->receiver() != NULL); 1840 ASSERT(node->receiver() != NULL);
1854 ValueGraphVisitor receiver_value(owner(), temp_index()); 1841 ValueGraphVisitor receiver_value(owner(), temp_index());
1855 node->receiver()->Visit(&receiver_value); 1842 node->receiver()->Visit(&receiver_value);
1856 Append(receiver_value); 1843 Append(receiver_value);
1857 arguments->Add(PushArgument(receiver_value.value())); 1844 arguments->Add(PushArgument(receiver_value.value()));
1858 } else { 1845 } else {
1859 getter_function = node->cls().LookupStaticFunction(getter_name); 1846 getter_function = node->cls().LookupStaticFunction(getter_name);
1860 ASSERT(!getter_function.IsNull()); 1847 ASSERT(!getter_function.IsNull());
1861 } 1848 }
1862 StaticCallComp* call = new StaticCallComp(node->token_pos(), 1849 StaticCallComp* call = new StaticCallComp(node->token_pos(),
1863 owner()->try_index(),
1864 getter_function, 1850 getter_function,
1865 Array::ZoneHandle(), // No names. 1851 Array::ZoneHandle(), // No names.
1866 arguments); 1852 arguments);
1867 ReturnComputation(call); 1853 ReturnComputation(call);
1868 } 1854 }
1869 1855
1870 1856
1871 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, 1857 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node,
1872 bool result_is_needed) { 1858 bool result_is_needed) {
1873 const String& setter_name = 1859 const String& setter_name =
(...skipping 24 matching lines...) Expand all
1898 if (result_is_needed) { 1884 if (result_is_needed) {
1899 value = Bind( 1885 value = Bind(
1900 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(), 1886 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(),
1901 for_value.value())); 1887 for_value.value()));
1902 } else { 1888 } else {
1903 value = for_value.value(); 1889 value = for_value.value();
1904 } 1890 }
1905 arguments->Add(PushArgument(value)); 1891 arguments->Add(PushArgument(value));
1906 1892
1907 StaticCallComp* call = new StaticCallComp(node->token_pos(), 1893 StaticCallComp* call = new StaticCallComp(node->token_pos(),
1908 owner()->try_index(),
1909 setter_function, 1894 setter_function,
1910 Array::ZoneHandle(), // No names. 1895 Array::ZoneHandle(), // No names.
1911 arguments); 1896 arguments);
1912 if (result_is_needed) { 1897 if (result_is_needed) {
1913 Do(call); 1898 Do(call);
1914 ReturnComputation( 1899 ReturnComputation(
1915 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); 1900 BuildLoadLocal(*owner()->parsed_function().expression_temp_var()));
1916 } else { 1901 } else {
1917 ReturnComputation(call); 1902 ReturnComputation(call);
1918 } 1903 }
1919 } 1904 }
1920 1905
1921 1906
1922 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { 1907 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) {
1923 BuildStaticSetter(node, false); // Result not needed. 1908 BuildStaticSetter(node, false); // Result not needed.
1924 } 1909 }
1925 1910
1926 1911
1927 void ValueGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { 1912 void ValueGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) {
1928 BuildStaticSetter(node, true); // Result needed. 1913 BuildStaticSetter(node, true); // Result needed.
1929 } 1914 }
1930 1915
1931 1916
1932 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { 1917 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
1933 NativeCallComp* native_call = 1918 NativeCallComp* native_call = new NativeCallComp(node);
1934 new NativeCallComp(node, owner()->try_index());
1935 ReturnComputation(native_call); 1919 ReturnComputation(native_call);
1936 } 1920 }
1937 1921
1938 1922
1939 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { 1923 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) {
1940 // PrimaryNodes are temporary during parsing. 1924 // PrimaryNodes are temporary during parsing.
1941 UNREACHABLE(); 1925 UNREACHABLE();
1942 } 1926 }
1943 1927
1944 1928
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2053 2037
2054 ValueGraphVisitor for_index(owner(), temp_index()); 2038 ValueGraphVisitor for_index(owner(), temp_index());
2055 node->index_expr()->Visit(&for_index); 2039 node->index_expr()->Visit(&for_index);
2056 Append(for_index); 2040 Append(for_index);
2057 arguments->Add(PushArgument(for_index.value())); 2041 arguments->Add(PushArgument(for_index.value()));
2058 2042
2059 const intptr_t checked_argument_count = 1; 2043 const intptr_t checked_argument_count = 1;
2060 const String& name = 2044 const String& name =
2061 String::ZoneHandle(Symbols::New(Token::Str(Token::kINDEX))); 2045 String::ZoneHandle(Symbols::New(Token::Str(Token::kINDEX)));
2062 InstanceCallComp* load = new InstanceCallComp(node->token_pos(), 2046 InstanceCallComp* load = new InstanceCallComp(node->token_pos(),
2063 owner()->try_index(),
2064 name, 2047 name,
2065 Token::kINDEX, 2048 Token::kINDEX,
2066 arguments, 2049 arguments,
2067 Array::ZoneHandle(), 2050 Array::ZoneHandle(),
2068 checked_argument_count); 2051 checked_argument_count);
2069 ReturnComputation(load); 2052 ReturnComputation(load);
2070 } 2053 }
2071 2054
2072 2055
2073 Computation* EffectGraphVisitor::BuildStoreIndexedValues( 2056 Computation* EffectGraphVisitor::BuildStoreIndexedValues(
(...skipping 21 matching lines...) Expand all
2095 for_value.value())); 2078 for_value.value()));
2096 } else { 2079 } else {
2097 value = for_value.value(); 2080 value = for_value.value();
2098 } 2081 }
2099 arguments->Add(PushArgument(value)); 2082 arguments->Add(PushArgument(value));
2100 2083
2101 const intptr_t checked_argument_count = 1; 2084 const intptr_t checked_argument_count = 1;
2102 const String& name = 2085 const String& name =
2103 String::ZoneHandle(Symbols::New(Token::Str(Token::kASSIGN_INDEX))); 2086 String::ZoneHandle(Symbols::New(Token::Str(Token::kASSIGN_INDEX)));
2104 InstanceCallComp* store = new InstanceCallComp(node->token_pos(), 2087 InstanceCallComp* store = new InstanceCallComp(node->token_pos(),
2105 owner()->try_index(),
2106 name, 2088 name,
2107 Token::kASSIGN_INDEX, 2089 Token::kASSIGN_INDEX,
2108 arguments, 2090 arguments,
2109 Array::ZoneHandle(), 2091 Array::ZoneHandle(),
2110 checked_argument_count); 2092 checked_argument_count);
2111 if (result_is_needed) { 2093 if (result_is_needed) {
2112 Do(store); 2094 Do(store);
2113 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var()); 2095 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var());
2114 } else { 2096 } else {
2115 return store; 2097 return store;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2151 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { 2133 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) {
2152 LocalScope* scope = node->scope(); 2134 LocalScope* scope = node->scope();
2153 const intptr_t num_context_variables = 2135 const intptr_t num_context_variables =
2154 (scope != NULL) ? scope->num_context_variables() : 0; 2136 (scope != NULL) ? scope->num_context_variables() : 0;
2155 int previous_context_level = owner()->context_level(); 2137 int previous_context_level = owner()->context_level();
2156 if (num_context_variables > 0) { 2138 if (num_context_variables > 0) {
2157 // The loop local scope declares variables that are captured. 2139 // The loop local scope declares variables that are captured.
2158 // Allocate and chain a new context. 2140 // Allocate and chain a new context.
2159 // Allocate context computation (uses current CTX) 2141 // Allocate context computation (uses current CTX)
2160 Value* allocated_context = 2142 Value* allocated_context =
2161 Bind(new AllocateContextComp(node->token_pos(), 2143 Bind(new AllocateContextComp(node->token_pos(), num_context_variables));
2162 owner()->try_index(),
2163 num_context_variables));
2164 2144
2165 // If this node_sequence is the body of the function being compiled, and if 2145 // If this node_sequence is the body of the function being compiled, and if
2166 // this function is not a closure, do not link the current context as the 2146 // this function is not a closure, do not link the current context as the
2167 // parent of the newly allocated context, as it is not accessible. Instead, 2147 // parent of the newly allocated context, as it is not accessible. Instead,
2168 // save it in a pre-allocated variable and restore it on exit. 2148 // save it in a pre-allocated variable and restore it on exit.
2169 if (MustSaveRestoreContext(node)) { 2149 if (MustSaveRestoreContext(node)) {
2170 Value* current_context = Bind(new CurrentContextComp()); 2150 Value* current_context = Bind(new CurrentContextComp());
2171 Do(BuildStoreLocal(*owner()->parsed_function().saved_context_var(), 2151 Do(BuildStoreLocal(*owner()->parsed_function().saved_context_var(),
2172 current_context)); 2152 current_context));
2173 Value* null_context = Bind(Constant(Object::ZoneHandle())); 2153 Value* null_context = Bind(Constant(Object::ZoneHandle()));
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
2301 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { 2281 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) {
2302 intptr_t old_try_index = owner()->try_index(); 2282 intptr_t old_try_index = owner()->try_index();
2303 intptr_t try_index = owner()->AllocateTryIndex(); 2283 intptr_t try_index = owner()->AllocateTryIndex();
2304 owner()->set_try_index(try_index); 2284 owner()->set_try_index(try_index);
2305 2285
2306 // Preserve CTX into local variable '%saved_context'. 2286 // Preserve CTX into local variable '%saved_context'.
2307 BuildStoreContext(node->context_var()); 2287 BuildStoreContext(node->context_var());
2308 2288
2309 EffectGraphVisitor for_try_block(owner(), temp_index()); 2289 EffectGraphVisitor for_try_block(owner(), temp_index());
2310 node->try_block()->Visit(&for_try_block); 2290 node->try_block()->Visit(&for_try_block);
2311 Append(for_try_block); 2291
2292 if (for_try_block.is_open()) {
2293 JoinEntryInstr* after_try = new JoinEntryInstr(old_try_index);
2294 for_try_block.Goto(after_try);
2295 for_try_block.exit_ = after_try;
2296 }
2297
2298 JoinEntryInstr* try_entry = new JoinEntryInstr(try_index);
2299
2300 Goto(try_entry);
2301 AppendFragment(try_entry, for_try_block);
2302 exit_ = for_try_block.exit_;
2312 2303
2313 // We are done generating code for the try block. 2304 // We are done generating code for the try block.
2314 owner()->set_try_index(old_try_index); 2305 owner()->set_try_index(old_try_index);
2315 2306
2316 CatchClauseNode* catch_block = node->catch_block(); 2307 CatchClauseNode* catch_block = node->catch_block();
2317 if (catch_block != NULL) { 2308 if (catch_block != NULL) {
2318 // Set the corresponding try index for this catch block so 2309 // Set the corresponding try index for this catch block so
2319 // that we can set the appropriate handler pc when we generate 2310 // that we can set the appropriate handler pc when we generate
2320 // code for this catch block. 2311 // code for this catch block.
2321 catch_block->set_try_index(try_index); 2312 catch_block->set_try_index(try_index);
2322 EffectGraphVisitor for_catch_block(owner(), temp_index()); 2313 EffectGraphVisitor for_catch_block(owner(), temp_index());
2323 catch_block->Visit(&for_catch_block); 2314 catch_block->Visit(&for_catch_block);
2324 TargetEntryInstr* catch_entry = new TargetEntryInstr(try_index); 2315 TargetEntryInstr* catch_entry = new TargetEntryInstr(old_try_index,
2316 try_index);
2325 owner()->AddCatchEntry(catch_entry); 2317 owner()->AddCatchEntry(catch_entry);
2326 ASSERT(!for_catch_block.is_open()); 2318 ASSERT(!for_catch_block.is_open());
2327 AppendFragment(catch_entry, for_catch_block); 2319 AppendFragment(catch_entry, for_catch_block);
2328 if (node->end_catch_label() != NULL) { 2320 if (node->end_catch_label() != NULL) {
2329 JoinEntryInstr* join = node->end_catch_label()->join_for_continue(); 2321 JoinEntryInstr* join = node->end_catch_label()->join_for_continue();
2330 if (join != NULL) { 2322 if (join != NULL) {
2331 if (is_open()) Goto(join); 2323 if (is_open()) Goto(join);
2332 exit_ = join; 2324 exit_ = join;
2333 } 2325 }
2334 } 2326 }
2335 } 2327 }
2336 2328
2337 // Generate code for the finally block if one exists. 2329 // Generate code for the finally block if one exists.
2338 if ((node->finally_block() != NULL) && is_open()) { 2330 if ((node->finally_block() != NULL) && is_open()) {
2339 EffectGraphVisitor for_finally_block(owner(), temp_index()); 2331 EffectGraphVisitor for_finally_block(owner(), temp_index());
2340 node->finally_block()->Visit(&for_finally_block); 2332 node->finally_block()->Visit(&for_finally_block);
2341 Append(for_finally_block); 2333 Append(for_finally_block);
2342 } 2334 }
2343 } 2335 }
2344 2336
2345 2337
2346 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { 2338 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) {
2347 ValueGraphVisitor for_exception(owner(), temp_index()); 2339 ValueGraphVisitor for_exception(owner(), temp_index());
2348 node->exception()->Visit(&for_exception); 2340 node->exception()->Visit(&for_exception);
2349 Append(for_exception); 2341 Append(for_exception);
2350 PushArgument(for_exception.value()); 2342 PushArgument(for_exception.value());
2351 Instruction* instr = NULL; 2343 Instruction* instr = NULL;
2352 if (node->stacktrace() == NULL) { 2344 if (node->stacktrace() == NULL) {
2353 instr = new ThrowInstr(node->token_pos(), owner()->try_index()); 2345 instr = new ThrowInstr(node->token_pos());
2354 } else { 2346 } else {
2355 ValueGraphVisitor for_stack_trace(owner(), temp_index()); 2347 ValueGraphVisitor for_stack_trace(owner(), temp_index());
2356 node->stacktrace()->Visit(&for_stack_trace); 2348 node->stacktrace()->Visit(&for_stack_trace);
2357 Append(for_stack_trace); 2349 Append(for_stack_trace);
2358 PushArgument(for_stack_trace.value()); 2350 PushArgument(for_stack_trace.value());
2359 instr = new ReThrowInstr(node->token_pos(), owner()->try_index()); 2351 instr = new ReThrowInstr(node->token_pos());
2360 } 2352 }
2361 AddInstruction(instr); 2353 AddInstruction(instr);
2362 } 2354 }
2363 2355
2364 2356
2365 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { 2357 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) {
2366 BuildThrowNode(node); 2358 BuildThrowNode(node);
2367 CloseFragment(); 2359 CloseFragment();
2368 } 2360 }
2369 2361
2370 2362
2371 // A throw cannot be part of an expression, however, the parser may replace 2363 // A throw cannot be part of an expression, however, the parser may replace
2372 // certain expression nodes with a throw. In that case generate a literal null 2364 // certain expression nodes with a throw. In that case generate a literal null
2373 // so that the fragment is not closed in the middle of an expression. 2365 // so that the fragment is not closed in the middle of an expression.
2374 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { 2366 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) {
2375 BuildThrowNode(node); 2367 BuildThrowNode(node);
2376 ReturnComputation(Constant(Instance::ZoneHandle())); 2368 ReturnComputation(Constant(Instance::ZoneHandle()));
2377 } 2369 }
2378 2370
2379 2371
2380 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { 2372 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) {
2381 const intptr_t try_index = owner()->try_index(); 2373 const intptr_t try_index = owner()->try_index();
2382 if (try_index >= 0) { 2374 if (try_index >= 0) {
2383 // We are about to generate code for an inlined finally block. Exceptions 2375 // We are about to generate code for an inlined finally block. Exceptions
2384 // thrown in this block of code should be treated as though they are 2376 // thrown in this block of code should be treated as though they are
2385 // thrown not from the current try block but the outer try block if any. 2377 // thrown not from the current try block but the outer try block if any.
2386 owner()->set_try_index((try_index - 1)); 2378 owner()->set_try_index((try_index - 1));
2387 } 2379 }
2388 BuildLoadContext(node->context_var()); 2380 BuildLoadContext(node->context_var());
2381
2382 JoinEntryInstr* finally_entry = new JoinEntryInstr(owner()->try_index());
2389 EffectGraphVisitor for_finally_block(owner(), temp_index()); 2383 EffectGraphVisitor for_finally_block(owner(), temp_index());
2390 node->finally_block()->Visit(&for_finally_block); 2384 node->finally_block()->Visit(&for_finally_block);
2391 Append(for_finally_block); 2385
2392 if (try_index >= 0) { 2386 if (try_index >= 0) {
2393 owner()->set_try_index(try_index); 2387 owner()->set_try_index(try_index);
2394 } 2388 }
2389
2390 if (for_finally_block.is_open()) {
2391 JoinEntryInstr* after_finally = new JoinEntryInstr(owner()->try_index());
2392 for_finally_block.Goto(after_finally);
2393 for_finally_block.exit_ = after_finally;
2394 }
2395
2396 Goto(finally_entry);
2397 AppendFragment(finally_entry, for_finally_block);
2398 exit_ = for_finally_block.exit_;
2395 } 2399 }
2396 2400
2397 2401
2398 FlowGraph* FlowGraphBuilder::BuildGraph() { 2402 FlowGraph* FlowGraphBuilder::BuildGraph() {
2399 if (FLAG_print_ast) { 2403 if (FLAG_print_ast) {
2400 // Print the function ast before IL generation. 2404 // Print the function ast before IL generation.
2401 AstPrinter::PrintFunctionNodes(parsed_function()); 2405 AstPrinter::PrintFunctionNodes(parsed_function());
2402 } 2406 }
2403 // Compilation can be nested, preserve the computation-id. 2407 // Compilation can be nested, preserve the computation-id.
2404 const Function& function = parsed_function().function(); 2408 const Function& function = parsed_function().function();
2405 TargetEntryInstr* normal_entry = new TargetEntryInstr(); 2409 TargetEntryInstr* normal_entry = new TargetEntryInstr(
2410 CatchClauseNode::kInvalidTryIndex);
2406 graph_entry_ = new GraphEntryInstr(normal_entry); 2411 graph_entry_ = new GraphEntryInstr(normal_entry);
2407 EffectGraphVisitor for_effect(this, 0); 2412 EffectGraphVisitor for_effect(this, 0);
2408 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the 2413 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the
2409 // stack check on entry for leaf routines). 2414 // stack check on entry for leaf routines).
2410 for_effect.Do(new CheckStackOverflowComp(function.token_pos(), 2415 for_effect.Do(new CheckStackOverflowComp(function.token_pos()));
2411 CatchClauseNode::kInvalidTryIndex));
2412 parsed_function().node_sequence()->Visit(&for_effect); 2416 parsed_function().node_sequence()->Visit(&for_effect);
2413 AppendFragment(normal_entry, for_effect); 2417 AppendFragment(normal_entry, for_effect);
2414 // Check that the graph is properly terminated. 2418 // Check that the graph is properly terminated.
2415 ASSERT(!for_effect.is_open()); 2419 ASSERT(!for_effect.is_open());
2416 return new FlowGraph(*this, graph_entry_); 2420 return new FlowGraph(*this, graph_entry_);
2417 } 2421 }
2418 2422
2419 2423
2420 void FlowGraphBuilder::Bailout(const char* reason) { 2424 void FlowGraphBuilder::Bailout(const char* reason) {
2421 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; 2425 const char* kFormat = "FlowGraphBuilder Bailout: %s %s";
2422 const char* function_name = parsed_function_.function().ToCString(); 2426 const char* function_name = parsed_function_.function().ToCString();
2423 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 2427 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
2424 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 2428 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
2425 OS::SNPrint(chars, len, kFormat, function_name, reason); 2429 OS::SNPrint(chars, len, kFormat, function_name, reason);
2426 const Error& error = Error::Handle( 2430 const Error& error = Error::Handle(
2427 LanguageError::New(String::Handle(String::New(chars)))); 2431 LanguageError::New(String::Handle(String::New(chars))));
2428 Isolate::Current()->long_jump_base()->Jump(1, error); 2432 Isolate::Current()->long_jump_base()->Jump(1, error);
2429 } 2433 }
2430 2434
2431 2435
2432 } // namespace dart 2436 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/flow_graph_compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698