| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |