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

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

Issue 10702092: Simplify adding of computations to the flow graph. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 5 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') | no next file » | 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/bit_vector.h" 8 #include "vm/bit_vector.h"
9 #include "vm/code_descriptors.h" 9 #include "vm/code_descriptors.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 entry_ = other_fragment.entry(); 55 entry_ = other_fragment.entry();
56 exit_ = other_fragment.exit(); 56 exit_ = other_fragment.exit();
57 } else { 57 } else {
58 exit()->set_successor(other_fragment.entry()); 58 exit()->set_successor(other_fragment.entry());
59 exit_ = other_fragment.exit(); 59 exit_ = other_fragment.exit();
60 } 60 }
61 temp_index_ = other_fragment.temp_index(); 61 temp_index_ = other_fragment.temp_index();
62 } 62 }
63 63
64 64
65 UseVal* EffectGraphVisitor::Bind(Computation* computation) {
66 ASSERT(is_open());
67 DeallocateTempIndex(computation->InputCount());
68 BindInstr* bind_instr = new BindInstr(computation);
69 bind_instr->set_temp_index(AllocateTempIndex());
70 if (is_empty()) {
71 entry_ = bind_instr;
72 } else {
73 exit()->set_successor(bind_instr);
74 }
75 exit_ = bind_instr;
76 return new UseVal(bind_instr);
77 }
78
79
80 void EffectGraphVisitor::Do(Computation* computation) {
81 ASSERT(is_open());
82 DeallocateTempIndex(computation->InputCount());
83 DoInstr* do_instr = new DoInstr(computation);
84 if (is_empty()) {
85 entry_ = do_instr;
86 } else {
87 exit()->set_successor(do_instr);
88 }
89 exit_ = do_instr;
90 }
91
92
65 void EffectGraphVisitor::AddInstruction(Instruction* instruction) { 93 void EffectGraphVisitor::AddInstruction(Instruction* instruction) {
66 ASSERT(is_open()); 94 ASSERT(is_open());
95 ASSERT(!instruction->IsDo());
96 ASSERT(!instruction->IsBind());
67 DeallocateTempIndex(instruction->InputCount()); 97 DeallocateTempIndex(instruction->InputCount());
68 if (instruction->IsDefinition()) { 98 if (instruction->IsDefinition()) {
69 instruction->AsDefinition()->set_temp_index(AllocateTempIndex()); 99 instruction->AsDefinition()->set_temp_index(AllocateTempIndex());
70 } 100 }
71 if (is_empty()) { 101 if (is_empty()) {
72 entry_ = exit_ = instruction; 102 entry_ = exit_ = instruction;
73 } else { 103 } else {
74 exit()->set_successor(instruction); 104 exit()->set_successor(instruction);
75 exit_ = instruction; 105 exit_ = instruction;
76 } 106 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 exit_ = *test_fragment.false_successor_address() = new TargetEntryInstr(); 186 exit_ = *test_fragment.false_successor_address() = new TargetEntryInstr();
157 } 187 }
158 188
159 189
160 Computation* EffectGraphVisitor::BuildStoreLocal( 190 Computation* EffectGraphVisitor::BuildStoreLocal(
161 const LocalVariable& local, Value* value) { 191 const LocalVariable& local, Value* value) {
162 if (local.is_captured()) { 192 if (local.is_captured()) {
163 intptr_t delta = owner()->context_level() - 193 intptr_t delta = owner()->context_level() -
164 local.owner()->context_level(); 194 local.owner()->context_level();
165 ASSERT(delta >= 0); 195 ASSERT(delta >= 0);
166 BindInstr* context = new BindInstr(new CurrentContextComp()); 196 Value* context = Bind(new CurrentContextComp());
167 AddInstruction(context);
168 Value* context_value = new UseVal(context);
169 while (delta-- > 0) { 197 while (delta-- > 0) {
170 BindInstr* load = new BindInstr(new LoadVMFieldComp( 198 context = Bind(new LoadVMFieldComp(
171 context_value, Context::parent_offset(), Type::ZoneHandle())); 199 context, Context::parent_offset(), Type::ZoneHandle()));
172 AddInstruction(load);
173 context_value = new UseVal(load);
174 } 200 }
175 return new StoreVMFieldComp( 201 return new StoreVMFieldComp(
176 context_value, 202 context,
177 Context::variable_offset(local.index()), 203 Context::variable_offset(local.index()),
178 value, 204 value,
179 local.type()); 205 local.type());
180 } else { 206 } else {
181 return new StoreLocalComp(local, value, owner()->context_level()); 207 return new StoreLocalComp(local, value, owner()->context_level());
182 } 208 }
183 } 209 }
184 210
185 211
186 Computation* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) { 212 Computation* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) {
187 if (local.is_captured()) { 213 if (local.is_captured()) {
188 intptr_t delta = owner()->context_level() - 214 intptr_t delta = owner()->context_level() -
189 local.owner()->context_level(); 215 local.owner()->context_level();
190 ASSERT(delta >= 0); 216 ASSERT(delta >= 0);
191 BindInstr* context = new BindInstr(new CurrentContextComp()); 217 Value* context = Bind(new CurrentContextComp());
192 AddInstruction(context);
193 Value* context_value = new UseVal(context);
194 while (delta-- > 0) { 218 while (delta-- > 0) {
195 BindInstr* load = new BindInstr(new LoadVMFieldComp( 219 context = Bind(new LoadVMFieldComp(
196 context_value, Context::parent_offset(), Type::ZoneHandle())); 220 context, Context::parent_offset(), Type::ZoneHandle()));
197 AddInstruction(load);
198 context_value = new UseVal(load);
199 } 221 }
200 return new LoadVMFieldComp(context_value, 222 return new LoadVMFieldComp(context,
201 Context::variable_offset(local.index()), 223 Context::variable_offset(local.index()),
202 local.type()); 224 local.type());
203 } else { 225 } else {
204 return new LoadLocalComp(local, owner()->context_level()); 226 return new LoadLocalComp(local, owner()->context_level());
205 } 227 }
206 } 228 }
207 229
208 230
209 // Stores current context into the 'variable' 231 // Stores current context into the 'variable'
210 void EffectGraphVisitor::BuildStoreContext(const LocalVariable& variable) { 232 void EffectGraphVisitor::BuildStoreContext(const LocalVariable& variable) {
211 BindInstr* context = new BindInstr(new CurrentContextComp()); 233 Value* context = Bind(new CurrentContextComp());
212 AddInstruction(context); 234 Do(BuildStoreLocal(variable, context));
213 Computation* store_context = BuildStoreLocal(variable, new UseVal(context));
214 AddInstruction(new DoInstr(store_context));
215 } 235 }
216 236
217 237
218 // Loads context saved in 'context_variable' into the current context. 238 // Loads context saved in 'context_variable' into the current context.
219 void EffectGraphVisitor::BuildLoadContext(const LocalVariable& variable) { 239 void EffectGraphVisitor::BuildLoadContext(const LocalVariable& variable) {
220 BindInstr* load_saved_context = new BindInstr(BuildLoadLocal(variable)); 240 Value* load_saved_context = Bind(BuildLoadLocal(variable));
221 AddInstruction(load_saved_context); 241 Do(new StoreContextComp(load_saved_context));
222 DoInstr* store_context =
223 new DoInstr(new StoreContextComp(new UseVal(load_saved_context)));
224 AddInstruction(store_context);
225 } 242 }
226 243
227 244
228 245
229 void TestGraphVisitor::ReturnValue(Value* value) { 246 void TestGraphVisitor::ReturnValue(Value* value) {
230 if (FLAG_enable_type_checks) { 247 if (FLAG_enable_type_checks) {
231 BindInstr* assert_boolean = 248 value = Bind(new AssertBooleanComp(condition_token_pos(),
232 new BindInstr(new AssertBooleanComp(condition_token_pos(), 249 owner()->try_index(),
233 owner()->try_index(), 250 value));
234 value));
235 AddInstruction(assert_boolean);
236 value = new UseVal(assert_boolean);
237 } 251 }
238 BranchInstr* branch = new BranchInstr(value); 252 BranchInstr* branch = new BranchInstr(value);
239 AddInstruction(branch); 253 AddInstruction(branch);
240 CloseFragment(); 254 CloseFragment();
241 true_successor_address_ = branch->true_successor_address(); 255 true_successor_address_ = branch->true_successor_address();
242 false_successor_address_ = branch->false_successor_address(); 256 false_successor_address_ = branch->false_successor_address();
243 } 257 }
244 258
245 259
246 void EffectGraphVisitor::Bailout(const char* reason) { 260 void EffectGraphVisitor::Bailout(const char* reason) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 ASSERT(current_context_level >= 0); 302 ASSERT(current_context_level >= 0);
289 if (owner()->parsed_function().saved_context_var() != NULL) { 303 if (owner()->parsed_function().saved_context_var() != NULL) {
290 // CTX on entry was saved, but not linked as context parent. 304 // CTX on entry was saved, but not linked as context parent.
291 BuildLoadContext(*owner()->parsed_function().saved_context_var()); 305 BuildLoadContext(*owner()->parsed_function().saved_context_var());
292 } else { 306 } else {
293 while (current_context_level-- > 0) { 307 while (current_context_level-- > 0) {
294 UnchainContext(); 308 UnchainContext();
295 } 309 }
296 } 310 }
297 311
298 AddInstruction( 312 AddInstruction(new ReturnInstr(node->token_pos(), return_value));
299 new ReturnInstr(node->token_pos(), return_value));
300 CloseFragment(); 313 CloseFragment();
301 } 314 }
302 315
303 316
304 // <Expression> ::= Literal { literal: Instance } 317 // <Expression> ::= Literal { literal: Instance }
305 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) { 318 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) {
306 return; 319 return;
307 } 320 }
308 321
309 void ValueGraphVisitor::VisitLiteralNode(LiteralNode* node) { 322 void ValueGraphVisitor::VisitLiteralNode(LiteralNode* node) {
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 478
466 TestGraphVisitor for_test(owner(), 479 TestGraphVisitor for_test(owner(),
467 temp_index(), 480 temp_index(),
468 node->left()->token_pos()); 481 node->left()->token_pos());
469 node->left()->Visit(&for_test); 482 node->left()->Visit(&for_test);
470 483
471 ValueGraphVisitor for_right(owner(), temp_index()); 484 ValueGraphVisitor for_right(owner(), temp_index());
472 node->right()->Visit(&for_right); 485 node->right()->Visit(&for_right);
473 Value* right_value = for_right.value(); 486 Value* right_value = for_right.value();
474 if (FLAG_enable_type_checks) { 487 if (FLAG_enable_type_checks) {
475 BindInstr* assert_boolean = 488 right_value =
476 new BindInstr(new AssertBooleanComp(node->right()->token_pos(), 489 for_right.Bind(new AssertBooleanComp(node->right()->token_pos(),
477 owner()->try_index(), 490 owner()->try_index(),
478 right_value)); 491 right_value));
479 for_right.AddInstruction(assert_boolean);
480 right_value = new UseVal(assert_boolean);
481 } 492 }
482 BindInstr* constant_true = new BindInstr(new ConstantVal(bool_true)); 493 Value* constant_true = for_right.Bind(new ConstantVal(bool_true));
483 for_right.AddInstruction(constant_true); 494 Value* compare =
484 BindInstr* comp = 495 for_right.Bind(new StrictCompareComp(Token::kEQ_STRICT,
485 new BindInstr(new StrictCompareComp(Token::kEQ_STRICT, 496 right_value,
486 right_value, 497 constant_true));
487 new UseVal(constant_true))); 498 for_right.Do(BuildStoreLocal(
488 for_right.AddInstruction(comp); 499 *owner()->parsed_function().expression_temp_var(),
489 for_right.AddInstruction( 500 compare));
490 new DoInstr(BuildStoreLocal(
491 *owner()->parsed_function().expression_temp_var(),
492 new UseVal(comp))));
493 501
494 if (node->kind() == Token::kAND) { 502 if (node->kind() == Token::kAND) {
495 ValueGraphVisitor for_false(owner(), temp_index()); 503 ValueGraphVisitor for_false(owner(), temp_index());
496 BindInstr* constant_false = new BindInstr(new ConstantVal(bool_false)); 504 Value* constant_false = for_false.Bind(new ConstantVal(bool_false));
497 for_false.AddInstruction(constant_false); 505 for_false.Do(BuildStoreLocal(
498 for_false.AddInstruction( 506 *owner()->parsed_function().expression_temp_var(),
499 new DoInstr(BuildStoreLocal( 507 constant_false));
500 *owner()->parsed_function().expression_temp_var(),
501 new UseVal(constant_false))));
502 Join(for_test, for_right, for_false); 508 Join(for_test, for_right, for_false);
503 } else { 509 } else {
504 ASSERT(node->kind() == Token::kOR); 510 ASSERT(node->kind() == Token::kOR);
505 ValueGraphVisitor for_true(owner(), temp_index()); 511 ValueGraphVisitor for_true(owner(), temp_index());
506 BindInstr* constant_true = new BindInstr(new ConstantVal(bool_true)); 512 Value* constant_true = for_true.Bind(new ConstantVal(bool_true));
507 for_true.AddInstruction(constant_true); 513 for_true.Do(BuildStoreLocal(
508 for_true.AddInstruction( 514 *owner()->parsed_function().expression_temp_var(),
509 new DoInstr(BuildStoreLocal( 515 constant_true));
510 *owner()->parsed_function().expression_temp_var(),
511 new UseVal(constant_true))));
512 Join(for_test, for_true, for_right); 516 Join(for_test, for_true, for_right);
513 } 517 }
514 ReturnComputation( 518 ReturnComputation(
515 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); 519 BuildLoadLocal(*owner()->parsed_function().expression_temp_var()));
516 return; 520 return;
517 } 521 }
518 EffectGraphVisitor::VisitBinaryOpNode(node); 522 EffectGraphVisitor::VisitBinaryOpNode(node);
519 } 523 }
520 524
521 525
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 instantiator = BuildInstantiator(); 613 instantiator = BuildInstantiator();
610 if (instantiator == NULL) { 614 if (instantiator == NULL) {
611 // No instantiator when inside factory. 615 // No instantiator when inside factory.
612 instantiator = BuildNullValue(); 616 instantiator = BuildNullValue();
613 instantiator_type_arguments = 617 instantiator_type_arguments =
614 BuildInstantiatorTypeArguments(token_pos, NULL); 618 BuildInstantiatorTypeArguments(token_pos, NULL);
615 } else { 619 } else {
616 // Preserve instantiator. 620 // Preserve instantiator.
617 const LocalVariable& expr_temp = 621 const LocalVariable& expr_temp =
618 *owner()->parsed_function().expression_temp_var(); 622 *owner()->parsed_function().expression_temp_var();
619 BindInstr* saved = 623 instantiator = Bind(BuildStoreLocal(expr_temp, instantiator));
620 new BindInstr(BuildStoreLocal(expr_temp, instantiator)); 624 Value* loaded = Bind(BuildLoadLocal(expr_temp));
621 AddInstruction(saved);
622 instantiator = new UseVal(saved);
623 BindInstr* loaded = new BindInstr(BuildLoadLocal(expr_temp));
624 AddInstruction(loaded);
625 instantiator_type_arguments = 625 instantiator_type_arguments =
626 BuildInstantiatorTypeArguments(token_pos, new UseVal(loaded)); 626 BuildInstantiatorTypeArguments(token_pos, loaded);
627 } 627 }
628 *instantiator_result = instantiator; 628 *instantiator_result = instantiator;
629 *instantiator_type_arguments_result = instantiator_type_arguments; 629 *instantiator_type_arguments_result = instantiator_type_arguments;
630 } 630 }
631 631
632 632
633 Value* EffectGraphVisitor::BuildNullValue() { 633 Value* EffectGraphVisitor::BuildNullValue() {
634 BindInstr* instr = new BindInstr(new ConstantVal(Object::ZoneHandle())); 634 return Bind(new ConstantVal(Object::ZoneHandle()));
635 AddInstruction(instr);
636 return new UseVal(instr);
637 } 635 }
638 636
639 637
640 // Used for testing incoming arguments. 638 // Used for testing incoming arguments.
641 AssertAssignableComp* EffectGraphVisitor::BuildAssertAssignable( 639 AssertAssignableComp* EffectGraphVisitor::BuildAssertAssignable(
642 intptr_t token_pos, 640 intptr_t token_pos,
643 Value* value, 641 Value* value,
644 const AbstractType& dst_type, 642 const AbstractType& dst_type,
645 const String& dst_name) { 643 const String& dst_name) {
646 // Build the type check computation. 644 // Build the type check computation.
(...skipping 18 matching lines...) Expand all
665 663
666 664
667 // Used for type casts and to test assignments. 665 // Used for type casts and to test assignments.
668 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos, 666 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos,
669 Value* value, 667 Value* value,
670 const AbstractType& dst_type, 668 const AbstractType& dst_type,
671 const String& dst_name) { 669 const String& dst_name) {
672 if (CanSkipTypeCheck(value, dst_type)) { 670 if (CanSkipTypeCheck(value, dst_type)) {
673 return value; 671 return value;
674 } 672 }
675 AssertAssignableComp* comp = BuildAssertAssignable(token_pos, 673 return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name));
676 value,
677 dst_type,
678 dst_name);
679 BindInstr* assert_assignable = new BindInstr(comp);
680 AddInstruction(assert_assignable);
681 return new UseVal(assert_assignable);
682 } 674 }
683 675
684 676
685 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { 677 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) {
686 ASSERT(Token::IsTypeTestOperator(node->kind())); 678 ASSERT(Token::IsTypeTestOperator(node->kind()));
687 EffectGraphVisitor for_left_value(owner(), temp_index()); 679 EffectGraphVisitor for_left_value(owner(), temp_index());
688 node->left()->Visit(&for_left_value); 680 node->left()->Visit(&for_left_value);
689 Append(for_left_value); 681 Append(for_left_value);
690 } 682 }
691 683
692 684
693 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { 685 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) {
694 ASSERT(Token::IsTypeCastOperator(node->kind())); 686 ASSERT(Token::IsTypeCastOperator(node->kind()));
695 const AbstractType& type = node->right()->AsTypeNode()->type(); 687 const AbstractType& type = node->right()->AsTypeNode()->type();
696 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. 688 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed.
697 ValueGraphVisitor for_value(owner(), temp_index()); 689 ValueGraphVisitor for_value(owner(), temp_index());
698 node->left()->Visit(&for_value); 690 node->left()->Visit(&for_value);
699 Append(for_value); 691 Append(for_value);
700 const String& dst_name = String::ZoneHandle( 692 const String& dst_name = String::ZoneHandle(
701 String::NewSymbol(Exceptions::kCastExceptionDstName)); 693 String::NewSymbol(Exceptions::kCastExceptionDstName));
702 if (!CanSkipTypeCheck(for_value.value(), type)) { 694 if (!CanSkipTypeCheck(for_value.value(), type)) {
703 AssertAssignableComp* assert_assignable = 695 Do(BuildAssertAssignable(
704 BuildAssertAssignable(node->token_pos(), 696 node->token_pos(), for_value.value(), type, dst_name));
705 for_value.value(),
706 type,
707 dst_name);
708 AddInstruction(new DoInstr(assert_assignable));
709 } 697 }
710 } 698 }
711 699
712 700
713 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { 701 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) {
714 ASSERT(Token::IsTypeTestOperator(node->kind())); 702 ASSERT(Token::IsTypeTestOperator(node->kind()));
715 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 703 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
716 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 704 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
717 const AbstractType& type = node->right()->AsTypeNode()->type(); 705 const AbstractType& type = node->right()->AsTypeNode()->type();
718 ASSERT(type.IsFinalized() && !type.IsMalformed()); 706 ASSERT(type.IsFinalized() && !type.IsMalformed());
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 Append(for_left_value); 820 Append(for_left_value);
833 ValueGraphVisitor for_right_value(owner(), temp_index()); 821 ValueGraphVisitor for_right_value(owner(), temp_index());
834 node->right()->Visit(&for_right_value); 822 node->right()->Visit(&for_right_value);
835 Append(for_right_value); 823 Append(for_right_value);
836 EqualityCompareComp* comp = new EqualityCompareComp( 824 EqualityCompareComp* comp = new EqualityCompareComp(
837 node->token_pos(), owner()->try_index(), 825 node->token_pos(), owner()->try_index(),
838 for_left_value.value(), for_right_value.value()); 826 for_left_value.value(), for_right_value.value());
839 if (node->kind() == Token::kEQ) { 827 if (node->kind() == Token::kEQ) {
840 ReturnComputation(comp); 828 ReturnComputation(comp);
841 } else { 829 } else {
842 BindInstr* eq_result = new BindInstr(comp); 830 Value* eq_result = Bind(comp);
843 AddInstruction(eq_result);
844 if (FLAG_enable_type_checks) { 831 if (FLAG_enable_type_checks) {
845 eq_result = 832 eq_result =
846 new BindInstr(new AssertBooleanComp(node->token_pos(), 833 Bind(new AssertBooleanComp(node->token_pos(),
847 owner()->try_index(), 834 owner()->try_index(),
848 new UseVal(eq_result))); 835 eq_result));
849 AddInstruction(eq_result);
850 } 836 }
851 BooleanNegateComp* negate = new BooleanNegateComp(new UseVal(eq_result)); 837 ReturnComputation(new BooleanNegateComp(eq_result));
852 ReturnComputation(negate);
853 } 838 }
854 return; 839 return;
855 } 840 }
856 841
857 ValueGraphVisitor for_left_value(owner(), temp_index()); 842 ValueGraphVisitor for_left_value(owner(), temp_index());
858 node->left()->Visit(&for_left_value); 843 node->left()->Visit(&for_left_value);
859 Append(for_left_value); 844 Append(for_left_value);
860 ValueGraphVisitor for_right_value(owner(), temp_index()); 845 ValueGraphVisitor for_right_value(owner(), temp_index());
861 node->right()->Visit(&for_right_value); 846 node->right()->Visit(&for_right_value);
862 Append(for_right_value); 847 Append(for_right_value);
863 RelationalOpComp* comp = new RelationalOpComp(node->token_pos(), 848 RelationalOpComp* comp = new RelationalOpComp(node->token_pos(),
864 owner()->try_index(), 849 owner()->try_index(),
865 node->kind(), 850 node->kind(),
866 for_left_value.value(), 851 for_left_value.value(),
867 for_right_value.value()); 852 for_right_value.value());
868 ReturnComputation(comp); 853 ReturnComputation(comp);
869 } 854 }
870 855
871 856
872 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { 857 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
873 // "!" cannot be overloaded, therefore do not call operator. 858 // "!" cannot be overloaded, therefore do not call operator.
874 if (node->kind() == Token::kNOT) { 859 if (node->kind() == Token::kNOT) {
875 ValueGraphVisitor for_value(owner(), temp_index()); 860 ValueGraphVisitor for_value(owner(), temp_index());
876 node->operand()->Visit(&for_value); 861 node->operand()->Visit(&for_value);
877 Append(for_value); 862 Append(for_value);
878 Value* value = for_value.value(); 863 Value* value = for_value.value();
879 if (FLAG_enable_type_checks) { 864 if (FLAG_enable_type_checks) {
880 BindInstr* assert_boolean = 865 value =
881 new BindInstr(new AssertBooleanComp(node->operand()->token_pos(), 866 Bind(new AssertBooleanComp(node->operand()->token_pos(),
882 owner()->try_index(), 867 owner()->try_index(),
883 value)); 868 value));
884 AddInstruction(assert_boolean);
885 value = new UseVal(assert_boolean);
886 } 869 }
887 BooleanNegateComp* negate = new BooleanNegateComp(value); 870 BooleanNegateComp* negate = new BooleanNegateComp(value);
888 ReturnComputation(negate); 871 ReturnComputation(negate);
889 return; 872 return;
890 } 873 }
891 ValueGraphVisitor for_value(owner(), temp_index()); 874 ValueGraphVisitor for_value(owner(), temp_index());
892 node->operand()->Visit(&for_value); 875 node->operand()->Visit(&for_value);
893 Append(for_value); 876 Append(for_value);
894 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); 877 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1);
895 arguments->Add(for_value.value()); 878 arguments->Add(for_value.value());
(...skipping 27 matching lines...) Expand all
923 906
924 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { 907 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
925 TestGraphVisitor for_test(owner(), 908 TestGraphVisitor for_test(owner(),
926 temp_index(), 909 temp_index(),
927 node->condition()->token_pos()); 910 node->condition()->token_pos());
928 node->condition()->Visit(&for_test); 911 node->condition()->Visit(&for_test);
929 912
930 ValueGraphVisitor for_true(owner(), temp_index()); 913 ValueGraphVisitor for_true(owner(), temp_index());
931 node->true_expr()->Visit(&for_true); 914 node->true_expr()->Visit(&for_true);
932 ASSERT(for_true.is_open()); 915 ASSERT(for_true.is_open());
933 for_true.AddInstruction(new DoInstr(BuildStoreLocal( 916 for_true.Do(BuildStoreLocal(
934 *owner()->parsed_function().expression_temp_var(), for_true.value()))); 917 *owner()->parsed_function().expression_temp_var(), for_true.value()));
935 918
936 ValueGraphVisitor for_false(owner(), temp_index()); 919 ValueGraphVisitor for_false(owner(), temp_index());
937 node->false_expr()->Visit(&for_false); 920 node->false_expr()->Visit(&for_false);
938 ASSERT(for_false.is_open()); 921 ASSERT(for_false.is_open());
939 for_false.AddInstruction(new DoInstr(BuildStoreLocal( 922 for_false.Do(BuildStoreLocal(
940 *owner()->parsed_function().expression_temp_var(), for_false.value()))); 923 *owner()->parsed_function().expression_temp_var(), for_false.value()));
941 924
942 Join(for_test, for_true, for_false); 925 Join(for_test, for_true, for_false);
943 ReturnComputation( 926 ReturnComputation(
944 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); 927 BuildLoadLocal(*owner()->parsed_function().expression_temp_var()));
945 } 928 }
946 929
947 930
948 // <Statement> ::= If { condition: <Expression> 931 // <Statement> ::= If { condition: <Expression>
949 // true_branch: <Sequence> 932 // true_branch: <Sequence>
950 // false_branch: <Sequence> } 933 // false_branch: <Sequence> }
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
1121 // f) loop-exit-target 1104 // f) loop-exit-target
1122 // g) break-join (optional) 1105 // g) break-join (optional)
1123 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { 1106 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) {
1124 TestGraphVisitor for_test(owner(), 1107 TestGraphVisitor for_test(owner(),
1125 temp_index(), 1108 temp_index(),
1126 node->condition()->token_pos()); 1109 node->condition()->token_pos());
1127 node->condition()->Visit(&for_test); 1110 node->condition()->Visit(&for_test);
1128 ASSERT(!for_test.is_empty()); // Language spec. 1111 ASSERT(!for_test.is_empty()); // Language spec.
1129 1112
1130 EffectGraphVisitor for_body(owner(), temp_index()); 1113 EffectGraphVisitor for_body(owner(), temp_index());
1131 CheckStackOverflowComp* comp = 1114 for_body.Do(
1132 new CheckStackOverflowComp(node->token_pos(), owner()->try_index()); 1115 new CheckStackOverflowComp(node->token_pos(), owner()->try_index()));
1133 for_body.AddInstruction(new DoInstr(comp));
1134 node->body()->Visit(&for_body); 1116 node->body()->Visit(&for_body);
1135 1117
1136 // Labels are set after body traversal. 1118 // Labels are set after body traversal.
1137 SourceLabel* lbl = node->label(); 1119 SourceLabel* lbl = node->label();
1138 ASSERT(lbl != NULL); 1120 ASSERT(lbl != NULL);
1139 if (lbl->join_for_continue() != NULL) { 1121 if (lbl->join_for_continue() != NULL) {
1140 AddInstruction(lbl->join_for_continue()); 1122 AddInstruction(lbl->join_for_continue());
1141 } 1123 }
1142 TieLoop(for_test, for_body); 1124 TieLoop(for_test, for_body);
1143 if (lbl->join_for_break() != NULL) { 1125 if (lbl->join_for_break() != NULL) {
1144 AddInstruction(lbl->join_for_break()); 1126 AddInstruction(lbl->join_for_break());
1145 } 1127 }
1146 } 1128 }
1147 1129
1148 1130
1149 // The fragment is composed as follows: 1131 // The fragment is composed as follows:
1150 // a) body-entry-join 1132 // a) body-entry-join
1151 // b) [ body ] 1133 // b) [ body ]
1152 // c) test-entry (continue-join or body-exit-target) 1134 // c) test-entry (continue-join or body-exit-target)
1153 // d) [ test-entry ] -> (back-target, loop-exit-target) 1135 // d) [ test-entry ] -> (back-target, loop-exit-target)
1154 // e) back-target -> (body-entry-join) 1136 // e) back-target -> (body-entry-join)
1155 // f) loop-exit-target 1137 // f) loop-exit-target
1156 // g) break-join 1138 // g) break-join
1157 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { 1139 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) {
1158 // Traverse body first in order to generate continue and break labels. 1140 // Traverse body first in order to generate continue and break labels.
1159 EffectGraphVisitor for_body(owner(), temp_index()); 1141 EffectGraphVisitor for_body(owner(), temp_index());
1160 CheckStackOverflowComp* comp = 1142 for_body.Do(
1161 new CheckStackOverflowComp(node->token_pos(), owner()->try_index()); 1143 new CheckStackOverflowComp(node->token_pos(), owner()->try_index()));
1162 for_body.AddInstruction(new DoInstr(comp));
1163 node->body()->Visit(&for_body); 1144 node->body()->Visit(&for_body);
1164 1145
1165 TestGraphVisitor for_test(owner(), 1146 TestGraphVisitor for_test(owner(),
1166 temp_index(), 1147 temp_index(),
1167 node->condition()->token_pos()); 1148 node->condition()->token_pos());
1168 node->condition()->Visit(&for_test); 1149 node->condition()->Visit(&for_test);
1169 ASSERT(is_open()); 1150 ASSERT(is_open());
1170 1151
1171 // Tie do-while loop (test is after the body). 1152 // Tie do-while loop (test is after the body).
1172 JoinEntryInstr* body_entry_join = new JoinEntryInstr(); 1153 JoinEntryInstr* body_entry_join = new JoinEntryInstr();
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1215 void EffectGraphVisitor::VisitForNode(ForNode* node) { 1196 void EffectGraphVisitor::VisitForNode(ForNode* node) {
1216 EffectGraphVisitor for_initializer(owner(), temp_index()); 1197 EffectGraphVisitor for_initializer(owner(), temp_index());
1217 node->initializer()->Visit(&for_initializer); 1198 node->initializer()->Visit(&for_initializer);
1218 Append(for_initializer); 1199 Append(for_initializer);
1219 ASSERT(is_open()); 1200 ASSERT(is_open());
1220 1201
1221 // Compose body to set any jump labels. 1202 // Compose body to set any jump labels.
1222 EffectGraphVisitor for_body(owner(), temp_index()); 1203 EffectGraphVisitor for_body(owner(), temp_index());
1223 TargetEntryInstr* body_entry = new TargetEntryInstr(); 1204 TargetEntryInstr* body_entry = new TargetEntryInstr();
1224 for_body.AddInstruction(body_entry); 1205 for_body.AddInstruction(body_entry);
1225 CheckStackOverflowComp* comp = 1206 for_body.Do(
1226 new CheckStackOverflowComp(node->token_pos(), owner()->try_index()); 1207 new CheckStackOverflowComp(node->token_pos(), owner()->try_index()));
1227 for_body.AddInstruction(new DoInstr(comp));
1228 node->body()->Visit(&for_body); 1208 node->body()->Visit(&for_body);
1229 1209
1230 // Join loop body, increment and compute their end instruction. 1210 // Join loop body, increment and compute their end instruction.
1231 ASSERT(!for_body.is_empty()); 1211 ASSERT(!for_body.is_empty());
1232 Instruction* loop_increment_end = NULL; 1212 Instruction* loop_increment_end = NULL;
1233 EffectGraphVisitor for_increment(owner(), temp_index()); 1213 EffectGraphVisitor for_increment(owner(), temp_index());
1234 if ((node->label()->join_for_continue() == NULL) && for_body.is_open()) { 1214 if ((node->label()->join_for_continue() == NULL) && for_body.is_open()) {
1235 // Do not insert an extra basic block. 1215 // Do not insert an extra basic block.
1236 node->increment()->Visit(&for_increment); 1216 node->increment()->Visit(&for_increment);
1237 for_body.Append(for_increment); 1217 for_body.Append(for_increment);
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1349 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { 1329 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) {
1350 // Translate the array elements and collect their values. 1330 // Translate the array elements and collect their values.
1351 ZoneGrowableArray<Value*>* values = 1331 ZoneGrowableArray<Value*>* values =
1352 new ZoneGrowableArray<Value*>(node->length()); 1332 new ZoneGrowableArray<Value*>(node->length());
1353 for (int i = 0; i < node->length(); ++i) { 1333 for (int i = 0; i < node->length(); ++i) {
1354 ValueGraphVisitor for_value(owner(), temp_index()); 1334 ValueGraphVisitor for_value(owner(), temp_index());
1355 node->ElementAt(i)->Visit(&for_value); 1335 node->ElementAt(i)->Visit(&for_value);
1356 Append(for_value); 1336 Append(for_value);
1357 values->Add(for_value.value()); 1337 values->Add(for_value.value());
1358 } 1338 }
1359 Value* element_type = new UseVal( 1339 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(),
1360 BuildInstantiatedTypeArguments(node->token_pos(), 1340 node->type_arguments());
1361 node->type_arguments()));
1362 CreateArrayComp* create = new CreateArrayComp(node->token_pos(), 1341 CreateArrayComp* create = new CreateArrayComp(node->token_pos(),
1363 owner()->try_index(), 1342 owner()->try_index(),
1364 values, 1343 values,
1365 element_type); 1344 element_type);
1366 ReturnComputation(create); 1345 ReturnComputation(create);
1367 } 1346 }
1368 1347
1369 1348
1370 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { 1349 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) {
1371 const Function& function = node->function(); 1350 const Function& function = node->function();
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1468 arguments->Add(for_closure.value()); 1447 arguments->Add(for_closure.value());
1469 TranslateArgumentList(*node->arguments(), arguments); 1448 TranslateArgumentList(*node->arguments(), arguments);
1470 1449
1471 // Save context around the call. 1450 // Save context around the call.
1472 BuildStoreContext(*owner()->parsed_function().expression_temp_var()); 1451 BuildStoreContext(*owner()->parsed_function().expression_temp_var());
1473 return new ClosureCallComp(node, owner()->try_index(), arguments); 1452 return new ClosureCallComp(node, owner()->try_index(), arguments);
1474 } 1453 }
1475 1454
1476 1455
1477 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { 1456 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
1478 ClosureCallComp* call = BuildClosureCall(node); 1457 Do(BuildClosureCall(node));
1479 AddInstruction(new DoInstr(call));
1480
1481 // Restore context from saved location. 1458 // Restore context from saved location.
1482 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); 1459 BuildLoadContext(*owner()->parsed_function().expression_temp_var());
1483 } 1460 }
1484 1461
1485 1462
1486 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { 1463 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
1487 ClosureCallComp* call = BuildClosureCall(node); 1464 Value* result = Bind(BuildClosureCall(node));
1488 BindInstr* result = new BindInstr(call);
1489 AddInstruction(result);
1490
1491 // Restore context from temp. 1465 // Restore context from temp.
1492 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); 1466 BuildLoadContext(*owner()->parsed_function().expression_temp_var());
1493 1467 ReturnValue(result);
1494 ReturnValue(new UseVal(result));
1495 } 1468 }
1496 1469
1497 1470
1498 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { 1471 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
1499 BindInstr* context = new BindInstr(new CurrentContextComp()); 1472 Value* context = Bind(new CurrentContextComp());
1500 AddInstruction(context); 1473 Value* clone = Bind(new CloneContextComp(node->token_pos(),
1501 BindInstr* clone = 1474 owner()->try_index(),
1502 new BindInstr(new CloneContextComp(node->token_pos(), 1475 context));
1503 owner()->try_index(), 1476 ReturnComputation(new StoreContextComp(clone));
1504 new UseVal(context)));
1505 AddInstruction(clone);
1506 ReturnComputation(new StoreContextComp(new UseVal(clone)));
1507 } 1477 }
1508 1478
1509 1479
1510 BindInstr* EffectGraphVisitor::BuildObjectAllocation( 1480 Value* EffectGraphVisitor::BuildObjectAllocation(
1511 ConstructorCallNode* node) { 1481 ConstructorCallNode* node) {
1512 const Class& cls = Class::ZoneHandle(node->constructor().owner()); 1482 const Class& cls = Class::ZoneHandle(node->constructor().owner());
1513 const bool requires_type_arguments = cls.HasTypeArguments(); 1483 const bool requires_type_arguments = cls.HasTypeArguments();
1514 1484
1515 ZoneGrowableArray<Value*>* allocate_arguments = 1485 ZoneGrowableArray<Value*>* allocate_arguments =
1516 new ZoneGrowableArray<Value*>(); 1486 new ZoneGrowableArray<Value*>();
1517 if (requires_type_arguments) { 1487 if (requires_type_arguments) {
1518 BuildConstructorTypeArguments(node, allocate_arguments); 1488 BuildConstructorTypeArguments(node, allocate_arguments);
1519 } 1489 }
1520 // In checked mode, if the type arguments are uninstantiated, they may need to 1490 // In checked mode, if the type arguments are uninstantiated, they may need to
(...skipping 13 matching lines...) Expand all
1534 // may represent the identity vector and may be replaced by the instantiated 1504 // may represent the identity vector and may be replaced by the instantiated
1535 // type arguments of the instantiator at run time. 1505 // type arguments of the instantiator at run time.
1536 allocate_comp = new AllocateObjectWithBoundsCheckComp(node, 1506 allocate_comp = new AllocateObjectWithBoundsCheckComp(node,
1537 owner()->try_index(), 1507 owner()->try_index(),
1538 allocate_arguments); 1508 allocate_arguments);
1539 } else { 1509 } else {
1540 allocate_comp = new AllocateObjectComp(node, 1510 allocate_comp = new AllocateObjectComp(node,
1541 owner()->try_index(), 1511 owner()->try_index(),
1542 allocate_arguments); 1512 allocate_arguments);
1543 } 1513 }
1544 BindInstr* allocate = new BindInstr(allocate_comp); 1514 return Bind(allocate_comp);
1545 AddInstruction(allocate);
1546 return allocate;
1547 } 1515 }
1548 1516
1549 1517
1550 void EffectGraphVisitor::BuildConstructorCall(ConstructorCallNode* node, 1518 void EffectGraphVisitor::BuildConstructorCall(ConstructorCallNode* node,
1551 Value* alloc_value) { 1519 Value* alloc_value) {
1552 BindInstr* ctor_arg = 1520 Value* ctor_arg = Bind(
1553 new BindInstr(new ConstantVal( 1521 new ConstantVal(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))));
1554 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))));
1555 AddInstruction(ctor_arg);
1556 1522
1557 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(); 1523 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>();
1558 values->Add(alloc_value); 1524 values->Add(alloc_value);
1559 values->Add(new UseVal(ctor_arg)); 1525 values->Add(ctor_arg);
1560 1526
1561 TranslateArgumentList(*node->arguments(), values); 1527 TranslateArgumentList(*node->arguments(), values);
1562 StaticCallComp* call = 1528 Do(new StaticCallComp(node->token_pos(),
1563 new StaticCallComp(node->token_pos(), 1529 owner()->try_index(),
1564 owner()->try_index(), 1530 node->constructor(),
1565 node->constructor(), 1531 node->arguments()->names(),
1566 node->arguments()->names(), 1532 values));
1567 values);
1568 AddInstruction(new DoInstr(call));
1569 } 1533 }
1570 1534
1571 1535
1572 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { 1536 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
1573 if (node->constructor().IsFactory()) { 1537 if (node->constructor().IsFactory()) {
1574 ZoneGrowableArray<Value*>* factory_arguments = 1538 ZoneGrowableArray<Value*>* factory_arguments =
1575 new ZoneGrowableArray<Value*>(); 1539 new ZoneGrowableArray<Value*>();
1576 factory_arguments->Add( 1540 factory_arguments->Add(
1577 new UseVal(BuildInstantiatedTypeArguments(node->token_pos(), 1541 BuildInstantiatedTypeArguments(node->token_pos(),
1578 node->type_arguments()))); 1542 node->type_arguments()));
1579 ASSERT(factory_arguments->length() == 1); 1543 ASSERT(factory_arguments->length() == 1);
1580 TranslateArgumentList(*node->arguments(), factory_arguments); 1544 TranslateArgumentList(*node->arguments(), factory_arguments);
1581 StaticCallComp* call = 1545 StaticCallComp* call =
1582 new StaticCallComp(node->token_pos(), 1546 new StaticCallComp(node->token_pos(),
1583 owner()->try_index(), 1547 owner()->try_index(),
1584 node->constructor(), 1548 node->constructor(),
1585 node->arguments()->names(), 1549 node->arguments()->names(),
1586 factory_arguments); 1550 factory_arguments);
1587 ReturnComputation(call); 1551 ReturnComputation(call);
1588 return; 1552 return;
1589 } 1553 }
1590 // t_n contains the allocated and initialized object. 1554 // t_n contains the allocated and initialized object.
1591 // t_n <- AllocateObject(class) 1555 // t_n <- AllocateObject(class)
1592 // t_n+1 <- ctor-arg 1556 // t_n+1 <- ctor-arg
1593 // t_n+2... <- constructor arguments start here 1557 // t_n+2... <- constructor arguments start here
1594 // StaticCall(constructor, t_n+1, t_n+2, ...) 1558 // StaticCall(constructor, t_n+1, t_n+2, ...)
1595 // No need to preserve allocated value (simpler than in ValueGraphVisitor). 1559 // No need to preserve allocated value (simpler than in ValueGraphVisitor).
1596 BindInstr* allocate = BuildObjectAllocation(node); 1560 Value* allocate = BuildObjectAllocation(node);
1597 BuildConstructorCall(node, new UseVal(allocate)); 1561 BuildConstructorCall(node, allocate);
1598 } 1562 }
1599 1563
1600 1564
1601 Value* EffectGraphVisitor::BuildInstantiator() { 1565 Value* EffectGraphVisitor::BuildInstantiator() {
1602 const Class& instantiator_class = Class::Handle( 1566 const Class& instantiator_class = Class::Handle(
1603 owner()->parsed_function().function().owner()); 1567 owner()->parsed_function().function().owner());
1604 if (instantiator_class.NumTypeParameters() == 0) { 1568 if (instantiator_class.NumTypeParameters() == 0) {
1605 return NULL; 1569 return NULL;
1606 } 1570 }
1607 Function& outer_function = 1571 Function& outer_function =
(...skipping 21 matching lines...) Expand all
1629 owner()->parsed_function().function().owner()); 1593 owner()->parsed_function().function().owner());
1630 if (instantiator_class.NumTypeParameters() == 0) { 1594 if (instantiator_class.NumTypeParameters() == 0) {
1631 // The type arguments are compile time constants. 1595 // The type arguments are compile time constants.
1632 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); 1596 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle();
1633 // TODO(regis): Temporary type should be allocated in new gen heap. 1597 // TODO(regis): Temporary type should be allocated in new gen heap.
1634 Type& type = Type::Handle( 1598 Type& type = Type::Handle(
1635 Type::New(instantiator_class, type_arguments, token_pos)); 1599 Type::New(instantiator_class, type_arguments, token_pos));
1636 type ^= ClassFinalizer::FinalizeType( 1600 type ^= ClassFinalizer::FinalizeType(
1637 instantiator_class, type, ClassFinalizer::kFinalizeWellFormed); 1601 instantiator_class, type, ClassFinalizer::kFinalizeWellFormed);
1638 type_arguments = type.arguments(); 1602 type_arguments = type.arguments();
1639 BindInstr* args = new BindInstr(new ConstantVal(type_arguments)); 1603 return Bind(new ConstantVal(type_arguments));
1640 AddInstruction(args);
1641 return new UseVal(args);
1642 } 1604 }
1643 Function& outer_function = 1605 Function& outer_function =
1644 Function::Handle(owner()->parsed_function().function().raw()); 1606 Function::Handle(owner()->parsed_function().function().raw());
1645 while (outer_function.IsLocalFunction()) { 1607 while (outer_function.IsLocalFunction()) {
1646 outer_function = outer_function.parent_function(); 1608 outer_function = outer_function.parent_function();
1647 } 1609 }
1648 if (outer_function.IsFactory()) { 1610 if (outer_function.IsFactory()) {
1649 // No instantiator for factories. 1611 // No instantiator for factories.
1650 ASSERT(instantiator == NULL); 1612 ASSERT(instantiator == NULL);
1651 ASSERT(owner()->parsed_function().instantiator() != NULL); 1613 ASSERT(owner()->parsed_function().instantiator() != NULL);
1652 ValueGraphVisitor for_instantiator(owner(), temp_index()); 1614 ValueGraphVisitor for_instantiator(owner(), temp_index());
1653 owner()->parsed_function().instantiator()->Visit(&for_instantiator); 1615 owner()->parsed_function().instantiator()->Visit(&for_instantiator);
1654 Append(for_instantiator); 1616 Append(for_instantiator);
1655 return for_instantiator.value(); 1617 return for_instantiator.value();
1656 } 1618 }
1657 if (instantiator == NULL) { 1619 if (instantiator == NULL) {
1658 instantiator = BuildInstantiator(); 1620 instantiator = BuildInstantiator();
1659 } 1621 }
1660 // The instantiator is the receiver of the caller, which is not a factory. 1622 // The instantiator is the receiver of the caller, which is not a factory.
1661 // The receiver cannot be null; extract its AbstractTypeArguments object. 1623 // The receiver cannot be null; extract its AbstractTypeArguments object.
1662 // Note that in the factory case, the instantiator is the first parameter 1624 // Note that in the factory case, the instantiator is the first parameter
1663 // of the factory, i.e. already an AbstractTypeArguments object. 1625 // of the factory, i.e. already an AbstractTypeArguments object.
1664 intptr_t type_arguments_instance_field_offset = 1626 intptr_t type_arguments_instance_field_offset =
1665 instantiator_class.type_arguments_instance_field_offset(); 1627 instantiator_class.type_arguments_instance_field_offset();
1666 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments); 1628 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments);
1667 1629
1668 BindInstr* load = 1630 return Bind(new LoadVMFieldComp(
1669 new BindInstr(new LoadVMFieldComp( 1631 instantiator,
1670 instantiator, 1632 type_arguments_instance_field_offset,
1671 type_arguments_instance_field_offset, 1633 Type::ZoneHandle())); // Not an instance, no type.
1672 Type::ZoneHandle())); // Not an instance, no type.
1673 AddInstruction(load);
1674 return new UseVal(load);
1675 } 1634 }
1676 1635
1677 1636
1678 BindInstr* EffectGraphVisitor::BuildInstantiatedTypeArguments( 1637 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments(
1679 intptr_t token_pos, 1638 intptr_t token_pos,
1680 const AbstractTypeArguments& type_arguments) { 1639 const AbstractTypeArguments& type_arguments) {
1681 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { 1640 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) {
1682 BindInstr* type_args = 1641 return Bind(new ConstantVal(type_arguments));
1683 new BindInstr(new ConstantVal(type_arguments));
1684 AddInstruction(type_args);
1685 return type_args;
1686 } 1642 }
1687 // The type arguments are uninstantiated. 1643 // The type arguments are uninstantiated.
1688 Value* instantiator_value = 1644 Value* instantiator_value =
1689 BuildInstantiatorTypeArguments(token_pos, NULL); 1645 BuildInstantiatorTypeArguments(token_pos, NULL);
1690 BindInstr* instantiate = 1646 return Bind(new InstantiateTypeArgumentsComp(token_pos,
1691 new BindInstr(new InstantiateTypeArgumentsComp(token_pos, 1647 owner()->try_index(),
1692 owner()->try_index(), 1648 type_arguments,
1693 type_arguments, 1649 instantiator_value));
1694 instantiator_value));
1695 AddInstruction(instantiate);
1696 return instantiate;
1697 } 1650 }
1698 1651
1699 1652
1700 void EffectGraphVisitor::BuildConstructorTypeArguments( 1653 void EffectGraphVisitor::BuildConstructorTypeArguments(
1701 ConstructorCallNode* node, 1654 ConstructorCallNode* node,
1702 ZoneGrowableArray<Value*>* args) { 1655 ZoneGrowableArray<Value*>* args) {
1703 const Class& cls = Class::ZoneHandle(node->constructor().owner()); 1656 const Class& cls = Class::ZoneHandle(node->constructor().owner());
1704 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); 1657 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory());
1705 if (node->type_arguments().IsNull() || 1658 if (node->type_arguments().IsNull() ||
1706 node->type_arguments().IsInstantiated()) { 1659 node->type_arguments().IsInstantiated()) {
1707 BindInstr* type_args = 1660 Value* type_args = Bind(new ConstantVal(node->type_arguments()));
1708 new BindInstr(new ConstantVal(node->type_arguments()));
1709 AddInstruction(type_args);
1710 // No instantiator required. 1661 // No instantiator required.
1711 BindInstr* no_instantiator = 1662 Value* no_instantiator = Bind(
1712 new BindInstr(new ConstantVal( 1663 new ConstantVal(Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator))));
1713 Smi::ZoneHandle(Smi::New( 1664 args->Add(type_args);
1714 StubCode::kNoInstantiator)))); 1665 args->Add(no_instantiator);
1715 AddInstruction(no_instantiator);
1716 args->Add(new UseVal(type_args));
1717 args->Add(new UseVal(no_instantiator));
1718 return; 1666 return;
1719 } 1667 }
1720 // The type arguments are uninstantiated. The generated pseudo code: 1668 // The type arguments are uninstantiated. The generated pseudo code:
1721 // t1 = InstantiatorTypeArguments(); 1669 // t1 = InstantiatorTypeArguments();
1722 // t2 = ExtractConstructorTypeArguments(t1); 1670 // t2 = ExtractConstructorTypeArguments(t1);
1723 // t1 = ExtractConstructorInstantiator(t1); 1671 // t1 = ExtractConstructorInstantiator(t1);
1724 // t_n <- t2 1672 // t_n <- t2
1725 // t_n+1 <- t1 1673 // t_n+1 <- t1
1726 // Use expression_temp_var and node->allocated_object_var() locals to keep 1674 // Use expression_temp_var and node->allocated_object_var() locals to keep
1727 // intermediate results around (t1 and t2 above). 1675 // intermediate results around (t1 and t2 above).
1728 ASSERT(owner()->parsed_function().expression_temp_var() != NULL); 1676 ASSERT(owner()->parsed_function().expression_temp_var() != NULL);
1729 const LocalVariable& t1 = *owner()->parsed_function().expression_temp_var(); 1677 const LocalVariable& t1 = *owner()->parsed_function().expression_temp_var();
1730 const LocalVariable& t2 = node->allocated_object_var(); 1678 const LocalVariable& t2 = node->allocated_object_var();
1731 Value* instantiator_type_arguments = BuildInstantiatorTypeArguments( 1679 Value* instantiator_type_arguments = BuildInstantiatorTypeArguments(
1732 node->token_pos(), NULL); 1680 node->token_pos(), NULL);
1733 ASSERT(instantiator_type_arguments->IsUse()); 1681 ASSERT(instantiator_type_arguments->IsUse());
1734 BindInstr* stored_instantiator = new BindInstr( 1682 Value* stored_instantiator =
1735 BuildStoreLocal(t1, instantiator_type_arguments)); 1683 Bind(BuildStoreLocal(t1, instantiator_type_arguments));
1736 AddInstruction(stored_instantiator);
1737 // t1: instantiator type arguments. 1684 // t1: instantiator type arguments.
1738 1685
1739 BindInstr* extract_type_arguments = new BindInstr( 1686 Value* extract_type_arguments = Bind(
1740 new ExtractConstructorTypeArgumentsComp( 1687 new ExtractConstructorTypeArgumentsComp(
1741 node->token_pos(), 1688 node->token_pos(),
1742 owner()->try_index(), 1689 owner()->try_index(),
1743 node->type_arguments(), 1690 node->type_arguments(),
1744 new UseVal(stored_instantiator))); 1691 stored_instantiator));
1745 AddInstruction(extract_type_arguments);
1746 1692
1747 Instruction* stored_type_arguments = new DoInstr( 1693 Do(BuildStoreLocal(t2, extract_type_arguments));
1748 BuildStoreLocal(t2, new UseVal(extract_type_arguments)));
1749 AddInstruction(stored_type_arguments);
1750 // t2: extracted constructor type arguments. 1694 // t2: extracted constructor type arguments.
1751 BindInstr* load_instantiator = new BindInstr(BuildLoadLocal(t1)); 1695 Value* load_instantiator = Bind(BuildLoadLocal(t1));
1752 AddInstruction(load_instantiator);
1753 1696
1754 BindInstr* extract_instantiator = 1697 Value* extract_instantiator =
1755 new BindInstr(new ExtractConstructorInstantiatorComp( 1698 Bind(new ExtractConstructorInstantiatorComp(node, load_instantiator));
1756 node, 1699 Do(BuildStoreLocal(t1, extract_instantiator));
1757 new UseVal(load_instantiator)));
1758 AddInstruction(extract_instantiator);
1759 AddInstruction(new DoInstr(
1760 BuildStoreLocal(t1, new UseVal(extract_instantiator))));
1761 // t2: extracted constructor type arguments. 1700 // t2: extracted constructor type arguments.
1762 // t1: extracted constructor instantiator. 1701 // t1: extracted constructor instantiator.
1763 BindInstr* load_0 = new BindInstr(BuildLoadLocal(t2)); 1702 Value* load_0 = Bind(BuildLoadLocal(t2));
1764 AddInstruction(load_0); 1703 Value* load_1 = Bind(BuildLoadLocal(t1));
1765 BindInstr* load_1 = new BindInstr(BuildLoadLocal(t1)); 1704 args->Add(load_0);
1766 AddInstruction(load_1); 1705 args->Add(load_1);
1767 args->Add(new UseVal(load_0));
1768 args->Add(new UseVal(load_1));
1769 } 1706 }
1770 1707
1771 1708
1772 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { 1709 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
1773 if (node->constructor().IsFactory()) { 1710 if (node->constructor().IsFactory()) {
1774 EffectGraphVisitor::VisitConstructorCallNode(node); 1711 EffectGraphVisitor::VisitConstructorCallNode(node);
1775 return; 1712 return;
1776 } 1713 }
1777 1714
1778 // t_n contains the allocated and initialized object. 1715 // t_n contains the allocated and initialized object.
1779 // t_n <- AllocateObject(class) 1716 // t_n <- AllocateObject(class)
1780 // t_n <- StoreLocal(temp, t_n); 1717 // t_n <- StoreLocal(temp, t_n);
1781 // t_n+1 <- ctor-arg 1718 // t_n+1 <- ctor-arg
1782 // t_n+2... <- constructor arguments start here 1719 // t_n+2... <- constructor arguments start here
1783 // StaticCall(constructor, t_n, t_n+1, ...) 1720 // StaticCall(constructor, t_n, t_n+1, ...)
1784 // tn <- LoadLocal(temp) 1721 // tn <- LoadLocal(temp)
1785 1722
1786 BindInstr* allocate = BuildObjectAllocation(node); 1723 Value* allocate = BuildObjectAllocation(node);
1787 Computation* store_allocated = BuildStoreLocal( 1724 Computation* store_allocated = BuildStoreLocal(
1788 node->allocated_object_var(), 1725 node->allocated_object_var(),
1789 new UseVal(allocate)); 1726 allocate);
1790 BindInstr* allocated_value = new BindInstr(store_allocated); 1727 Value* allocated_value = Bind(store_allocated);
1791 AddInstruction(allocated_value); 1728 BuildConstructorCall(node, allocated_value);
1792 BuildConstructorCall(node, new UseVal(allocated_value));
1793 Computation* load_allocated = BuildLoadLocal( 1729 Computation* load_allocated = BuildLoadLocal(
1794 node->allocated_object_var()); 1730 node->allocated_object_var());
1795 allocated_value = new BindInstr(load_allocated); 1731 allocated_value = Bind(load_allocated);
1796 AddInstruction(allocated_value); 1732 ReturnValue(allocated_value);
1797 ReturnValue(new UseVal(allocated_value));
1798 } 1733 }
1799 1734
1800 1735
1801 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { 1736 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
1802 ValueGraphVisitor for_receiver(owner(), temp_index()); 1737 ValueGraphVisitor for_receiver(owner(), temp_index());
1803 node->receiver()->Visit(&for_receiver); 1738 node->receiver()->Visit(&for_receiver);
1804 Append(for_receiver); 1739 Append(for_receiver);
1805 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); 1740 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1);
1806 arguments->Add(for_receiver.value()); 1741 arguments->Add(for_receiver.value());
1807 const String& name = 1742 const String& name =
(...skipping 27 matching lines...) Expand all
1835 node->field_name(), 1770 node->field_name(),
1836 receiver, 1771 receiver,
1837 value); 1772 value);
1838 ReturnComputation(setter); 1773 ReturnComputation(setter);
1839 } 1774 }
1840 1775
1841 1776
1842 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { 1777 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
1843 Value *receiver, *value; 1778 Value *receiver, *value;
1844 BuildInstanceSetterValues(node, &receiver, &value); 1779 BuildInstanceSetterValues(node, &receiver, &value);
1845 BindInstr* store_local_instr = new BindInstr( 1780 Value* saved_value = Bind(
1846 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(), 1781 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(),
1847 value)); 1782 value));
1848 AddInstruction(store_local_instr); 1783 Do(new InstanceSetterComp(node->token_pos(),
1849 UseVal* saved_value = new UseVal(store_local_instr); 1784 owner()->try_index(),
1850 InstanceSetterComp* setter = 1785 node->field_name(),
1851 new InstanceSetterComp(node->token_pos(), 1786 receiver,
1852 owner()->try_index(), 1787 saved_value));
1853 node->field_name(),
1854 receiver,
1855 saved_value);
1856 AddInstruction(new DoInstr(setter));
1857 ReturnComputation( 1788 ReturnComputation(
1858 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); 1789 BuildLoadLocal(*owner()->parsed_function().expression_temp_var()));
1859 } 1790 }
1860 1791
1861 1792
1862 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { 1793 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) {
1863 const String& getter_name = 1794 const String& getter_name =
1864 String::Handle(Field::GetterName(node->field_name())); 1795 String::Handle(Field::GetterName(node->field_name()));
1865 const Function& getter_function = 1796 const Function& getter_function =
1866 Function::ZoneHandle(node->cls().LookupStaticFunction(getter_name)); 1797 Function::ZoneHandle(node->cls().LookupStaticFunction(getter_name));
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
2048 array, 1979 array,
2049 index, 1980 index,
2050 value); 1981 value);
2051 ReturnComputation(store); 1982 ReturnComputation(store);
2052 } 1983 }
2053 1984
2054 1985
2055 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { 1986 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) {
2056 Value *array, *index, *value; 1987 Value *array, *index, *value;
2057 BuildStoreIndexedValues(node, &array, &index, &value); 1988 BuildStoreIndexedValues(node, &array, &index, &value);
2058 BindInstr* store_local_instr = new BindInstr( 1989 Value* saved_value = Bind(
2059 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(), 1990 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(),
2060 value)); 1991 value));
2061 AddInstruction(store_local_instr); 1992 Do(new StoreIndexedComp(node->token_pos(),
2062 UseVal* saved_value = new UseVal(store_local_instr); 1993 owner()->try_index(),
2063 StoreIndexedComp* store = new StoreIndexedComp(node->token_pos(), 1994 array,
2064 owner()->try_index(), 1995 index,
2065 array, 1996 saved_value));
2066 index,
2067 saved_value);
2068 AddInstruction(new DoInstr(store));
2069 ReturnComputation( 1997 ReturnComputation(
2070 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); 1998 BuildLoadLocal(*owner()->parsed_function().expression_temp_var()));
2071 } 1999 }
2072 2000
2073 2001
2074 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { 2002 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const {
2075 return (node == owner()->parsed_function().node_sequence()) && 2003 return (node == owner()->parsed_function().node_sequence()) &&
2076 (owner()->parsed_function().saved_context_var() != NULL); 2004 (owner()->parsed_function().saved_context_var() != NULL);
2077 } 2005 }
2078 2006
2079 2007
2080 void EffectGraphVisitor::UnchainContext() { 2008 void EffectGraphVisitor::UnchainContext() {
2081 BindInstr* context = new BindInstr(new CurrentContextComp()); 2009 Value* context = Bind(new CurrentContextComp());
2082 AddInstruction(context); 2010 Value* parent = Bind(
2083 BindInstr* parent = 2011 new LoadVMFieldComp(context,
2084 new BindInstr( 2012 Context::parent_offset(),
2085 new LoadVMFieldComp( 2013 Type::ZoneHandle())); // Not an instance, no type.
2086 new UseVal(context), 2014 Do(new StoreContextComp(parent));
2087 Context::parent_offset(),
2088 Type::ZoneHandle())); // Not an instance, no type.
2089 AddInstruction(parent);
2090 AddInstruction(new DoInstr(new StoreContextComp(new UseVal(parent))));
2091 } 2015 }
2092 2016
2093 2017
2094 // <Statement> ::= Sequence { scope: LocalScope 2018 // <Statement> ::= Sequence { scope: LocalScope
2095 // nodes: <Statement>* 2019 // nodes: <Statement>*
2096 // label: SourceLabel } 2020 // label: SourceLabel }
2097 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { 2021 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) {
2098 LocalScope* scope = node->scope(); 2022 LocalScope* scope = node->scope();
2099 const intptr_t num_context_variables = 2023 const intptr_t num_context_variables =
2100 (scope != NULL) ? scope->num_context_variables() : 0; 2024 (scope != NULL) ? scope->num_context_variables() : 0;
2101 int previous_context_level = owner()->context_level(); 2025 int previous_context_level = owner()->context_level();
2102 if (num_context_variables > 0) { 2026 if (num_context_variables > 0) {
2103 // The loop local scope declares variables that are captured. 2027 // The loop local scope declares variables that are captured.
2104 // Allocate and chain a new context. 2028 // Allocate and chain a new context.
2105 // Allocate context computation (uses current CTX) 2029 // Allocate context computation (uses current CTX)
2106 BindInstr* allocated_context = 2030 Value* allocated_context =
2107 new BindInstr(new AllocateContextComp(node->token_pos(), 2031 Bind(new AllocateContextComp(node->token_pos(),
2108 owner()->try_index(), 2032 owner()->try_index(),
2109 num_context_variables)); 2033 num_context_variables));
2110 AddInstruction(allocated_context);
2111 2034
2112 // If this node_sequence is the body of the function being compiled, and if 2035 // If this node_sequence is the body of the function being compiled, and if
2113 // this function is not a closure, do not link the current context as the 2036 // this function is not a closure, do not link the current context as the
2114 // parent of the newly allocated context, as it is not accessible. Instead, 2037 // parent of the newly allocated context, as it is not accessible. Instead,
2115 // save it in a pre-allocated variable and restore it on exit. 2038 // save it in a pre-allocated variable and restore it on exit.
2116 if (MustSaveRestoreContext(node)) { 2039 if (MustSaveRestoreContext(node)) {
2117 BindInstr* current_context = new BindInstr(new CurrentContextComp()); 2040 Value* current_context = Bind(new CurrentContextComp());
2118 AddInstruction(current_context); 2041 Do(BuildStoreLocal(*owner()->parsed_function().saved_context_var(),
2119 Computation* store_local = BuildStoreLocal( 2042 current_context));
2120 *owner()->parsed_function().saved_context_var(), 2043 Value* null_context = Bind(new ConstantVal(Object::ZoneHandle()));
2121 new UseVal(current_context)); 2044 Do(new StoreContextComp(null_context));
2122 AddInstruction(new DoInstr(store_local));
2123 BindInstr* null_context =
2124 new BindInstr(new ConstantVal(Object::ZoneHandle()));
2125 AddInstruction(null_context);
2126 StoreContextComp* store_context =
2127 new StoreContextComp(new UseVal(null_context));
2128 AddInstruction(new DoInstr(store_context));
2129 } 2045 }
2130 2046
2131 ChainContextComp* chain_context = 2047 Do(new ChainContextComp(allocated_context));
2132 new ChainContextComp(new UseVal(allocated_context));
2133 AddInstruction(new DoInstr(chain_context));
2134 owner()->set_context_level(scope->context_level()); 2048 owner()->set_context_level(scope->context_level());
2135 2049
2136 // If this node_sequence is the body of the function being compiled, copy 2050 // If this node_sequence is the body of the function being compiled, copy
2137 // the captured parameters from the frame into the context. 2051 // the captured parameters from the frame into the context.
2138 if (node == owner()->parsed_function().node_sequence()) { 2052 if (node == owner()->parsed_function().node_sequence()) {
2139 ASSERT(scope->context_level() == 1); 2053 ASSERT(scope->context_level() == 1);
2140 const Function& function = owner()->parsed_function().function(); 2054 const Function& function = owner()->parsed_function().function();
2141 const int num_params = function.NumberOfParameters(); 2055 const int num_params = function.NumberOfParameters();
2142 int param_frame_index = (num_params == function.num_fixed_parameters()) ? 2056 int param_frame_index = (num_params == function.num_fixed_parameters()) ?
2143 (1 + num_params) : ParsedFunction::kFirstLocalSlotIndex; 2057 (1 + num_params) : ParsedFunction::kFirstLocalSlotIndex;
2144 for (int pos = 0; pos < num_params; param_frame_index--, pos++) { 2058 for (int pos = 0; pos < num_params; param_frame_index--, pos++) {
2145 const LocalVariable& parameter = *scope->VariableAt(pos); 2059 const LocalVariable& parameter = *scope->VariableAt(pos);
2146 ASSERT(parameter.owner() == scope); 2060 ASSERT(parameter.owner() == scope);
2147 if (parameter.is_captured()) { 2061 if (parameter.is_captured()) {
2148 // Create a temporary local describing the original position. 2062 // Create a temporary local describing the original position.
2149 const String& temp_name = String::ZoneHandle(String::Concat( 2063 const String& temp_name = String::ZoneHandle(String::Concat(
2150 parameter.name(), String::Handle(String::NewSymbol("-orig")))); 2064 parameter.name(), String::Handle(String::NewSymbol("-orig"))));
2151 LocalVariable* temp_local = new LocalVariable( 2065 LocalVariable* temp_local = new LocalVariable(
2152 0, // Token index. 2066 0, // Token index.
2153 temp_name, 2067 temp_name,
2154 Type::ZoneHandle(Type::DynamicType())); // Type. 2068 Type::ZoneHandle(Type::DynamicType())); // Type.
2155 temp_local->set_index(param_frame_index); 2069 temp_local->set_index(param_frame_index);
2156 2070
2157 // Copy parameter from local frame to current context. 2071 // Copy parameter from local frame to current context.
2158 BindInstr* load = new BindInstr(BuildLoadLocal(*temp_local)); 2072 Value* load = Bind(BuildLoadLocal(*temp_local));
2159 AddInstruction(load); 2073 Do(BuildStoreLocal(parameter, load));
2160 Computation* store_local =
2161 BuildStoreLocal(parameter, new UseVal(load));
2162 AddInstruction(new DoInstr(store_local));
2163 // Write NULL to the source location to detect buggy accesses and 2074 // Write NULL to the source location to detect buggy accesses and
2164 // allow GC of passed value if it gets overwritten by a new value in 2075 // allow GC of passed value if it gets overwritten by a new value in
2165 // the function. 2076 // the function.
2166 BindInstr* null_constant = 2077 Value* null_constant = Bind(new ConstantVal(Object::ZoneHandle()));
2167 new BindInstr(new ConstantVal(Object::ZoneHandle())); 2078 Do(BuildStoreLocal(*temp_local, null_constant));
2168 AddInstruction(null_constant);
2169 Computation* clear_local =
2170 BuildStoreLocal(*temp_local, new UseVal(null_constant));
2171 AddInstruction(new DoInstr(clear_local));
2172 } 2079 }
2173 } 2080 }
2174 } 2081 }
2175 } 2082 }
2176 2083
2177 if (FLAG_enable_type_checks && 2084 if (FLAG_enable_type_checks &&
2178 (node == owner()->parsed_function().node_sequence())) { 2085 (node == owner()->parsed_function().node_sequence())) {
2179 const Function& function = owner()->parsed_function().function(); 2086 const Function& function = owner()->parsed_function().function();
2180 const int num_params = function.NumberOfParameters(); 2087 const int num_params = function.NumberOfParameters();
2181 int pos = 0; 2088 int pos = 0;
2182 if (function.IsConstructor()) { 2089 if (function.IsConstructor()) {
2183 // Skip type checking of receiver and phase for constructor functions. 2090 // Skip type checking of receiver and phase for constructor functions.
2184 pos = 2; 2091 pos = 2;
2185 } else if (function.IsFactory() || function.IsDynamicFunction()) { 2092 } else if (function.IsFactory() || function.IsDynamicFunction()) {
2186 // Skip type checking of type arguments for factory functions. 2093 // Skip type checking of type arguments for factory functions.
2187 // Skip type checking of receiver for instance functions. 2094 // Skip type checking of receiver for instance functions.
2188 pos = 1; 2095 pos = 1;
2189 } 2096 }
2190 while (pos < num_params) { 2097 while (pos < num_params) {
2191 const LocalVariable& parameter = *scope->VariableAt(pos); 2098 const LocalVariable& parameter = *scope->VariableAt(pos);
2192 ASSERT(parameter.owner() == scope); 2099 ASSERT(parameter.owner() == scope);
2193 if (!CanSkipTypeCheck(NULL, parameter.type())) { 2100 if (!CanSkipTypeCheck(NULL, parameter.type())) {
2194 BindInstr* load = new BindInstr(BuildLoadLocal(parameter)); 2101 Value* load = Bind(BuildLoadLocal(parameter));
2195 AddInstruction(load); 2102 Do(BuildAssertAssignable(parameter.token_pos(),
2196 AssertAssignableComp* assert_assignable = 2103 load,
2197 BuildAssertAssignable(parameter.token_pos(), 2104 parameter.type(),
2198 new UseVal(load), 2105 parameter.name()));
2199 parameter.type(),
2200 parameter.name());
2201 AddInstruction(new DoInstr(assert_assignable));
2202 } 2106 }
2203 pos++; 2107 pos++;
2204 } 2108 }
2205 } 2109 }
2206 2110
2207 intptr_t i = 0; 2111 intptr_t i = 0;
2208 while (is_open() && (i < node->length())) { 2112 while (is_open() && (i < node->length())) {
2209 EffectGraphVisitor for_effect(owner(), temp_index()); 2113 EffectGraphVisitor for_effect(owner(), temp_index());
2210 node->NodeAt(i++)->Visit(&for_effect); 2114 node->NodeAt(i++)->Visit(&for_effect);
2211 Append(for_effect); 2115 Append(for_effect);
(...skipping 30 matching lines...) Expand all
2242 ASSERT((node->label() == NULL) || 2146 ASSERT((node->label() == NULL) ||
2243 (node != owner()->parsed_function().node_sequence())); 2147 (node != owner()->parsed_function().node_sequence()));
2244 owner()->set_context_level(previous_context_level); 2148 owner()->set_context_level(previous_context_level);
2245 } 2149 }
2246 2150
2247 2151
2248 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { 2152 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) {
2249 // NOTE: The implicit variables ':saved_context', ':exception_var' 2153 // NOTE: The implicit variables ':saved_context', ':exception_var'
2250 // and ':stacktrace_var' can never be captured variables. 2154 // and ':stacktrace_var' can never be captured variables.
2251 // Restores CTX from local variable ':saved_context'. 2155 // Restores CTX from local variable ':saved_context'.
2252 CatchEntryComp* catch_entry = new CatchEntryComp(node->exception_var(), 2156 Do(new CatchEntryComp(node->exception_var(), node->stacktrace_var()));
2253 node->stacktrace_var());
2254 AddInstruction(new DoInstr(catch_entry));
2255 BuildLoadContext(node->context_var()); 2157 BuildLoadContext(node->context_var());
2256 2158
2257 EffectGraphVisitor for_catch(owner(), temp_index()); 2159 EffectGraphVisitor for_catch(owner(), temp_index());
2258 node->VisitChildren(&for_catch); 2160 node->VisitChildren(&for_catch);
2259 Append(for_catch); 2161 Append(for_catch);
2260 } 2162 }
2261 2163
2262 2164
2263 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { 2165 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) {
2264 intptr_t old_try_index = owner()->try_index(); 2166 intptr_t old_try_index = owner()->try_index();
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after
2799 char* chars = reinterpret_cast<char*>( 2701 char* chars = reinterpret_cast<char*>(
2800 Isolate::Current()->current_zone()->Allocate(len)); 2702 Isolate::Current()->current_zone()->Allocate(len));
2801 OS::SNPrint(chars, len, kFormat, function_name, reason); 2703 OS::SNPrint(chars, len, kFormat, function_name, reason);
2802 const Error& error = Error::Handle( 2704 const Error& error = Error::Handle(
2803 LanguageError::New(String::Handle(String::New(chars)))); 2705 LanguageError::New(String::Handle(String::New(chars))));
2804 Isolate::Current()->long_jump_base()->Jump(1, error); 2706 Isolate::Current()->long_jump_base()->Jump(1, error);
2805 } 2707 }
2806 2708
2807 2709
2808 } // namespace dart 2710 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698