| 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/code_descriptors.h" | 8 #include "vm/code_descriptors.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flags.h" | 10 #include "vm/flags.h" |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 | 155 |
| 156 // 3. Add a join or select one (or neither) of the arms as exit. | 156 // 3. Add a join or select one (or neither) of the arms as exit. |
| 157 if (true_exit == NULL) { | 157 if (true_exit == NULL) { |
| 158 exit_ = false_exit; // May be NULL. | 158 exit_ = false_exit; // May be NULL. |
| 159 if (false_exit != NULL) temp_index_ = false_fragment.temp_index(); | 159 if (false_exit != NULL) temp_index_ = false_fragment.temp_index(); |
| 160 } else if (false_exit == NULL) { | 160 } else if (false_exit == NULL) { |
| 161 exit_ = true_exit; | 161 exit_ = true_exit; |
| 162 temp_index_ = true_fragment.temp_index(); | 162 temp_index_ = true_fragment.temp_index(); |
| 163 } else { | 163 } else { |
| 164 JoinEntryInstr* join = | 164 JoinEntryInstr* join = |
| 165 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 165 new JoinEntryInstr(owner()->AllocateBlockId(), |
| 166 owner()->try_index(), |
| 167 loop_depth()); |
| 166 true_exit->Goto(join); | 168 true_exit->Goto(join); |
| 167 false_exit->Goto(join); | 169 false_exit->Goto(join); |
| 168 exit_ = join; | 170 exit_ = join; |
| 169 ASSERT(true_fragment.temp_index() == false_fragment.temp_index()); | 171 ASSERT(true_fragment.temp_index() == false_fragment.temp_index()); |
| 170 temp_index_ = true_fragment.temp_index(); | 172 temp_index_ = true_fragment.temp_index(); |
| 171 } | 173 } |
| 172 } | 174 } |
| 173 | 175 |
| 174 | 176 |
| 175 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment, | 177 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment, |
| 176 const EffectGraphVisitor& body_fragment) { | 178 const EffectGraphVisitor& body_fragment) { |
| 177 // We have: a test graph fragment with zero, one, or two available exits; | 179 // We have: a test graph fragment with zero, one, or two available exits; |
| 178 // and an effect graph fragment with zero or one available exits. We want | 180 // and an effect graph fragment with zero or one available exits. We want |
| 179 // to append the 'while loop' consisting of the test graph fragment as | 181 // to append the 'while loop' consisting of the test graph fragment as |
| 180 // condition and the effect graph fragment as body. | 182 // condition and the effect graph fragment as body. |
| 181 ASSERT(is_open()); | 183 ASSERT(is_open()); |
| 182 | 184 |
| 183 // 1. Connect the body to the test if it is reachable, and if so record | 185 // 1. Connect the body to the test if it is reachable, and if so record |
| 184 // its exit (if any). | 186 // its exit (if any). |
| 185 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor(); | 187 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor(); |
| 186 Instruction* body_exit = AppendFragment(body_entry, body_fragment); | 188 Instruction* body_exit = AppendFragment(body_entry, body_fragment); |
| 187 | 189 |
| 188 // 2. Connect the test to this graph, including the body if reachable and | 190 // 2. Connect the test to this graph, including the body if reachable and |
| 189 // using a fresh join node if the body is reachable and has an open exit. | 191 // using a fresh join node if the body is reachable and has an open exit. |
| 190 if (body_exit == NULL) { | 192 if (body_exit == NULL) { |
| 191 Append(test_fragment); | 193 Append(test_fragment); |
| 192 } else { | 194 } else { |
| 193 JoinEntryInstr* join = | 195 JoinEntryInstr* join = |
| 194 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 196 new JoinEntryInstr(owner()->AllocateBlockId(), |
| 197 owner()->try_index(), |
| 198 loop_depth()); |
| 195 join->LinkTo(test_fragment.entry()); | 199 join->LinkTo(test_fragment.entry()); |
| 196 Goto(join); | 200 Goto(join); |
| 197 body_exit->Goto(join); | 201 body_exit->Goto(join); |
| 198 } | 202 } |
| 199 | 203 |
| 200 // 3. Set the exit to the graph to be the false successor of the test, a | 204 // 3. Set the exit to the graph to be the false successor of the test, a |
| 201 // fresh target node | 205 // fresh target node |
| 202 | 206 |
| 203 exit_ = test_fragment.CreateFalseSuccessor(); | 207 exit_ = test_fragment.CreateFalseSuccessor(); |
| 204 } | 208 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 AddInstruction(new StoreContextInstr(load_saved_context)); | 300 AddInstruction(new StoreContextInstr(load_saved_context)); |
| 297 } | 301 } |
| 298 | 302 |
| 299 | 303 |
| 300 void TestGraphVisitor::ConnectBranchesTo( | 304 void TestGraphVisitor::ConnectBranchesTo( |
| 301 const GrowableArray<TargetEntryInstr**>& branches, | 305 const GrowableArray<TargetEntryInstr**>& branches, |
| 302 JoinEntryInstr* join) const { | 306 JoinEntryInstr* join) const { |
| 303 ASSERT(!branches.is_empty()); | 307 ASSERT(!branches.is_empty()); |
| 304 for (intptr_t i = 0; i < branches.length(); i++) { | 308 for (intptr_t i = 0; i < branches.length(); i++) { |
| 305 TargetEntryInstr* target = | 309 TargetEntryInstr* target = |
| 306 new TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 310 new TargetEntryInstr(owner()->AllocateBlockId(), |
| 311 owner()->try_index(), |
| 312 loop_depth()); |
| 307 *(branches[i]) = target; | 313 *(branches[i]) = target; |
| 308 target->Goto(join); | 314 target->Goto(join); |
| 309 } | 315 } |
| 310 } | 316 } |
| 311 | 317 |
| 312 | 318 |
| 313 void TestGraphVisitor::IfTrueGoto(JoinEntryInstr* join) const { | 319 void TestGraphVisitor::IfTrueGoto(JoinEntryInstr* join) const { |
| 314 ConnectBranchesTo(true_successor_addresses_, join); | 320 ConnectBranchesTo(true_successor_addresses_, join); |
| 315 } | 321 } |
| 316 | 322 |
| 317 | 323 |
| 318 void TestGraphVisitor::IfFalseGoto(JoinEntryInstr* join) const { | 324 void TestGraphVisitor::IfFalseGoto(JoinEntryInstr* join) const { |
| 319 ConnectBranchesTo(false_successor_addresses_, join); | 325 ConnectBranchesTo(false_successor_addresses_, join); |
| 320 } | 326 } |
| 321 | 327 |
| 322 | 328 |
| 323 BlockEntryInstr* TestGraphVisitor::CreateSuccessorFor( | 329 BlockEntryInstr* TestGraphVisitor::CreateSuccessorFor( |
| 324 const GrowableArray<TargetEntryInstr**>& branches) const { | 330 const GrowableArray<TargetEntryInstr**>& branches) const { |
| 325 ASSERT(!branches.is_empty()); | 331 ASSERT(!branches.is_empty()); |
| 326 | 332 |
| 327 if (branches.length() == 1) { | 333 if (branches.length() == 1) { |
| 328 TargetEntryInstr* target = | 334 TargetEntryInstr* target = |
| 329 new TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 335 new TargetEntryInstr(owner()->AllocateBlockId(), |
| 336 owner()->try_index(), |
| 337 loop_depth()); |
| 330 *(branches[0]) = target; | 338 *(branches[0]) = target; |
| 331 return target; | 339 return target; |
| 332 } | 340 } |
| 333 | 341 |
| 334 JoinEntryInstr* join = | 342 JoinEntryInstr* join = |
| 335 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 343 new JoinEntryInstr(owner()->AllocateBlockId(), |
| 344 owner()->try_index(), |
| 345 loop_depth()); |
| 336 ConnectBranchesTo(branches, join); | 346 ConnectBranchesTo(branches, join); |
| 337 return join; | 347 return join; |
| 338 } | 348 } |
| 339 | 349 |
| 340 | 350 |
| 341 BlockEntryInstr* TestGraphVisitor::CreateTrueSuccessor() const { | 351 BlockEntryInstr* TestGraphVisitor::CreateTrueSuccessor() const { |
| 342 return CreateSuccessorFor(true_successor_addresses_); | 352 return CreateSuccessorFor(true_successor_addresses_); |
| 343 } | 353 } |
| 344 | 354 |
| 345 | 355 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 } | 428 } |
| 419 | 429 |
| 420 | 430 |
| 421 // Special handling for AND/OR. | 431 // Special handling for AND/OR. |
| 422 void TestGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 432 void TestGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 423 // Operators "&&" and "||" cannot be overloaded therefore do not call | 433 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 424 // operator. | 434 // operator. |
| 425 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 435 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 426 TestGraphVisitor for_left(owner(), | 436 TestGraphVisitor for_left(owner(), |
| 427 temp_index(), | 437 temp_index(), |
| 438 loop_depth(), |
| 428 node->left()->token_pos()); | 439 node->left()->token_pos()); |
| 429 node->left()->Visit(&for_left); | 440 node->left()->Visit(&for_left); |
| 430 | 441 |
| 431 TestGraphVisitor for_right(owner(), | 442 TestGraphVisitor for_right(owner(), |
| 432 temp_index(), | 443 temp_index(), |
| 444 loop_depth(), |
| 433 node->right()->token_pos()); | 445 node->right()->token_pos()); |
| 434 node->right()->Visit(&for_right); | 446 node->right()->Visit(&for_right); |
| 435 | 447 |
| 436 Append(for_left); | 448 Append(for_left); |
| 437 | 449 |
| 438 if (node->kind() == Token::kAND) { | 450 if (node->kind() == Token::kAND) { |
| 439 AppendFragment(for_left.CreateTrueSuccessor(), for_right); | 451 AppendFragment(for_left.CreateTrueSuccessor(), for_right); |
| 440 true_successor_addresses_.AddArray(for_right.true_successor_addresses_); | 452 true_successor_addresses_.AddArray(for_right.true_successor_addresses_); |
| 441 false_successor_addresses_.AddArray(for_left.false_successor_addresses_); | 453 false_successor_addresses_.AddArray(for_left.false_successor_addresses_); |
| 442 false_successor_addresses_.AddArray(for_right.false_successor_addresses_); | 454 false_successor_addresses_.AddArray(for_right.false_successor_addresses_); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 461 | 473 |
| 462 void EffectGraphVisitor::InlineBailout(const char* reason) { | 474 void EffectGraphVisitor::InlineBailout(const char* reason) { |
| 463 owner()->parsed_function().function().set_is_inlinable(false); | 475 owner()->parsed_function().function().set_is_inlinable(false); |
| 464 if (owner()->InInliningContext()) owner()->Bailout(reason); | 476 if (owner()->InInliningContext()) owner()->Bailout(reason); |
| 465 } | 477 } |
| 466 | 478 |
| 467 | 479 |
| 468 // <Statement> ::= Return { value: <Expression> | 480 // <Statement> ::= Return { value: <Expression> |
| 469 // inlined_finally_list: <InlinedFinally>* } | 481 // inlined_finally_list: <InlinedFinally>* } |
| 470 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { | 482 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { |
| 471 ValueGraphVisitor for_value(owner(), temp_index()); | 483 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); |
| 472 node->value()->Visit(&for_value); | 484 node->value()->Visit(&for_value); |
| 473 Append(for_value); | 485 Append(for_value); |
| 474 | 486 |
| 475 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { | 487 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { |
| 476 InlineBailout("EffectGraphVisitor::VisitReturnNode (exception)"); | 488 InlineBailout("EffectGraphVisitor::VisitReturnNode (exception)"); |
| 477 EffectGraphVisitor for_effect(owner(), temp_index()); | 489 EffectGraphVisitor for_effect(owner(), temp_index(), loop_depth()); |
| 478 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); | 490 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
| 479 Append(for_effect); | 491 Append(for_effect); |
| 480 if (!is_open()) return; | 492 if (!is_open()) return; |
| 481 } | 493 } |
| 482 | 494 |
| 483 Value* return_value = for_value.value(); | 495 Value* return_value = for_value.value(); |
| 484 if (FLAG_enable_type_checks) { | 496 if (FLAG_enable_type_checks) { |
| 485 const Function& function = owner()->parsed_function().function(); | 497 const Function& function = owner()->parsed_function().function(); |
| 486 const bool is_implicit_dynamic_getter = | 498 const bool is_implicit_dynamic_getter = |
| 487 (!function.is_static() && | 499 (!function.is_static() && |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 | 604 |
| 593 // <Expression> :: Assignable { expr: <Expression> | 605 // <Expression> :: Assignable { expr: <Expression> |
| 594 // type: AbstractType | 606 // type: AbstractType |
| 595 // dst_name: String } | 607 // dst_name: String } |
| 596 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { | 608 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 597 UNREACHABLE(); | 609 UNREACHABLE(); |
| 598 } | 610 } |
| 599 | 611 |
| 600 | 612 |
| 601 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { | 613 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 602 ValueGraphVisitor for_value(owner(), temp_index()); | 614 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); |
| 603 node->expr()->Visit(&for_value); | 615 node->expr()->Visit(&for_value); |
| 604 Append(for_value); | 616 Append(for_value); |
| 605 ReturnValue(BuildAssignableValue(node->expr()->token_pos(), | 617 ReturnValue(BuildAssignableValue(node->expr()->token_pos(), |
| 606 for_value.value(), | 618 for_value.value(), |
| 607 node->type(), | 619 node->type(), |
| 608 node->dst_name())); | 620 node->dst_name())); |
| 609 } | 621 } |
| 610 | 622 |
| 611 | 623 |
| 612 // <Expression> :: BinaryOp { kind: Token::Kind | 624 // <Expression> :: BinaryOp { kind: Token::Kind |
| 613 // left: <Expression> | 625 // left: <Expression> |
| 614 // right: <Expression> } | 626 // right: <Expression> } |
| 615 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 627 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
| 616 // Operators "&&" and "||" cannot be overloaded therefore do not call | 628 // Operators "&&" and "||" cannot be overloaded therefore do not call |
| 617 // operator. | 629 // operator. |
| 618 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 630 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 619 // See ValueGraphVisitor::VisitBinaryOpNode. | 631 // See ValueGraphVisitor::VisitBinaryOpNode. |
| 620 TestGraphVisitor for_left(owner(), | 632 TestGraphVisitor for_left(owner(), |
| 621 temp_index(), | 633 temp_index(), |
| 634 loop_depth(), |
| 622 node->left()->token_pos()); | 635 node->left()->token_pos()); |
| 623 node->left()->Visit(&for_left); | 636 node->left()->Visit(&for_left); |
| 624 EffectGraphVisitor for_right(owner(), temp_index()); | 637 EffectGraphVisitor for_right(owner(), temp_index(), loop_depth()); |
| 625 node->right()->Visit(&for_right); | 638 node->right()->Visit(&for_right); |
| 626 EffectGraphVisitor empty(owner(), temp_index()); | 639 EffectGraphVisitor empty(owner(), temp_index(), loop_depth()); |
| 627 if (node->kind() == Token::kAND) { | 640 if (node->kind() == Token::kAND) { |
| 628 Join(for_left, for_right, empty); | 641 Join(for_left, for_right, empty); |
| 629 } else { | 642 } else { |
| 630 Join(for_left, empty, for_right); | 643 Join(for_left, empty, for_right); |
| 631 } | 644 } |
| 632 return; | 645 return; |
| 633 } | 646 } |
| 634 ValueGraphVisitor for_left_value(owner(), temp_index()); | 647 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); |
| 635 node->left()->Visit(&for_left_value); | 648 node->left()->Visit(&for_left_value); |
| 636 Append(for_left_value); | 649 Append(for_left_value); |
| 637 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); | 650 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); |
| 638 | 651 |
| 639 ValueGraphVisitor for_right_value(owner(), temp_index()); | 652 ValueGraphVisitor for_right_value(owner(), temp_index(), loop_depth()); |
| 640 node->right()->Visit(&for_right_value); | 653 node->right()->Visit(&for_right_value); |
| 641 Append(for_right_value); | 654 Append(for_right_value); |
| 642 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); | 655 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); |
| 643 | 656 |
| 644 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 657 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 645 new ZoneGrowableArray<PushArgumentInstr*>(2); | 658 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 646 arguments->Add(push_left); | 659 arguments->Add(push_left); |
| 647 arguments->Add(push_right); | 660 arguments->Add(push_right); |
| 648 const String& name = String::ZoneHandle(Symbols::New(node->Name())); | 661 const String& name = String::ZoneHandle(Symbols::New(node->Name())); |
| 649 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), | 662 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), |
| (...skipping 13 matching lines...) Expand all Loading... |
| 663 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 676 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
| 664 // Implement short-circuit logic: do not evaluate right if evaluation | 677 // Implement short-circuit logic: do not evaluate right if evaluation |
| 665 // of left is sufficient. | 678 // of left is sufficient. |
| 666 // AND: left ? right === true : false; | 679 // AND: left ? right === true : false; |
| 667 // OR: left ? true : right === true; | 680 // OR: left ? true : right === true; |
| 668 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 681 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 669 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 682 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| 670 | 683 |
| 671 TestGraphVisitor for_test(owner(), | 684 TestGraphVisitor for_test(owner(), |
| 672 temp_index(), | 685 temp_index(), |
| 686 loop_depth(), |
| 673 node->left()->token_pos()); | 687 node->left()->token_pos()); |
| 674 node->left()->Visit(&for_test); | 688 node->left()->Visit(&for_test); |
| 675 | 689 |
| 676 ValueGraphVisitor for_right(owner(), temp_index()); | 690 ValueGraphVisitor for_right(owner(), temp_index(), loop_depth()); |
| 677 node->right()->Visit(&for_right); | 691 node->right()->Visit(&for_right); |
| 678 Value* right_value = for_right.value(); | 692 Value* right_value = for_right.value(); |
| 679 if (FLAG_enable_type_checks) { | 693 if (FLAG_enable_type_checks) { |
| 680 right_value = | 694 right_value = |
| 681 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(), | 695 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(), |
| 682 right_value)); | 696 right_value)); |
| 683 } | 697 } |
| 684 Value* constant_true = for_right.Bind(new ConstantInstr(bool_true)); | 698 Value* constant_true = for_right.Bind(new ConstantInstr(bool_true)); |
| 685 Value* compare = | 699 Value* compare = |
| 686 for_right.Bind(new StrictCompareInstr(Token::kEQ_STRICT, | 700 for_right.Bind(new StrictCompareInstr(Token::kEQ_STRICT, |
| 687 right_value, | 701 right_value, |
| 688 constant_true)); | 702 constant_true)); |
| 689 for_right.Do(BuildStoreExprTemp(compare)); | 703 for_right.Do(BuildStoreExprTemp(compare)); |
| 690 | 704 |
| 691 if (node->kind() == Token::kAND) { | 705 if (node->kind() == Token::kAND) { |
| 692 ValueGraphVisitor for_false(owner(), temp_index()); | 706 ValueGraphVisitor for_false(owner(), temp_index(), loop_depth()); |
| 693 Value* constant_false = for_false.Bind(new ConstantInstr(bool_false)); | 707 Value* constant_false = for_false.Bind(new ConstantInstr(bool_false)); |
| 694 for_false.Do(BuildStoreExprTemp(constant_false)); | 708 for_false.Do(BuildStoreExprTemp(constant_false)); |
| 695 Join(for_test, for_right, for_false); | 709 Join(for_test, for_right, for_false); |
| 696 } else { | 710 } else { |
| 697 ASSERT(node->kind() == Token::kOR); | 711 ASSERT(node->kind() == Token::kOR); |
| 698 ValueGraphVisitor for_true(owner(), temp_index()); | 712 ValueGraphVisitor for_true(owner(), temp_index(), loop_depth()); |
| 699 Value* constant_true = for_true.Bind(new ConstantInstr(bool_true)); | 713 Value* constant_true = for_true.Bind(new ConstantInstr(bool_true)); |
| 700 for_true.Do(BuildStoreExprTemp(constant_true)); | 714 for_true.Do(BuildStoreExprTemp(constant_true)); |
| 701 Join(for_test, for_true, for_right); | 715 Join(for_test, for_true, for_right); |
| 702 } | 716 } |
| 703 ReturnDefinition(BuildLoadExprTemp()); | 717 ReturnDefinition(BuildLoadExprTemp()); |
| 704 return; | 718 return; |
| 705 } | 719 } |
| 706 EffectGraphVisitor::VisitBinaryOpNode(node); | 720 EffectGraphVisitor::VisitBinaryOpNode(node); |
| 707 } | 721 } |
| 708 | 722 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 773 const String& dst_name) { | 787 const String& dst_name) { |
| 774 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { | 788 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { |
| 775 return value; | 789 return value; |
| 776 } | 790 } |
| 777 return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name)); | 791 return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name)); |
| 778 } | 792 } |
| 779 | 793 |
| 780 | 794 |
| 781 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { | 795 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
| 782 ASSERT(Token::IsTypeTestOperator(node->kind())); | 796 ASSERT(Token::IsTypeTestOperator(node->kind())); |
| 783 EffectGraphVisitor for_left_value(owner(), temp_index()); | 797 EffectGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); |
| 784 node->left()->Visit(&for_left_value); | 798 node->left()->Visit(&for_left_value); |
| 785 Append(for_left_value); | 799 Append(for_left_value); |
| 786 } | 800 } |
| 787 | 801 |
| 788 | 802 |
| 789 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { | 803 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { |
| 790 ASSERT(Token::IsTypeCastOperator(node->kind())); | 804 ASSERT(Token::IsTypeCastOperator(node->kind())); |
| 791 const AbstractType& type = node->right()->AsTypeNode()->type(); | 805 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 792 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. | 806 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. |
| 793 ValueGraphVisitor for_value(owner(), temp_index()); | 807 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); |
| 794 node->left()->Visit(&for_value); | 808 node->left()->Visit(&for_value); |
| 795 const String& dst_name = String::ZoneHandle( | 809 const String& dst_name = String::ZoneHandle( |
| 796 Symbols::New(Exceptions::kCastErrorDstName)); | 810 Symbols::New(Exceptions::kCastErrorDstName)); |
| 797 if (!CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) { | 811 if (!CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) { |
| 798 Append(for_value); | 812 Append(for_value); |
| 799 Do(BuildAssertAssignable( | 813 Do(BuildAssertAssignable( |
| 800 node->token_pos(), for_value.value(), type, dst_name)); | 814 node->token_pos(), for_value.value(), type, dst_name)); |
| 801 } | 815 } |
| 802 } | 816 } |
| 803 | 817 |
| 804 | 818 |
| 805 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { | 819 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
| 806 ASSERT(Token::IsTypeTestOperator(node->kind())); | 820 ASSERT(Token::IsTypeTestOperator(node->kind())); |
| 807 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 821 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 808 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | 822 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); |
| 809 const AbstractType& type = node->right()->AsTypeNode()->type(); | 823 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 810 ASSERT(type.IsFinalized() && !type.IsMalformed()); | 824 ASSERT(type.IsFinalized() && !type.IsMalformed()); |
| 811 const bool negate_result = (node->kind() == Token::kISNOT); | 825 const bool negate_result = (node->kind() == Token::kISNOT); |
| 812 // All objects are instances of type T if Object type is a subtype of type T. | 826 // All objects are instances of type T if Object type is a subtype of type T. |
| 813 const Type& object_type = Type::Handle(Type::ObjectType()); | 827 const Type& object_type = Type::Handle(Type::ObjectType()); |
| 814 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { | 828 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { |
| 815 // Must evaluate left side. | 829 // Must evaluate left side. |
| 816 EffectGraphVisitor for_left_value(owner(), temp_index()); | 830 EffectGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); |
| 817 node->left()->Visit(&for_left_value); | 831 node->left()->Visit(&for_left_value); |
| 818 Append(for_left_value); | 832 Append(for_left_value); |
| 819 ReturnDefinition(new ConstantInstr(negate_result ? bool_false : bool_true)); | 833 ReturnDefinition(new ConstantInstr(negate_result ? bool_false : bool_true)); |
| 820 return; | 834 return; |
| 821 } | 835 } |
| 822 | 836 |
| 823 // Eliminate the test if it can be performed successfully at compile time. | 837 // Eliminate the test if it can be performed successfully at compile time. |
| 824 if ((node->left() != NULL) && | 838 if ((node->left() != NULL) && |
| 825 node->left()->IsLiteralNode() && | 839 node->left()->IsLiteralNode() && |
| 826 type.IsInstantiated()) { | 840 type.IsInstantiated()) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 837 if (literal_value.IsInstanceOf(type, TypeArguments::Handle(), NULL)) { | 851 if (literal_value.IsInstanceOf(type, TypeArguments::Handle(), NULL)) { |
| 838 result = new ConstantInstr(negate_result ? bool_false : bool_true); | 852 result = new ConstantInstr(negate_result ? bool_false : bool_true); |
| 839 } else { | 853 } else { |
| 840 result = new ConstantInstr(negate_result ? bool_true : bool_false); | 854 result = new ConstantInstr(negate_result ? bool_true : bool_false); |
| 841 } | 855 } |
| 842 } | 856 } |
| 843 ReturnDefinition(result); | 857 ReturnDefinition(result); |
| 844 return; | 858 return; |
| 845 } | 859 } |
| 846 | 860 |
| 847 ValueGraphVisitor for_left_value(owner(), temp_index()); | 861 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); |
| 848 node->left()->Visit(&for_left_value); | 862 node->left()->Visit(&for_left_value); |
| 849 Append(for_left_value); | 863 Append(for_left_value); |
| 850 Value* instantiator = NULL; | 864 Value* instantiator = NULL; |
| 851 Value* instantiator_type_arguments = NULL; | 865 Value* instantiator_type_arguments = NULL; |
| 852 if (type.IsInstantiated()) { | 866 if (type.IsInstantiated()) { |
| 853 instantiator = BuildNullValue(); | 867 instantiator = BuildNullValue(); |
| 854 instantiator_type_arguments = BuildNullValue(); | 868 instantiator_type_arguments = BuildNullValue(); |
| 855 } else { | 869 } else { |
| 856 BuildTypecheckArguments(node->token_pos(), | 870 BuildTypecheckArguments(node->token_pos(), |
| 857 &instantiator, | 871 &instantiator, |
| 858 &instantiator_type_arguments); | 872 &instantiator_type_arguments); |
| 859 } | 873 } |
| 860 // TODO(zerny): Remove this when issues 5216 and 5217 are fixed. | 874 // TODO(zerny): Remove this when issues 5216 and 5217 are fixed. |
| 861 InlineBailout("instance of"); | 875 InlineBailout("instance of"); |
| 862 InstanceOfInstr* instance_of = | 876 InstanceOfInstr* instance_of = |
| 863 new InstanceOfInstr(node->token_pos(), | 877 new InstanceOfInstr(node->token_pos(), |
| 864 for_left_value.value(), | 878 for_left_value.value(), |
| 865 instantiator, | 879 instantiator, |
| 866 instantiator_type_arguments, | 880 instantiator_type_arguments, |
| 867 node->right()->AsTypeNode()->type(), | 881 node->right()->AsTypeNode()->type(), |
| 868 (node->kind() == Token::kISNOT)); | 882 (node->kind() == Token::kISNOT)); |
| 869 ReturnDefinition(instance_of); | 883 ReturnDefinition(instance_of); |
| 870 } | 884 } |
| 871 | 885 |
| 872 | 886 |
| 873 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { | 887 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { |
| 874 ASSERT(Token::IsTypeCastOperator(node->kind())); | 888 ASSERT(Token::IsTypeCastOperator(node->kind())); |
| 875 const AbstractType& type = node->right()->AsTypeNode()->type(); | 889 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 876 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. | 890 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. |
| 877 ValueGraphVisitor for_value(owner(), temp_index()); | 891 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); |
| 878 node->left()->Visit(&for_value); | 892 node->left()->Visit(&for_value); |
| 879 Append(for_value); | 893 Append(for_value); |
| 880 const String& dst_name = String::ZoneHandle( | 894 const String& dst_name = String::ZoneHandle( |
| 881 Symbols::New(Exceptions::kCastErrorDstName)); | 895 Symbols::New(Exceptions::kCastErrorDstName)); |
| 882 ReturnValue(BuildAssignableValue(node->token_pos(), | 896 ReturnValue(BuildAssignableValue(node->token_pos(), |
| 883 for_value.value(), | 897 for_value.value(), |
| 884 type, | 898 type, |
| 885 dst_name)); | 899 dst_name)); |
| 886 } | 900 } |
| 887 | 901 |
| 888 | 902 |
| 889 // <Expression> :: Comparison { kind: Token::Kind | 903 // <Expression> :: Comparison { kind: Token::Kind |
| 890 // left: <Expression> | 904 // left: <Expression> |
| 891 // right: <Expression> } | 905 // right: <Expression> } |
| 892 // TODO(srdjan): Implement new equality. | 906 // TODO(srdjan): Implement new equality. |
| 893 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { | 907 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { |
| 894 if (Token::IsTypeTestOperator(node->kind())) { | 908 if (Token::IsTypeTestOperator(node->kind())) { |
| 895 BuildTypeTest(node); | 909 BuildTypeTest(node); |
| 896 return; | 910 return; |
| 897 } | 911 } |
| 898 if (Token::IsTypeCastOperator(node->kind())) { | 912 if (Token::IsTypeCastOperator(node->kind())) { |
| 899 BuildTypeCast(node); | 913 BuildTypeCast(node); |
| 900 return; | 914 return; |
| 901 } | 915 } |
| 902 if ((node->kind() == Token::kEQ_STRICT) || | 916 if ((node->kind() == Token::kEQ_STRICT) || |
| 903 (node->kind() == Token::kNE_STRICT)) { | 917 (node->kind() == Token::kNE_STRICT)) { |
| 904 ValueGraphVisitor for_left_value(owner(), temp_index()); | 918 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); |
| 905 node->left()->Visit(&for_left_value); | 919 node->left()->Visit(&for_left_value); |
| 906 Append(for_left_value); | 920 Append(for_left_value); |
| 907 ValueGraphVisitor for_right_value(owner(), temp_index()); | 921 ValueGraphVisitor for_right_value(owner(), temp_index(), loop_depth()); |
| 908 node->right()->Visit(&for_right_value); | 922 node->right()->Visit(&for_right_value); |
| 909 Append(for_right_value); | 923 Append(for_right_value); |
| 910 StrictCompareInstr* comp = new StrictCompareInstr( | 924 StrictCompareInstr* comp = new StrictCompareInstr( |
| 911 node->kind(), for_left_value.value(), for_right_value.value()); | 925 node->kind(), for_left_value.value(), for_right_value.value()); |
| 912 ReturnDefinition(comp); | 926 ReturnDefinition(comp); |
| 913 return; | 927 return; |
| 914 } | 928 } |
| 915 | 929 |
| 916 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { | 930 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { |
| 917 ValueGraphVisitor for_left_value(owner(), temp_index()); | 931 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); |
| 918 node->left()->Visit(&for_left_value); | 932 node->left()->Visit(&for_left_value); |
| 919 Append(for_left_value); | 933 Append(for_left_value); |
| 920 ValueGraphVisitor for_right_value(owner(), temp_index()); | 934 ValueGraphVisitor for_right_value(owner(), temp_index(), loop_depth()); |
| 921 node->right()->Visit(&for_right_value); | 935 node->right()->Visit(&for_right_value); |
| 922 Append(for_right_value); | 936 Append(for_right_value); |
| 923 if (FLAG_enable_type_checks) { | 937 if (FLAG_enable_type_checks) { |
| 924 EqualityCompareInstr* comp = new EqualityCompareInstr( | 938 EqualityCompareInstr* comp = new EqualityCompareInstr( |
| 925 node->token_pos(), | 939 node->token_pos(), |
| 926 Token::kEQ, | 940 Token::kEQ, |
| 927 for_left_value.value(), | 941 for_left_value.value(), |
| 928 for_right_value.value()); | 942 for_right_value.value()); |
| 929 if (node->kind() == Token::kEQ) { | 943 if (node->kind() == Token::kEQ) { |
| 930 ReturnDefinition(comp); | 944 ReturnDefinition(comp); |
| 931 } else { | 945 } else { |
| 932 Value* eq_result = Bind(comp); | 946 Value* eq_result = Bind(comp); |
| 933 eq_result = Bind(new AssertBooleanInstr(node->token_pos(), eq_result)); | 947 eq_result = Bind(new AssertBooleanInstr(node->token_pos(), eq_result)); |
| 934 ReturnDefinition(new BooleanNegateInstr(eq_result)); | 948 ReturnDefinition(new BooleanNegateInstr(eq_result)); |
| 935 } | 949 } |
| 936 } else { | 950 } else { |
| 937 EqualityCompareInstr* comp = new EqualityCompareInstr( | 951 EqualityCompareInstr* comp = new EqualityCompareInstr( |
| 938 node->token_pos(), | 952 node->token_pos(), |
| 939 node->kind(), | 953 node->kind(), |
| 940 for_left_value.value(), | 954 for_left_value.value(), |
| 941 for_right_value.value()); | 955 for_right_value.value()); |
| 942 ReturnDefinition(comp); | 956 ReturnDefinition(comp); |
| 943 } | 957 } |
| 944 return; | 958 return; |
| 945 } | 959 } |
| 946 | 960 |
| 947 ValueGraphVisitor for_left_value(owner(), temp_index()); | 961 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); |
| 948 node->left()->Visit(&for_left_value); | 962 node->left()->Visit(&for_left_value); |
| 949 Append(for_left_value); | 963 Append(for_left_value); |
| 950 ValueGraphVisitor for_right_value(owner(), temp_index()); | 964 ValueGraphVisitor for_right_value(owner(), temp_index(), loop_depth()); |
| 951 node->right()->Visit(&for_right_value); | 965 node->right()->Visit(&for_right_value); |
| 952 Append(for_right_value); | 966 Append(for_right_value); |
| 953 RelationalOpInstr* comp = new RelationalOpInstr(node->token_pos(), | 967 RelationalOpInstr* comp = new RelationalOpInstr(node->token_pos(), |
| 954 node->kind(), | 968 node->kind(), |
| 955 for_left_value.value(), | 969 for_left_value.value(), |
| 956 for_right_value.value()); | 970 for_right_value.value()); |
| 957 ReturnDefinition(comp); | 971 ReturnDefinition(comp); |
| 958 } | 972 } |
| 959 | 973 |
| 960 | 974 |
| 961 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { | 975 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { |
| 962 // "!" cannot be overloaded, therefore do not call operator. | 976 // "!" cannot be overloaded, therefore do not call operator. |
| 963 if (node->kind() == Token::kNOT) { | 977 if (node->kind() == Token::kNOT) { |
| 964 ValueGraphVisitor for_value(owner(), temp_index()); | 978 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); |
| 965 node->operand()->Visit(&for_value); | 979 node->operand()->Visit(&for_value); |
| 966 Append(for_value); | 980 Append(for_value); |
| 967 Value* value = for_value.value(); | 981 Value* value = for_value.value(); |
| 968 if (FLAG_enable_type_checks) { | 982 if (FLAG_enable_type_checks) { |
| 969 value = | 983 value = |
| 970 Bind(new AssertBooleanInstr(node->operand()->token_pos(), value)); | 984 Bind(new AssertBooleanInstr(node->operand()->token_pos(), value)); |
| 971 } | 985 } |
| 972 BooleanNegateInstr* negate = new BooleanNegateInstr(value); | 986 BooleanNegateInstr* negate = new BooleanNegateInstr(value); |
| 973 ReturnDefinition(negate); | 987 ReturnDefinition(negate); |
| 974 return; | 988 return; |
| 975 } | 989 } |
| 976 | 990 |
| 977 ValueGraphVisitor for_value(owner(), temp_index()); | 991 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); |
| 978 node->operand()->Visit(&for_value); | 992 node->operand()->Visit(&for_value); |
| 979 Append(for_value); | 993 Append(for_value); |
| 980 PushArgumentInstr* push_value = PushArgument(for_value.value()); | 994 PushArgumentInstr* push_value = PushArgument(for_value.value()); |
| 981 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 995 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 982 new ZoneGrowableArray<PushArgumentInstr*>(1); | 996 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 983 arguments->Add(push_value); | 997 arguments->Add(push_value); |
| 984 InstanceCallInstr* call = | 998 InstanceCallInstr* call = |
| 985 new InstanceCallInstr(node->token_pos(), | 999 new InstanceCallInstr(node->token_pos(), |
| 986 String::ZoneHandle( | 1000 String::ZoneHandle( |
| 987 Symbols::New(Token::Str(node->kind()))), | 1001 Symbols::New(Token::Str(node->kind()))), |
| 988 node->kind(), | 1002 node->kind(), |
| 989 arguments, | 1003 arguments, |
| 990 Array::ZoneHandle(), | 1004 Array::ZoneHandle(), |
| 991 1); | 1005 1); |
| 992 ReturnDefinition(call); | 1006 ReturnDefinition(call); |
| 993 } | 1007 } |
| 994 | 1008 |
| 995 | 1009 |
| 996 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 1010 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| 997 TestGraphVisitor for_test(owner(), | 1011 TestGraphVisitor for_test(owner(), |
| 998 temp_index(), | 1012 temp_index(), |
| 1013 loop_depth(), |
| 999 node->condition()->token_pos()); | 1014 node->condition()->token_pos()); |
| 1000 node->condition()->Visit(&for_test); | 1015 node->condition()->Visit(&for_test); |
| 1001 | 1016 |
| 1002 // Translate the subexpressions for their effects. | 1017 // Translate the subexpressions for their effects. |
| 1003 EffectGraphVisitor for_true(owner(), temp_index()); | 1018 EffectGraphVisitor for_true(owner(), temp_index(), loop_depth()); |
| 1004 node->true_expr()->Visit(&for_true); | 1019 node->true_expr()->Visit(&for_true); |
| 1005 EffectGraphVisitor for_false(owner(), temp_index()); | 1020 EffectGraphVisitor for_false(owner(), temp_index(), loop_depth()); |
| 1006 node->false_expr()->Visit(&for_false); | 1021 node->false_expr()->Visit(&for_false); |
| 1007 | 1022 |
| 1008 Join(for_test, for_true, for_false); | 1023 Join(for_test, for_true, for_false); |
| 1009 } | 1024 } |
| 1010 | 1025 |
| 1011 | 1026 |
| 1012 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 1027 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| 1013 TestGraphVisitor for_test(owner(), | 1028 TestGraphVisitor for_test(owner(), |
| 1014 temp_index(), | 1029 temp_index(), |
| 1030 loop_depth(), |
| 1015 node->condition()->token_pos()); | 1031 node->condition()->token_pos()); |
| 1016 node->condition()->Visit(&for_test); | 1032 node->condition()->Visit(&for_test); |
| 1017 | 1033 |
| 1018 ValueGraphVisitor for_true(owner(), temp_index()); | 1034 ValueGraphVisitor for_true(owner(), temp_index(), loop_depth()); |
| 1019 node->true_expr()->Visit(&for_true); | 1035 node->true_expr()->Visit(&for_true); |
| 1020 ASSERT(for_true.is_open()); | 1036 ASSERT(for_true.is_open()); |
| 1021 for_true.Do(BuildStoreExprTemp(for_true.value())); | 1037 for_true.Do(BuildStoreExprTemp(for_true.value())); |
| 1022 | 1038 |
| 1023 ValueGraphVisitor for_false(owner(), temp_index()); | 1039 ValueGraphVisitor for_false(owner(), temp_index(), loop_depth()); |
| 1024 node->false_expr()->Visit(&for_false); | 1040 node->false_expr()->Visit(&for_false); |
| 1025 ASSERT(for_false.is_open()); | 1041 ASSERT(for_false.is_open()); |
| 1026 for_false.Do(BuildStoreExprTemp(for_false.value())); | 1042 for_false.Do(BuildStoreExprTemp(for_false.value())); |
| 1027 | 1043 |
| 1028 Join(for_test, for_true, for_false); | 1044 Join(for_test, for_true, for_false); |
| 1029 ReturnDefinition(BuildLoadExprTemp()); | 1045 ReturnDefinition(BuildLoadExprTemp()); |
| 1030 } | 1046 } |
| 1031 | 1047 |
| 1032 | 1048 |
| 1033 // <Statement> ::= If { condition: <Expression> | 1049 // <Statement> ::= If { condition: <Expression> |
| 1034 // true_branch: <Sequence> | 1050 // true_branch: <Sequence> |
| 1035 // false_branch: <Sequence> } | 1051 // false_branch: <Sequence> } |
| 1036 void EffectGraphVisitor::VisitIfNode(IfNode* node) { | 1052 void EffectGraphVisitor::VisitIfNode(IfNode* node) { |
| 1037 TestGraphVisitor for_test(owner(), | 1053 TestGraphVisitor for_test(owner(), |
| 1038 temp_index(), | 1054 temp_index(), |
| 1055 loop_depth(), |
| 1039 node->condition()->token_pos()); | 1056 node->condition()->token_pos()); |
| 1040 node->condition()->Visit(&for_test); | 1057 node->condition()->Visit(&for_test); |
| 1041 | 1058 |
| 1042 EffectGraphVisitor for_true(owner(), temp_index()); | 1059 EffectGraphVisitor for_true(owner(), temp_index(), loop_depth()); |
| 1043 EffectGraphVisitor for_false(owner(), temp_index()); | 1060 EffectGraphVisitor for_false(owner(), temp_index(), loop_depth()); |
| 1044 | 1061 |
| 1045 node->true_branch()->Visit(&for_true); | 1062 node->true_branch()->Visit(&for_true); |
| 1046 // The for_false graph fragment will be empty (default graph fragment) if | 1063 // The for_false graph fragment will be empty (default graph fragment) if |
| 1047 // we do not call Visit. | 1064 // we do not call Visit. |
| 1048 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false); | 1065 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false); |
| 1049 Join(for_test, for_true, for_false); | 1066 Join(for_test, for_true, for_false); |
| 1050 } | 1067 } |
| 1051 | 1068 |
| 1052 | 1069 |
| 1053 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) { | 1070 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) { |
| 1054 EffectGraphVisitor switch_body(owner(), temp_index()); | 1071 EffectGraphVisitor switch_body(owner(), temp_index(), loop_depth()); |
| 1055 node->body()->Visit(&switch_body); | 1072 node->body()->Visit(&switch_body); |
| 1056 Append(switch_body); | 1073 Append(switch_body); |
| 1057 if ((node->label() != NULL) && (node->label()->join_for_break() != NULL)) { | 1074 if ((node->label() != NULL) && (node->label()->join_for_break() != NULL)) { |
| 1058 if (is_open()) Goto(node->label()->join_for_break()); | 1075 if (is_open()) Goto(node->label()->join_for_break()); |
| 1059 exit_ = node->label()->join_for_break(); | 1076 exit_ = node->label()->join_for_break(); |
| 1060 } | 1077 } |
| 1061 // No continue label allowed. | 1078 // No continue label allowed. |
| 1062 ASSERT((node->label() == NULL) || | 1079 ASSERT((node->label() == NULL) || |
| 1063 (node->label()->join_for_continue() == NULL)); | 1080 (node->label()->join_for_continue() == NULL)); |
| 1064 } | 1081 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1081 // g) case-statements-join | 1098 // g) case-statements-join |
| 1082 // h) [ case-statements ] -> exit-join | 1099 // h) [ case-statements ] -> exit-join |
| 1083 // i) exit-target -> exit-join | 1100 // i) exit-target -> exit-join |
| 1084 // j) exit-join | 1101 // j) exit-join |
| 1085 // | 1102 // |
| 1086 // Note: The specification of switch/case is under discussion and may change | 1103 // Note: The specification of switch/case is under discussion and may change |
| 1087 // drastically. | 1104 // drastically. |
| 1088 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { | 1105 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { |
| 1089 const intptr_t len = node->case_expressions()->length(); | 1106 const intptr_t len = node->case_expressions()->length(); |
| 1090 // Create case statements instructions. | 1107 // Create case statements instructions. |
| 1091 EffectGraphVisitor for_case_statements(owner(), temp_index()); | 1108 EffectGraphVisitor for_case_statements(owner(), temp_index(), loop_depth()); |
| 1092 // Compute start of statements fragment. | 1109 // Compute start of statements fragment. |
| 1093 JoinEntryInstr* statement_start = NULL; | 1110 JoinEntryInstr* statement_start = NULL; |
| 1094 if ((node->label() != NULL) && node->label()->is_continue_target()) { | 1111 if ((node->label() != NULL) && node->label()->is_continue_target()) { |
| 1095 // Since a labeled jump continue statement occur in a different case node, | 1112 // Since a labeled jump continue statement occur in a different case node, |
| 1096 // allocate JoinNode here and use it as statement start. | 1113 // allocate JoinNode here and use it as statement start. |
| 1097 statement_start = node->label()->join_for_continue(); | 1114 statement_start = node->label()->join_for_continue(); |
| 1098 if (statement_start == NULL) { | 1115 if (statement_start == NULL) { |
| 1099 statement_start = | 1116 statement_start = new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1100 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 1117 owner()->try_index(), |
| 1118 loop_depth()); |
| 1101 node->label()->set_join_for_continue(statement_start); | 1119 node->label()->set_join_for_continue(statement_start); |
| 1102 } | 1120 } |
| 1103 } else { | 1121 } else { |
| 1104 statement_start = | 1122 statement_start = new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1105 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 1123 owner()->try_index(), |
| 1124 loop_depth()); |
| 1106 } | 1125 } |
| 1107 node->statements()->Visit(&for_case_statements); | 1126 node->statements()->Visit(&for_case_statements); |
| 1108 Instruction* statement_exit = | 1127 Instruction* statement_exit = |
| 1109 AppendFragment(statement_start, for_case_statements); | 1128 AppendFragment(statement_start, for_case_statements); |
| 1110 if (is_open() && (len == 0)) { | 1129 if (is_open() && (len == 0)) { |
| 1111 ASSERT(node->contains_default()); | 1130 ASSERT(node->contains_default()); |
| 1112 // Default only case node. | 1131 // Default only case node. |
| 1113 Goto(statement_start); | 1132 Goto(statement_start); |
| 1114 exit_ = statement_exit; | 1133 exit_ = statement_exit; |
| 1115 return; | 1134 return; |
| 1116 } | 1135 } |
| 1117 | 1136 |
| 1118 // Generate instructions for all case expressions. | 1137 // Generate instructions for all case expressions. |
| 1119 TargetEntryInstr* next_target = NULL; | 1138 TargetEntryInstr* next_target = NULL; |
| 1120 for (intptr_t i = 0; i < len; i++) { | 1139 for (intptr_t i = 0; i < len; i++) { |
| 1121 AstNode* case_expr = node->case_expressions()->NodeAt(i); | 1140 AstNode* case_expr = node->case_expressions()->NodeAt(i); |
| 1122 TestGraphVisitor for_case_expression(owner(), | 1141 TestGraphVisitor for_case_expression(owner(), |
| 1123 temp_index(), | 1142 temp_index(), |
| 1143 loop_depth(), |
| 1124 case_expr->token_pos()); | 1144 case_expr->token_pos()); |
| 1125 case_expr->Visit(&for_case_expression); | 1145 case_expr->Visit(&for_case_expression); |
| 1126 if (i == 0) { | 1146 if (i == 0) { |
| 1127 // Append only the first one, everything else is connected from it. | 1147 // Append only the first one, everything else is connected from it. |
| 1128 Append(for_case_expression); | 1148 Append(for_case_expression); |
| 1129 } else { | 1149 } else { |
| 1130 ASSERT(next_target != NULL); | 1150 ASSERT(next_target != NULL); |
| 1131 AppendFragment(next_target, for_case_expression); | 1151 AppendFragment(next_target, for_case_expression); |
| 1132 } | 1152 } |
| 1133 for_case_expression.IfTrueGoto(statement_start); | 1153 for_case_expression.IfTrueGoto(statement_start); |
| 1134 next_target = for_case_expression.CreateFalseSuccessor()->AsTargetEntry(); | 1154 next_target = for_case_expression.CreateFalseSuccessor()->AsTargetEntry(); |
| 1135 } | 1155 } |
| 1136 | 1156 |
| 1137 // Once a test fragment has been added, this fragment is closed. | 1157 // Once a test fragment has been added, this fragment is closed. |
| 1138 ASSERT(!is_open()); | 1158 ASSERT(!is_open()); |
| 1139 | 1159 |
| 1140 Instruction* exit_instruction = NULL; | 1160 Instruction* exit_instruction = NULL; |
| 1141 // Handle last (or only) case: false goes to exit or to statement if this | 1161 // Handle last (or only) case: false goes to exit or to statement if this |
| 1142 // node contains default. | 1162 // node contains default. |
| 1143 if (len > 0) { | 1163 if (len > 0) { |
| 1144 ASSERT(next_target != NULL); | 1164 ASSERT(next_target != NULL); |
| 1145 if (node->contains_default()) { | 1165 if (node->contains_default()) { |
| 1146 // True and false go to statement start. | 1166 // True and false go to statement start. |
| 1147 next_target->Goto(statement_start); | 1167 next_target->Goto(statement_start); |
| 1148 exit_instruction = statement_exit; | 1168 exit_instruction = statement_exit; |
| 1149 } else { | 1169 } else { |
| 1150 if (statement_exit != NULL) { | 1170 if (statement_exit != NULL) { |
| 1151 JoinEntryInstr* join = new JoinEntryInstr(owner()->AllocateBlockId(), | 1171 JoinEntryInstr* join = new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1152 owner()->try_index()); | 1172 owner()->try_index(), |
| 1173 loop_depth()); |
| 1153 statement_exit->Goto(join); | 1174 statement_exit->Goto(join); |
| 1154 next_target->Goto(join); | 1175 next_target->Goto(join); |
| 1155 exit_instruction = join; | 1176 exit_instruction = join; |
| 1156 } else { | 1177 } else { |
| 1157 exit_instruction = next_target; | 1178 exit_instruction = next_target; |
| 1158 } | 1179 } |
| 1159 } | 1180 } |
| 1160 } else { | 1181 } else { |
| 1161 // A CaseNode without case expressions must contain default. | 1182 // A CaseNode without case expressions must contain default. |
| 1162 ASSERT(node->contains_default()); | 1183 ASSERT(node->contains_default()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1176 // a) loop-join | 1197 // a) loop-join |
| 1177 // b) [ test ] -> (body-entry-target, loop-exit-target) | 1198 // b) [ test ] -> (body-entry-target, loop-exit-target) |
| 1178 // c) body-entry-target | 1199 // c) body-entry-target |
| 1179 // d) [ body ] -> (continue-join) | 1200 // d) [ body ] -> (continue-join) |
| 1180 // e) continue-join -> (loop-join) | 1201 // e) continue-join -> (loop-join) |
| 1181 // f) loop-exit-target | 1202 // f) loop-exit-target |
| 1182 // g) break-join (optional) | 1203 // g) break-join (optional) |
| 1183 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { | 1204 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { |
| 1184 TestGraphVisitor for_test(owner(), | 1205 TestGraphVisitor for_test(owner(), |
| 1185 temp_index(), | 1206 temp_index(), |
| 1207 loop_depth() + 1, |
| 1186 node->condition()->token_pos()); | 1208 node->condition()->token_pos()); |
| 1187 node->condition()->Visit(&for_test); | 1209 node->condition()->Visit(&for_test); |
| 1188 ASSERT(!for_test.is_empty()); // Language spec. | 1210 ASSERT(!for_test.is_empty()); // Language spec. |
| 1189 | 1211 |
| 1190 EffectGraphVisitor for_body(owner(), temp_index()); | 1212 EffectGraphVisitor for_body(owner(), temp_index(), loop_depth() + 1); |
| 1191 for_body.AddInstruction( | 1213 for_body.AddInstruction( |
| 1192 new CheckStackOverflowInstr(node->token_pos())); | 1214 new CheckStackOverflowInstr(node->token_pos())); |
| 1193 node->body()->Visit(&for_body); | 1215 node->body()->Visit(&for_body); |
| 1194 | 1216 |
| 1195 // Labels are set after body traversal. | 1217 // Labels are set after body traversal. |
| 1196 SourceLabel* lbl = node->label(); | 1218 SourceLabel* lbl = node->label(); |
| 1197 ASSERT(lbl != NULL); | 1219 ASSERT(lbl != NULL); |
| 1198 JoinEntryInstr* join = lbl->join_for_continue(); | 1220 JoinEntryInstr* join = lbl->join_for_continue(); |
| 1199 if (join != NULL) { | 1221 if (join != NULL) { |
| 1200 if (for_body.is_open()) for_body.Goto(join); | 1222 if (for_body.is_open()) for_body.Goto(join); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1212 // The fragment is composed as follows: | 1234 // The fragment is composed as follows: |
| 1213 // a) body-entry-join | 1235 // a) body-entry-join |
| 1214 // b) [ body ] | 1236 // b) [ body ] |
| 1215 // c) test-entry (continue-join or body-exit-target) | 1237 // c) test-entry (continue-join or body-exit-target) |
| 1216 // d) [ test-entry ] -> (back-target, loop-exit-target) | 1238 // d) [ test-entry ] -> (back-target, loop-exit-target) |
| 1217 // e) back-target -> (body-entry-join) | 1239 // e) back-target -> (body-entry-join) |
| 1218 // f) loop-exit-target | 1240 // f) loop-exit-target |
| 1219 // g) break-join | 1241 // g) break-join |
| 1220 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { | 1242 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { |
| 1221 // Traverse body first in order to generate continue and break labels. | 1243 // Traverse body first in order to generate continue and break labels. |
| 1222 EffectGraphVisitor for_body(owner(), temp_index()); | 1244 EffectGraphVisitor for_body(owner(), temp_index(), loop_depth() + 1); |
| 1223 for_body.AddInstruction( | 1245 for_body.AddInstruction( |
| 1224 new CheckStackOverflowInstr(node->token_pos())); | 1246 new CheckStackOverflowInstr(node->token_pos())); |
| 1225 node->body()->Visit(&for_body); | 1247 node->body()->Visit(&for_body); |
| 1226 | 1248 |
| 1227 TestGraphVisitor for_test(owner(), | 1249 TestGraphVisitor for_test(owner(), |
| 1228 temp_index(), | 1250 temp_index(), |
| 1251 loop_depth() + 1, |
| 1229 node->condition()->token_pos()); | 1252 node->condition()->token_pos()); |
| 1230 node->condition()->Visit(&for_test); | 1253 node->condition()->Visit(&for_test); |
| 1231 ASSERT(is_open()); | 1254 ASSERT(is_open()); |
| 1232 | 1255 |
| 1233 // Tie do-while loop (test is after the body). | 1256 // Tie do-while loop (test is after the body). |
| 1234 JoinEntryInstr* body_entry_join = | 1257 JoinEntryInstr* body_entry_join = |
| 1235 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 1258 new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1259 owner()->try_index(), |
| 1260 loop_depth() + 1); |
| 1236 Goto(body_entry_join); | 1261 Goto(body_entry_join); |
| 1237 Instruction* body_exit = AppendFragment(body_entry_join, for_body); | 1262 Instruction* body_exit = AppendFragment(body_entry_join, for_body); |
| 1238 | 1263 |
| 1239 JoinEntryInstr* join = node->label()->join_for_continue(); | 1264 JoinEntryInstr* join = node->label()->join_for_continue(); |
| 1240 if ((body_exit != NULL) || (join != NULL)) { | 1265 if ((body_exit != NULL) || (join != NULL)) { |
| 1241 if (join == NULL) { | 1266 if (join == NULL) { |
| 1242 join = | 1267 join = new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1243 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 1268 owner()->try_index(), |
| 1269 loop_depth() + 1); |
| 1244 } | 1270 } |
| 1245 join->LinkTo(for_test.entry()); | 1271 join->LinkTo(for_test.entry()); |
| 1246 if (body_exit != NULL) { | 1272 if (body_exit != NULL) { |
| 1247 body_exit->Goto(join); | 1273 body_exit->Goto(join); |
| 1248 } | 1274 } |
| 1249 } | 1275 } |
| 1250 | 1276 |
| 1251 | 1277 |
| 1252 for_test.IfTrueGoto(body_entry_join); | 1278 for_test.IfTrueGoto(body_entry_join); |
| 1253 if (node->label()->join_for_break() == NULL) { | 1279 if (node->label()->join_for_break() == NULL) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1265 // a) [ initializer ] | 1291 // a) [ initializer ] |
| 1266 // b) loop-join | 1292 // b) loop-join |
| 1267 // c) [ test ] -> (body-entry-target, loop-exit-target) | 1293 // c) [ test ] -> (body-entry-target, loop-exit-target) |
| 1268 // d) body-entry-target | 1294 // d) body-entry-target |
| 1269 // e) [ body ] | 1295 // e) [ body ] |
| 1270 // f) continue-join (optional) | 1296 // f) continue-join (optional) |
| 1271 // g) [ increment ] -> (loop-join) | 1297 // g) [ increment ] -> (loop-join) |
| 1272 // h) loop-exit-target | 1298 // h) loop-exit-target |
| 1273 // i) break-join | 1299 // i) break-join |
| 1274 void EffectGraphVisitor::VisitForNode(ForNode* node) { | 1300 void EffectGraphVisitor::VisitForNode(ForNode* node) { |
| 1275 EffectGraphVisitor for_initializer(owner(), temp_index()); | 1301 EffectGraphVisitor for_initializer(owner(), temp_index(), loop_depth()); |
| 1276 node->initializer()->Visit(&for_initializer); | 1302 node->initializer()->Visit(&for_initializer); |
| 1277 Append(for_initializer); | 1303 Append(for_initializer); |
| 1278 ASSERT(is_open()); | 1304 ASSERT(is_open()); |
| 1279 | 1305 |
| 1280 // Compose body to set any jump labels. | 1306 // Compose body to set any jump labels. |
| 1281 EffectGraphVisitor for_body(owner(), temp_index()); | 1307 EffectGraphVisitor for_body(owner(), temp_index(), loop_depth() + 1); |
| 1282 for_body.AddInstruction( | 1308 for_body.AddInstruction( |
| 1283 new CheckStackOverflowInstr(node->token_pos())); | 1309 new CheckStackOverflowInstr(node->token_pos())); |
| 1284 node->body()->Visit(&for_body); | 1310 node->body()->Visit(&for_body); |
| 1285 | 1311 |
| 1286 // Join loop body, increment and compute their end instruction. | 1312 // Join loop body, increment and compute their end instruction. |
| 1287 ASSERT(!for_body.is_empty()); | 1313 ASSERT(!for_body.is_empty()); |
| 1288 Instruction* loop_increment_end = NULL; | 1314 Instruction* loop_increment_end = NULL; |
| 1289 EffectGraphVisitor for_increment(owner(), temp_index()); | 1315 EffectGraphVisitor for_increment(owner(), temp_index(), loop_depth() + 1); |
| 1290 node->increment()->Visit(&for_increment); | 1316 node->increment()->Visit(&for_increment); |
| 1291 JoinEntryInstr* join = node->label()->join_for_continue(); | 1317 JoinEntryInstr* join = node->label()->join_for_continue(); |
| 1292 if (join != NULL) { | 1318 if (join != NULL) { |
| 1293 // Insert the join between the body and increment. | 1319 // Insert the join between the body and increment. |
| 1294 if (for_body.is_open()) for_body.Goto(join); | 1320 if (for_body.is_open()) for_body.Goto(join); |
| 1295 loop_increment_end = AppendFragment(join, for_increment); | 1321 loop_increment_end = AppendFragment(join, for_increment); |
| 1296 ASSERT(loop_increment_end != NULL); | 1322 ASSERT(loop_increment_end != NULL); |
| 1297 } else if (for_body.is_open()) { | 1323 } else if (for_body.is_open()) { |
| 1298 // Do not insert an extra basic block. | 1324 // Do not insert an extra basic block. |
| 1299 for_body.Append(for_increment); | 1325 for_body.Append(for_increment); |
| 1300 loop_increment_end = for_body.exit(); | 1326 loop_increment_end = for_body.exit(); |
| 1301 // 'for_body' contains at least the stack check. | 1327 // 'for_body' contains at least the stack check. |
| 1302 ASSERT(loop_increment_end != NULL); | 1328 ASSERT(loop_increment_end != NULL); |
| 1303 } else { | 1329 } else { |
| 1304 loop_increment_end = NULL; | 1330 loop_increment_end = NULL; |
| 1305 } | 1331 } |
| 1306 | 1332 |
| 1307 // 'loop_increment_end' is NULL only if there is no join for continue and the | 1333 // 'loop_increment_end' is NULL only if there is no join for continue and the |
| 1308 // body is not open, i.e., no backward branch exists. | 1334 // body is not open, i.e., no backward branch exists. |
| 1309 if (loop_increment_end != NULL) { | 1335 if (loop_increment_end != NULL) { |
| 1310 JoinEntryInstr* loop_start = | 1336 JoinEntryInstr* loop_start = |
| 1311 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 1337 new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1338 owner()->try_index(), |
| 1339 loop_depth() + 1); |
| 1312 Goto(loop_start); | 1340 Goto(loop_start); |
| 1313 loop_increment_end->Goto(loop_start); | 1341 loop_increment_end->Goto(loop_start); |
| 1314 exit_ = loop_start; | 1342 exit_ = loop_start; |
| 1315 } | 1343 } |
| 1316 | 1344 |
| 1317 if (node->condition() == NULL) { | 1345 if (node->condition() == NULL) { |
| 1318 // Endless loop, no test. | 1346 // Endless loop, no test. |
| 1319 JoinEntryInstr* body_entry = | 1347 JoinEntryInstr* body_entry = |
| 1320 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 1348 new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1349 owner()->try_index(), |
| 1350 loop_depth() + 1); |
| 1321 AppendFragment(body_entry, for_body); | 1351 AppendFragment(body_entry, for_body); |
| 1322 Goto(body_entry); | 1352 Goto(body_entry); |
| 1323 if (node->label()->join_for_break() != NULL) { | 1353 if (node->label()->join_for_break() != NULL) { |
| 1324 // Control flow of ForLoop continues into join_for_break. | 1354 // Control flow of ForLoop continues into join_for_break. |
| 1325 exit_ = node->label()->join_for_break(); | 1355 exit_ = node->label()->join_for_break(); |
| 1326 } | 1356 } |
| 1327 } else { | 1357 } else { |
| 1328 TestGraphVisitor for_test(owner(), | 1358 TestGraphVisitor for_test(owner(), |
| 1329 temp_index(), | 1359 temp_index(), |
| 1360 loop_depth() + 1, |
| 1330 node->condition()->token_pos()); | 1361 node->condition()->token_pos()); |
| 1331 node->condition()->Visit(&for_test); | 1362 node->condition()->Visit(&for_test); |
| 1332 Append(for_test); | 1363 Append(for_test); |
| 1333 | 1364 |
| 1334 BlockEntryInstr* body_entry = for_test.CreateTrueSuccessor(); | 1365 BlockEntryInstr* body_entry = for_test.CreateTrueSuccessor(); |
| 1335 AppendFragment(body_entry, for_body); | 1366 AppendFragment(body_entry, for_body); |
| 1336 | 1367 |
| 1337 if (node->label()->join_for_break() == NULL) { | 1368 if (node->label()->join_for_break() == NULL) { |
| 1338 exit_ = for_test.CreateFalseSuccessor(); | 1369 exit_ = for_test.CreateFalseSuccessor(); |
| 1339 } else { | 1370 } else { |
| 1340 for_test.IfFalseGoto(node->label()->join_for_break()); | 1371 for_test.IfFalseGoto(node->label()->join_for_break()); |
| 1341 exit_ = node->label()->join_for_break(); | 1372 exit_ = node->label()->join_for_break(); |
| 1342 } | 1373 } |
| 1343 } | 1374 } |
| 1344 } | 1375 } |
| 1345 | 1376 |
| 1346 | 1377 |
| 1347 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { | 1378 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { |
| 1348 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { | 1379 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { |
| 1349 EffectGraphVisitor for_effect(owner(), temp_index()); | 1380 EffectGraphVisitor for_effect(owner(), temp_index(), loop_depth()); |
| 1350 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); | 1381 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
| 1351 Append(for_effect); | 1382 Append(for_effect); |
| 1352 if (!is_open()) return; | 1383 if (!is_open()) return; |
| 1353 } | 1384 } |
| 1354 | 1385 |
| 1355 // Unchain the context(s) up to the outer context level of the scope which | 1386 // Unchain the context(s) up to the outer context level of the scope which |
| 1356 // contains the destination label. | 1387 // contains the destination label. |
| 1357 SourceLabel* label = node->label(); | 1388 SourceLabel* label = node->label(); |
| 1358 ASSERT(label->owner() != NULL); | 1389 ASSERT(label->owner() != NULL); |
| 1359 int target_context_level = 0; | 1390 int target_context_level = 0; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1377 intptr_t current_context_level = owner()->context_level(); | 1408 intptr_t current_context_level = owner()->context_level(); |
| 1378 ASSERT(current_context_level >= target_context_level); | 1409 ASSERT(current_context_level >= target_context_level); |
| 1379 while (current_context_level-- > target_context_level) { | 1410 while (current_context_level-- > target_context_level) { |
| 1380 UnchainContext(); | 1411 UnchainContext(); |
| 1381 } | 1412 } |
| 1382 | 1413 |
| 1383 JoinEntryInstr* jump_target = NULL; | 1414 JoinEntryInstr* jump_target = NULL; |
| 1384 if (node->kind() == Token::kBREAK) { | 1415 if (node->kind() == Token::kBREAK) { |
| 1385 if (node->label()->join_for_break() == NULL) { | 1416 if (node->label()->join_for_break() == NULL) { |
| 1386 node->label()->set_join_for_break( | 1417 node->label()->set_join_for_break( |
| 1387 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index())); | 1418 new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1419 owner()->try_index(), |
| 1420 loop_depth() - 1)); // Breaks out of a loop. |
| 1388 } | 1421 } |
| 1389 jump_target = node->label()->join_for_break(); | 1422 jump_target = node->label()->join_for_break(); |
| 1390 } else { | 1423 } else { |
| 1391 if (node->label()->join_for_continue() == NULL) { | 1424 if (node->label()->join_for_continue() == NULL) { |
| 1392 node->label()->set_join_for_continue( | 1425 node->label()->set_join_for_continue( |
| 1393 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index())); | 1426 new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1427 owner()->try_index(), |
| 1428 loop_depth())); // Continue in same loop. |
| 1394 } | 1429 } |
| 1395 jump_target = node->label()->join_for_continue(); | 1430 jump_target = node->label()->join_for_continue(); |
| 1396 } | 1431 } |
| 1397 Goto(jump_target); | 1432 Goto(jump_target); |
| 1398 } | 1433 } |
| 1399 | 1434 |
| 1400 | 1435 |
| 1401 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { | 1436 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { |
| 1402 UNREACHABLE(); | 1437 UNREACHABLE(); |
| 1403 } | 1438 } |
| 1404 | 1439 |
| 1405 | 1440 |
| 1406 void EffectGraphVisitor::VisitArgumentDefinitionTestNode( | 1441 void EffectGraphVisitor::VisitArgumentDefinitionTestNode( |
| 1407 ArgumentDefinitionTestNode* node) { | 1442 ArgumentDefinitionTestNode* node) { |
| 1408 InlineBailout("EffectGraphVisitor::VisitArgumentDefinitionTestNode"); | 1443 InlineBailout("EffectGraphVisitor::VisitArgumentDefinitionTestNode"); |
| 1409 Definition* load = BuildLoadLocal(node->saved_arguments_descriptor()); | 1444 Definition* load = BuildLoadLocal(node->saved_arguments_descriptor()); |
| 1410 Value* arguments_descriptor = Bind(load); | 1445 Value* arguments_descriptor = Bind(load); |
| 1411 ArgumentDefinitionTestInstr* arg_def_test = | 1446 ArgumentDefinitionTestInstr* arg_def_test = |
| 1412 new ArgumentDefinitionTestInstr(node, arguments_descriptor); | 1447 new ArgumentDefinitionTestInstr(node, arguments_descriptor); |
| 1413 ReturnDefinition(arg_def_test); | 1448 ReturnDefinition(arg_def_test); |
| 1414 } | 1449 } |
| 1415 | 1450 |
| 1416 | 1451 |
| 1417 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { | 1452 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { |
| 1418 // Translate the array elements and collect their values. | 1453 // Translate the array elements and collect their values. |
| 1419 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1454 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1420 new ZoneGrowableArray<PushArgumentInstr*>(node->length()); | 1455 new ZoneGrowableArray<PushArgumentInstr*>(node->length()); |
| 1421 for (int i = 0; i < node->length(); ++i) { | 1456 for (int i = 0; i < node->length(); ++i) { |
| 1422 ValueGraphVisitor for_value(owner(), temp_index()); | 1457 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); |
| 1423 node->ElementAt(i)->Visit(&for_value); | 1458 node->ElementAt(i)->Visit(&for_value); |
| 1424 Append(for_value); | 1459 Append(for_value); |
| 1425 arguments->Add(PushArgument(for_value.value())); | 1460 arguments->Add(PushArgument(for_value.value())); |
| 1426 } | 1461 } |
| 1427 const AbstractTypeArguments& type_args = | 1462 const AbstractTypeArguments& type_args = |
| 1428 AbstractTypeArguments::ZoneHandle(node->type().arguments()); | 1463 AbstractTypeArguments::ZoneHandle(node->type().arguments()); |
| 1429 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), | 1464 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), |
| 1430 type_args); | 1465 type_args); |
| 1431 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), | 1466 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), |
| 1432 arguments, | 1467 arguments, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1446 if (function.context_scope() == ContextScope::null()) { | 1481 if (function.context_scope() == ContextScope::null()) { |
| 1447 // TODO(regis): Why are we not doing this in the parser? | 1482 // TODO(regis): Why are we not doing this in the parser? |
| 1448 const ContextScope& context_scope = ContextScope::ZoneHandle( | 1483 const ContextScope& context_scope = ContextScope::ZoneHandle( |
| 1449 node->scope()->PreserveOuterScope(owner()->context_level())); | 1484 node->scope()->PreserveOuterScope(owner()->context_level())); |
| 1450 ASSERT(!function.HasCode()); | 1485 ASSERT(!function.HasCode()); |
| 1451 ASSERT(function.context_scope() == ContextScope::null()); | 1486 ASSERT(function.context_scope() == ContextScope::null()); |
| 1452 function.set_context_scope(context_scope); | 1487 function.set_context_scope(context_scope); |
| 1453 } | 1488 } |
| 1454 receiver = BuildNullValue(); | 1489 receiver = BuildNullValue(); |
| 1455 } else if (function.IsImplicitInstanceClosureFunction()) { | 1490 } else if (function.IsImplicitInstanceClosureFunction()) { |
| 1456 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1491 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); |
| 1457 node->receiver()->Visit(&for_receiver); | 1492 node->receiver()->Visit(&for_receiver); |
| 1458 Append(for_receiver); | 1493 Append(for_receiver); |
| 1459 receiver = for_receiver.value(); | 1494 receiver = for_receiver.value(); |
| 1460 } else { | 1495 } else { |
| 1461 receiver = BuildNullValue(); | 1496 receiver = BuildNullValue(); |
| 1462 } | 1497 } |
| 1463 PushArgumentInstr* push_receiver = PushArgument(receiver); | 1498 PushArgumentInstr* push_receiver = PushArgument(receiver); |
| 1464 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1499 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1465 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1500 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1466 arguments->Add(push_receiver); | 1501 arguments->Add(push_receiver); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1481 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments); | 1516 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments); |
| 1482 arguments->Add(push_type_arguments); | 1517 arguments->Add(push_type_arguments); |
| 1483 ReturnDefinition(new CreateClosureInstr(node, arguments)); | 1518 ReturnDefinition(new CreateClosureInstr(node, arguments)); |
| 1484 } | 1519 } |
| 1485 | 1520 |
| 1486 | 1521 |
| 1487 void EffectGraphVisitor::TranslateArgumentList( | 1522 void EffectGraphVisitor::TranslateArgumentList( |
| 1488 const ArgumentListNode& node, | 1523 const ArgumentListNode& node, |
| 1489 ZoneGrowableArray<Value*>* values) { | 1524 ZoneGrowableArray<Value*>* values) { |
| 1490 for (intptr_t i = 0; i < node.length(); ++i) { | 1525 for (intptr_t i = 0; i < node.length(); ++i) { |
| 1491 ValueGraphVisitor for_argument(owner(), temp_index()); | 1526 ValueGraphVisitor for_argument(owner(), temp_index(), loop_depth()); |
| 1492 node.NodeAt(i)->Visit(&for_argument); | 1527 node.NodeAt(i)->Visit(&for_argument); |
| 1493 Append(for_argument); | 1528 Append(for_argument); |
| 1494 values->Add(for_argument.value()); | 1529 values->Add(for_argument.value()); |
| 1495 } | 1530 } |
| 1496 } | 1531 } |
| 1497 | 1532 |
| 1498 | 1533 |
| 1499 void EffectGraphVisitor::BuildPushArguments( | 1534 void EffectGraphVisitor::BuildPushArguments( |
| 1500 const ArgumentListNode& node, | 1535 const ArgumentListNode& node, |
| 1501 ZoneGrowableArray<PushArgumentInstr*>* values) { | 1536 ZoneGrowableArray<PushArgumentInstr*>* values) { |
| 1502 for (intptr_t i = 0; i < node.length(); ++i) { | 1537 for (intptr_t i = 0; i < node.length(); ++i) { |
| 1503 ValueGraphVisitor for_argument(owner(), temp_index()); | 1538 ValueGraphVisitor for_argument(owner(), temp_index(), loop_depth()); |
| 1504 node.NodeAt(i)->Visit(&for_argument); | 1539 node.NodeAt(i)->Visit(&for_argument); |
| 1505 Append(for_argument); | 1540 Append(for_argument); |
| 1506 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); | 1541 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); |
| 1507 values->Add(push_arg); | 1542 values->Add(push_arg); |
| 1508 } | 1543 } |
| 1509 } | 1544 } |
| 1510 | 1545 |
| 1511 | 1546 |
| 1512 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { | 1547 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { |
| 1513 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1548 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); |
| 1514 node->receiver()->Visit(&for_receiver); | 1549 node->receiver()->Visit(&for_receiver); |
| 1515 Append(for_receiver); | 1550 Append(for_receiver); |
| 1516 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 1551 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 1517 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1552 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1518 new ZoneGrowableArray<PushArgumentInstr*>( | 1553 new ZoneGrowableArray<PushArgumentInstr*>( |
| 1519 node->arguments()->length() + 1); | 1554 node->arguments()->length() + 1); |
| 1520 arguments->Add(push_receiver); | 1555 arguments->Add(push_receiver); |
| 1521 | 1556 |
| 1522 BuildPushArguments(*node->arguments(), arguments); | 1557 BuildPushArguments(*node->arguments(), arguments); |
| 1523 InstanceCallInstr* call = new InstanceCallInstr( | 1558 InstanceCallInstr* call = new InstanceCallInstr( |
| 1524 node->token_pos(), | 1559 node->token_pos(), |
| 1525 node->function_name(), Token::kILLEGAL, arguments, | 1560 node->function_name(), Token::kILLEGAL, arguments, |
| 1526 node->arguments()->names(), 1); | 1561 node->arguments()->names(), 1); |
| 1527 ReturnDefinition(call); | 1562 ReturnDefinition(call); |
| 1528 } | 1563 } |
| 1529 | 1564 |
| 1530 | 1565 |
| 1531 // <Expression> ::= StaticCall { function: Function | 1566 // <Expression> ::= StaticCall { function: Function |
| 1532 // arguments: <ArgumentList> } | 1567 // arguments: <ArgumentList> } |
| 1533 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { | 1568 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { |
| 1534 if (node->function().name() == Symbols::Identical()) { | 1569 if (node->function().name() == Symbols::Identical()) { |
| 1535 // Attempt to replace identical with strcit equal early on. | 1570 // Attempt to replace identical with strcit equal early on. |
| 1536 // TODO(hausner): Evaluate if this can happen at AST building time. | 1571 // TODO(hausner): Evaluate if this can happen at AST building time. |
| 1537 const Class& cls = Class::Handle(node->function().Owner()); | 1572 const Class& cls = Class::Handle(node->function().Owner()); |
| 1538 if (cls.IsTopLevel()) { | 1573 if (cls.IsTopLevel()) { |
| 1539 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 1574 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| 1540 if (cls.library() == core_lib.raw()) { | 1575 if (cls.library() == core_lib.raw()) { |
| 1541 ASSERT(node->arguments()->length() == 2); | 1576 ASSERT(node->arguments()->length() == 2); |
| 1542 ValueGraphVisitor for_left_value(owner(), temp_index()); | 1577 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); |
| 1543 node->arguments()->NodeAt(0)->Visit(&for_left_value); | 1578 node->arguments()->NodeAt(0)->Visit(&for_left_value); |
| 1544 Append(for_left_value); | 1579 Append(for_left_value); |
| 1545 ValueGraphVisitor for_right_value(owner(), temp_index()); | 1580 ValueGraphVisitor for_right_value(owner(), temp_index(), loop_depth()); |
| 1546 node->arguments()->NodeAt(1)->Visit(&for_right_value); | 1581 node->arguments()->NodeAt(1)->Visit(&for_right_value); |
| 1547 Append(for_right_value); | 1582 Append(for_right_value); |
| 1548 StrictCompareInstr* comp = new StrictCompareInstr( | 1583 StrictCompareInstr* comp = new StrictCompareInstr( |
| 1549 Token::kEQ_STRICT, | 1584 Token::kEQ_STRICT, |
| 1550 for_left_value.value(), | 1585 for_left_value.value(), |
| 1551 for_right_value.value()); | 1586 for_right_value.value()); |
| 1552 ReturnDefinition(comp); | 1587 ReturnDefinition(comp); |
| 1553 return; | 1588 return; |
| 1554 } | 1589 } |
| 1555 } | 1590 } |
| 1556 } | 1591 } |
| 1557 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1592 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1558 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 1593 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 1559 BuildPushArguments(*node->arguments(), arguments); | 1594 BuildPushArguments(*node->arguments(), arguments); |
| 1560 StaticCallInstr* call = | 1595 StaticCallInstr* call = |
| 1561 new StaticCallInstr(node->token_pos(), | 1596 new StaticCallInstr(node->token_pos(), |
| 1562 node->function(), | 1597 node->function(), |
| 1563 node->arguments()->names(), | 1598 node->arguments()->names(), |
| 1564 arguments); | 1599 arguments); |
| 1565 ReturnDefinition(call); | 1600 ReturnDefinition(call); |
| 1566 } | 1601 } |
| 1567 | 1602 |
| 1568 | 1603 |
| 1569 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall( | 1604 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall( |
| 1570 ClosureCallNode* node) { | 1605 ClosureCallNode* node) { |
| 1571 ValueGraphVisitor for_closure(owner(), temp_index()); | 1606 ValueGraphVisitor for_closure(owner(), temp_index(), loop_depth()); |
| 1572 node->closure()->Visit(&for_closure); | 1607 node->closure()->Visit(&for_closure); |
| 1573 Append(for_closure); | 1608 Append(for_closure); |
| 1574 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); | 1609 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); |
| 1575 | 1610 |
| 1576 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1611 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1577 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 1612 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 1578 arguments->Add(push_closure); | 1613 arguments->Add(push_closure); |
| 1579 BuildPushArguments(*node->arguments(), arguments); | 1614 BuildPushArguments(*node->arguments(), arguments); |
| 1580 | 1615 |
| 1581 // Save context around the call. | 1616 // Save context around the call. |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1732 Function& outer_function = | 1767 Function& outer_function = |
| 1733 Function::Handle(owner()->parsed_function().function().raw()); | 1768 Function::Handle(owner()->parsed_function().function().raw()); |
| 1734 while (outer_function.IsLocalFunction()) { | 1769 while (outer_function.IsLocalFunction()) { |
| 1735 outer_function = outer_function.parent_function(); | 1770 outer_function = outer_function.parent_function(); |
| 1736 } | 1771 } |
| 1737 if (outer_function.IsFactory()) { | 1772 if (outer_function.IsFactory()) { |
| 1738 return NULL; | 1773 return NULL; |
| 1739 } | 1774 } |
| 1740 | 1775 |
| 1741 ASSERT(owner()->parsed_function().instantiator() != NULL); | 1776 ASSERT(owner()->parsed_function().instantiator() != NULL); |
| 1742 ValueGraphVisitor for_instantiator(owner(), temp_index()); | 1777 ValueGraphVisitor for_instantiator(owner(), temp_index(), loop_depth()); |
| 1743 owner()->parsed_function().instantiator()->Visit(&for_instantiator); | 1778 owner()->parsed_function().instantiator()->Visit(&for_instantiator); |
| 1744 Append(for_instantiator); | 1779 Append(for_instantiator); |
| 1745 return for_instantiator.value(); | 1780 return for_instantiator.value(); |
| 1746 } | 1781 } |
| 1747 | 1782 |
| 1748 | 1783 |
| 1749 // 'expression_temp_var' may not be used inside this method if 'instantiator' | 1784 // 'expression_temp_var' may not be used inside this method if 'instantiator' |
| 1750 // is not NULL. | 1785 // is not NULL. |
| 1751 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( | 1786 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( |
| 1752 intptr_t token_pos, Value* instantiator) { | 1787 intptr_t token_pos, Value* instantiator) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1767 } | 1802 } |
| 1768 Function& outer_function = | 1803 Function& outer_function = |
| 1769 Function::Handle(owner()->parsed_function().function().raw()); | 1804 Function::Handle(owner()->parsed_function().function().raw()); |
| 1770 while (outer_function.IsLocalFunction()) { | 1805 while (outer_function.IsLocalFunction()) { |
| 1771 outer_function = outer_function.parent_function(); | 1806 outer_function = outer_function.parent_function(); |
| 1772 } | 1807 } |
| 1773 if (outer_function.IsFactory()) { | 1808 if (outer_function.IsFactory()) { |
| 1774 // No instantiator for factories. | 1809 // No instantiator for factories. |
| 1775 ASSERT(instantiator == NULL); | 1810 ASSERT(instantiator == NULL); |
| 1776 ASSERT(owner()->parsed_function().instantiator() != NULL); | 1811 ASSERT(owner()->parsed_function().instantiator() != NULL); |
| 1777 ValueGraphVisitor for_instantiator(owner(), temp_index()); | 1812 ValueGraphVisitor for_instantiator(owner(), temp_index(), loop_depth()); |
| 1778 owner()->parsed_function().instantiator()->Visit(&for_instantiator); | 1813 owner()->parsed_function().instantiator()->Visit(&for_instantiator); |
| 1779 Append(for_instantiator); | 1814 Append(for_instantiator); |
| 1780 return for_instantiator.value(); | 1815 return for_instantiator.value(); |
| 1781 } | 1816 } |
| 1782 if (instantiator == NULL) { | 1817 if (instantiator == NULL) { |
| 1783 instantiator = BuildInstantiator(); | 1818 instantiator = BuildInstantiator(); |
| 1784 } | 1819 } |
| 1785 // The instantiator is the receiver of the caller, which is not a factory. | 1820 // The instantiator is the receiver of the caller, which is not a factory. |
| 1786 // The receiver cannot be null; extract its AbstractTypeArguments object. | 1821 // The receiver cannot be null; extract its AbstractTypeArguments object. |
| 1787 // Note that in the factory case, the instantiator is the first parameter | 1822 // Note that in the factory case, the instantiator is the first parameter |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1915 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); | 1950 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); |
| 1916 BuildConstructorCall(node, push_allocated_value); | 1951 BuildConstructorCall(node, push_allocated_value); |
| 1917 Definition* load_allocated = BuildLoadLocal( | 1952 Definition* load_allocated = BuildLoadLocal( |
| 1918 node->allocated_object_var()); | 1953 node->allocated_object_var()); |
| 1919 allocated_value = Bind(load_allocated); | 1954 allocated_value = Bind(load_allocated); |
| 1920 ReturnValue(allocated_value); | 1955 ReturnValue(allocated_value); |
| 1921 } | 1956 } |
| 1922 | 1957 |
| 1923 | 1958 |
| 1924 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { | 1959 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { |
| 1925 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1960 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); |
| 1926 node->receiver()->Visit(&for_receiver); | 1961 node->receiver()->Visit(&for_receiver); |
| 1927 Append(for_receiver); | 1962 Append(for_receiver); |
| 1928 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 1963 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 1929 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1964 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1930 new ZoneGrowableArray<PushArgumentInstr*>(1); | 1965 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 1931 arguments->Add(push_receiver); | 1966 arguments->Add(push_receiver); |
| 1932 const String& name = | 1967 const String& name = |
| 1933 String::ZoneHandle(Field::GetterSymbol(node->field_name())); | 1968 String::ZoneHandle(Field::GetterSymbol(node->field_name())); |
| 1934 InstanceCallInstr* call = new InstanceCallInstr( | 1969 InstanceCallInstr* call = new InstanceCallInstr( |
| 1935 node->token_pos(), name, Token::kGET, | 1970 node->token_pos(), name, Token::kGET, |
| 1936 arguments, Array::ZoneHandle(), 1); | 1971 arguments, Array::ZoneHandle(), 1); |
| 1937 ReturnDefinition(call); | 1972 ReturnDefinition(call); |
| 1938 } | 1973 } |
| 1939 | 1974 |
| 1940 | 1975 |
| 1941 void EffectGraphVisitor::BuildInstanceSetterArguments( | 1976 void EffectGraphVisitor::BuildInstanceSetterArguments( |
| 1942 InstanceSetterNode* node, | 1977 InstanceSetterNode* node, |
| 1943 ZoneGrowableArray<PushArgumentInstr*>* arguments, | 1978 ZoneGrowableArray<PushArgumentInstr*>* arguments, |
| 1944 bool result_is_needed) { | 1979 bool result_is_needed) { |
| 1945 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1980 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); |
| 1946 node->receiver()->Visit(&for_receiver); | 1981 node->receiver()->Visit(&for_receiver); |
| 1947 Append(for_receiver); | 1982 Append(for_receiver); |
| 1948 arguments->Add(PushArgument(for_receiver.value())); | 1983 arguments->Add(PushArgument(for_receiver.value())); |
| 1949 | 1984 |
| 1950 ValueGraphVisitor for_value(owner(), temp_index()); | 1985 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); |
| 1951 node->value()->Visit(&for_value); | 1986 node->value()->Visit(&for_value); |
| 1952 Append(for_value); | 1987 Append(for_value); |
| 1953 | 1988 |
| 1954 Value* value = NULL; | 1989 Value* value = NULL; |
| 1955 if (result_is_needed) { | 1990 if (result_is_needed) { |
| 1956 value = Bind(BuildStoreExprTemp(for_value.value())); | 1991 value = Bind(BuildStoreExprTemp(for_value.value())); |
| 1957 } else { | 1992 } else { |
| 1958 value = for_value.value(); | 1993 value = for_value.value(); |
| 1959 } | 1994 } |
| 1960 arguments->Add(PushArgument(value)); | 1995 arguments->Add(PushArgument(value)); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1998 String::Handle(Field::GetterName(node->field_name())); | 2033 String::Handle(Field::GetterName(node->field_name())); |
| 1999 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2034 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2000 new ZoneGrowableArray<PushArgumentInstr*>(); | 2035 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 2001 Function& getter_function = Function::ZoneHandle(); | 2036 Function& getter_function = Function::ZoneHandle(); |
| 2002 if (node->is_super_getter()) { | 2037 if (node->is_super_getter()) { |
| 2003 // Statically resolved instance getter, i.e. "super getter". | 2038 // Statically resolved instance getter, i.e. "super getter". |
| 2004 getter_function = | 2039 getter_function = |
| 2005 Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); | 2040 Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); |
| 2006 ASSERT(!getter_function.IsNull()); | 2041 ASSERT(!getter_function.IsNull()); |
| 2007 ASSERT(node->receiver() != NULL); | 2042 ASSERT(node->receiver() != NULL); |
| 2008 ValueGraphVisitor receiver_value(owner(), temp_index()); | 2043 ValueGraphVisitor receiver_value(owner(), temp_index(), loop_depth()); |
| 2009 node->receiver()->Visit(&receiver_value); | 2044 node->receiver()->Visit(&receiver_value); |
| 2010 Append(receiver_value); | 2045 Append(receiver_value); |
| 2011 arguments->Add(PushArgument(receiver_value.value())); | 2046 arguments->Add(PushArgument(receiver_value.value())); |
| 2012 } else { | 2047 } else { |
| 2013 getter_function = node->cls().LookupStaticFunction(getter_name); | 2048 getter_function = node->cls().LookupStaticFunction(getter_name); |
| 2014 if (getter_function.IsNull()) { | 2049 if (getter_function.IsNull()) { |
| 2015 // When the parser encounters a reference to a static field materialized | 2050 // When the parser encounters a reference to a static field materialized |
| 2016 // only by a static setter, but no corresponding static getter, it creates | 2051 // only by a static setter, but no corresponding static getter, it creates |
| 2017 // a StaticGetterNode ast node referring to the non-existing static getter | 2052 // a StaticGetterNode ast node referring to the non-existing static getter |
| 2018 // for the case this field reference appears in a left hand side | 2053 // for the case this field reference appears in a left hand side |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2066 const Function& setter_function = | 2101 const Function& setter_function = |
| 2067 Function::ZoneHandle(is_super_setter | 2102 Function::ZoneHandle(is_super_setter |
| 2068 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name) | 2103 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name) |
| 2069 : node->cls().LookupStaticFunction(setter_name)); | 2104 : node->cls().LookupStaticFunction(setter_name)); |
| 2070 ASSERT(!setter_function.IsNull()); | 2105 ASSERT(!setter_function.IsNull()); |
| 2071 | 2106 |
| 2072 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2107 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2073 new ZoneGrowableArray<PushArgumentInstr*>(1); | 2108 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 2074 if (is_super_setter) { | 2109 if (is_super_setter) { |
| 2075 // Add receiver of instance getter. | 2110 // Add receiver of instance getter. |
| 2076 ValueGraphVisitor for_receiver(owner(), temp_index()); | 2111 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); |
| 2077 node->receiver()->Visit(&for_receiver); | 2112 node->receiver()->Visit(&for_receiver); |
| 2078 Append(for_receiver); | 2113 Append(for_receiver); |
| 2079 arguments->Add(PushArgument(for_receiver.value())); | 2114 arguments->Add(PushArgument(for_receiver.value())); |
| 2080 } | 2115 } |
| 2081 ValueGraphVisitor for_value(owner(), temp_index()); | 2116 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); |
| 2082 node->value()->Visit(&for_value); | 2117 node->value()->Visit(&for_value); |
| 2083 Append(for_value); | 2118 Append(for_value); |
| 2084 Value* value = NULL; | 2119 Value* value = NULL; |
| 2085 if (result_is_needed) { | 2120 if (result_is_needed) { |
| 2086 value = Bind(BuildStoreExprTemp(for_value.value())); | 2121 value = Bind(BuildStoreExprTemp(for_value.value())); |
| 2087 } else { | 2122 } else { |
| 2088 value = for_value.value(); | 2123 value = for_value.value(); |
| 2089 } | 2124 } |
| 2090 arguments->Add(PushArgument(value)); | 2125 arguments->Add(PushArgument(value)); |
| 2091 | 2126 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2121 | 2156 |
| 2122 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { | 2157 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { |
| 2123 // PrimaryNodes are temporary during parsing. | 2158 // PrimaryNodes are temporary during parsing. |
| 2124 UNREACHABLE(); | 2159 UNREACHABLE(); |
| 2125 } | 2160 } |
| 2126 | 2161 |
| 2127 | 2162 |
| 2128 // <Expression> ::= LoadLocal { local: LocalVariable } | 2163 // <Expression> ::= LoadLocal { local: LocalVariable } |
| 2129 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { | 2164 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| 2130 if (node->HasPseudo()) { | 2165 if (node->HasPseudo()) { |
| 2131 EffectGraphVisitor for_pseudo(owner(), temp_index()); | 2166 EffectGraphVisitor for_pseudo(owner(), temp_index(), loop_depth()); |
| 2132 node->pseudo()->Visit(&for_pseudo); | 2167 node->pseudo()->Visit(&for_pseudo); |
| 2133 Append(for_pseudo); | 2168 Append(for_pseudo); |
| 2134 } | 2169 } |
| 2135 } | 2170 } |
| 2136 | 2171 |
| 2137 | 2172 |
| 2138 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { | 2173 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| 2139 EffectGraphVisitor::VisitLoadLocalNode(node); | 2174 EffectGraphVisitor::VisitLoadLocalNode(node); |
| 2140 Definition* load = BuildLoadLocal(node->local()); | 2175 Definition* load = BuildLoadLocal(node->local()); |
| 2141 ReturnDefinition(load); | 2176 ReturnDefinition(load); |
| 2142 } | 2177 } |
| 2143 | 2178 |
| 2144 | 2179 |
| 2145 // <Expression> ::= StoreLocal { local: LocalVariable | 2180 // <Expression> ::= StoreLocal { local: LocalVariable |
| 2146 // value: <Expression> } | 2181 // value: <Expression> } |
| 2147 void EffectGraphVisitor::HandleStoreLocal(StoreLocalNode* node, | 2182 void EffectGraphVisitor::HandleStoreLocal(StoreLocalNode* node, |
| 2148 bool result_is_needed) { | 2183 bool result_is_needed) { |
| 2149 ValueGraphVisitor for_value(owner(), temp_index()); | 2184 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); |
| 2150 node->value()->Visit(&for_value); | 2185 node->value()->Visit(&for_value); |
| 2151 Append(for_value); | 2186 Append(for_value); |
| 2152 Value* store_value = for_value.value(); | 2187 Value* store_value = for_value.value(); |
| 2153 if (FLAG_enable_type_checks) { | 2188 if (FLAG_enable_type_checks) { |
| 2154 store_value = BuildAssignableValue(node->value()->token_pos(), | 2189 store_value = BuildAssignableValue(node->value()->token_pos(), |
| 2155 store_value, | 2190 store_value, |
| 2156 node->local().type(), | 2191 node->local().type(), |
| 2157 node->local().name()); | 2192 node->local().name()); |
| 2158 } | 2193 } |
| 2159 Definition* store = BuildStoreLocal(node->local(), | 2194 Definition* store = BuildStoreLocal(node->local(), |
| 2160 store_value, | 2195 store_value, |
| 2161 result_is_needed); | 2196 result_is_needed); |
| 2162 ReturnDefinition(store); | 2197 ReturnDefinition(store); |
| 2163 } | 2198 } |
| 2164 | 2199 |
| 2165 | 2200 |
| 2166 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { | 2201 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| 2167 HandleStoreLocal(node, kResultNotNeeded); | 2202 HandleStoreLocal(node, kResultNotNeeded); |
| 2168 } | 2203 } |
| 2169 | 2204 |
| 2170 | 2205 |
| 2171 void ValueGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { | 2206 void ValueGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| 2172 HandleStoreLocal(node, kResultNeeded); | 2207 HandleStoreLocal(node, kResultNeeded); |
| 2173 } | 2208 } |
| 2174 | 2209 |
| 2175 | 2210 |
| 2176 void EffectGraphVisitor::VisitLoadInstanceFieldNode( | 2211 void EffectGraphVisitor::VisitLoadInstanceFieldNode( |
| 2177 LoadInstanceFieldNode* node) { | 2212 LoadInstanceFieldNode* node) { |
| 2178 ValueGraphVisitor for_instance(owner(), temp_index()); | 2213 ValueGraphVisitor for_instance(owner(), temp_index(), loop_depth()); |
| 2179 node->instance()->Visit(&for_instance); | 2214 node->instance()->Visit(&for_instance); |
| 2180 Append(for_instance); | 2215 Append(for_instance); |
| 2181 LoadFieldInstr* load = new LoadFieldInstr( | 2216 LoadFieldInstr* load = new LoadFieldInstr( |
| 2182 for_instance.value(), | 2217 for_instance.value(), |
| 2183 node->field().Offset(), | 2218 node->field().Offset(), |
| 2184 AbstractType::ZoneHandle(node->field().type())); | 2219 AbstractType::ZoneHandle(node->field().type())); |
| 2185 ReturnDefinition(load); | 2220 ReturnDefinition(load); |
| 2186 } | 2221 } |
| 2187 | 2222 |
| 2188 | 2223 |
| 2189 void EffectGraphVisitor::VisitStoreInstanceFieldNode( | 2224 void EffectGraphVisitor::VisitStoreInstanceFieldNode( |
| 2190 StoreInstanceFieldNode* node) { | 2225 StoreInstanceFieldNode* node) { |
| 2191 ValueGraphVisitor for_instance(owner(), temp_index()); | 2226 ValueGraphVisitor for_instance(owner(), temp_index(), loop_depth()); |
| 2192 node->instance()->Visit(&for_instance); | 2227 node->instance()->Visit(&for_instance); |
| 2193 Append(for_instance); | 2228 Append(for_instance); |
| 2194 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); | 2229 ValueGraphVisitor for_value(owner(), for_instance.temp_index(), loop_depth()); |
| 2195 node->value()->Visit(&for_value); | 2230 node->value()->Visit(&for_value); |
| 2196 Append(for_value); | 2231 Append(for_value); |
| 2197 Value* store_value = for_value.value(); | 2232 Value* store_value = for_value.value(); |
| 2198 if (FLAG_enable_type_checks) { | 2233 if (FLAG_enable_type_checks) { |
| 2199 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 2234 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| 2200 const String& dst_name = String::ZoneHandle(node->field().name()); | 2235 const String& dst_name = String::ZoneHandle(node->field().name()); |
| 2201 store_value = BuildAssignableValue(node->value()->token_pos(), | 2236 store_value = BuildAssignableValue(node->value()->token_pos(), |
| 2202 store_value, | 2237 store_value, |
| 2203 type, | 2238 type, |
| 2204 dst_name); | 2239 dst_name); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2218 | 2253 |
| 2219 | 2254 |
| 2220 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { | 2255 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { |
| 2221 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(node->field()); | 2256 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(node->field()); |
| 2222 ReturnDefinition(load); | 2257 ReturnDefinition(load); |
| 2223 } | 2258 } |
| 2224 | 2259 |
| 2225 | 2260 |
| 2226 Definition* EffectGraphVisitor::BuildStoreStaticField( | 2261 Definition* EffectGraphVisitor::BuildStoreStaticField( |
| 2227 StoreStaticFieldNode* node, bool result_is_needed) { | 2262 StoreStaticFieldNode* node, bool result_is_needed) { |
| 2228 ValueGraphVisitor for_value(owner(), temp_index()); | 2263 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); |
| 2229 node->value()->Visit(&for_value); | 2264 node->value()->Visit(&for_value); |
| 2230 Append(for_value); | 2265 Append(for_value); |
| 2231 Value* store_value = NULL; | 2266 Value* store_value = NULL; |
| 2232 if (result_is_needed) { | 2267 if (result_is_needed) { |
| 2233 store_value = Bind(BuildStoreExprTemp(for_value.value())); | 2268 store_value = Bind(BuildStoreExprTemp(for_value.value())); |
| 2234 } else { | 2269 } else { |
| 2235 store_value = for_value.value(); | 2270 store_value = for_value.value(); |
| 2236 } | 2271 } |
| 2237 if (FLAG_enable_type_checks) { | 2272 if (FLAG_enable_type_checks) { |
| 2238 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 2273 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2260 | 2295 |
| 2261 | 2296 |
| 2262 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { | 2297 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
| 2263 ReturnDefinition(BuildStoreStaticField(node, kResultNeeded)); | 2298 ReturnDefinition(BuildStoreStaticField(node, kResultNeeded)); |
| 2264 } | 2299 } |
| 2265 | 2300 |
| 2266 | 2301 |
| 2267 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { | 2302 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { |
| 2268 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2303 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2269 new ZoneGrowableArray<PushArgumentInstr*>(2); | 2304 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 2270 ValueGraphVisitor for_array(owner(), temp_index()); | 2305 ValueGraphVisitor for_array(owner(), temp_index(), loop_depth()); |
| 2271 node->array()->Visit(&for_array); | 2306 node->array()->Visit(&for_array); |
| 2272 Append(for_array); | 2307 Append(for_array); |
| 2273 arguments->Add(PushArgument(for_array.value())); | 2308 arguments->Add(PushArgument(for_array.value())); |
| 2274 | 2309 |
| 2275 ValueGraphVisitor for_index(owner(), temp_index()); | 2310 ValueGraphVisitor for_index(owner(), temp_index(), loop_depth()); |
| 2276 node->index_expr()->Visit(&for_index); | 2311 node->index_expr()->Visit(&for_index); |
| 2277 Append(for_index); | 2312 Append(for_index); |
| 2278 arguments->Add(PushArgument(for_index.value())); | 2313 arguments->Add(PushArgument(for_index.value())); |
| 2279 | 2314 |
| 2280 const intptr_t checked_argument_count = 1; | 2315 const intptr_t checked_argument_count = 1; |
| 2281 const String& name = | 2316 const String& name = |
| 2282 String::ZoneHandle(Symbols::New(Token::Str(Token::kINDEX))); | 2317 String::ZoneHandle(Symbols::New(Token::Str(Token::kINDEX))); |
| 2283 InstanceCallInstr* load = new InstanceCallInstr(node->token_pos(), | 2318 InstanceCallInstr* load = new InstanceCallInstr(node->token_pos(), |
| 2284 name, | 2319 name, |
| 2285 Token::kINDEX, | 2320 Token::kINDEX, |
| 2286 arguments, | 2321 arguments, |
| 2287 Array::ZoneHandle(), | 2322 Array::ZoneHandle(), |
| 2288 checked_argument_count); | 2323 checked_argument_count); |
| 2289 ReturnDefinition(load); | 2324 ReturnDefinition(load); |
| 2290 } | 2325 } |
| 2291 | 2326 |
| 2292 | 2327 |
| 2293 Definition* EffectGraphVisitor::BuildStoreIndexedValues( | 2328 Definition* EffectGraphVisitor::BuildStoreIndexedValues( |
| 2294 StoreIndexedNode* node, | 2329 StoreIndexedNode* node, |
| 2295 bool result_is_needed) { | 2330 bool result_is_needed) { |
| 2296 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2331 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2297 new ZoneGrowableArray<PushArgumentInstr*>(3); | 2332 new ZoneGrowableArray<PushArgumentInstr*>(3); |
| 2298 ValueGraphVisitor for_array(owner(), temp_index()); | 2333 ValueGraphVisitor for_array(owner(), temp_index(), loop_depth()); |
| 2299 node->array()->Visit(&for_array); | 2334 node->array()->Visit(&for_array); |
| 2300 Append(for_array); | 2335 Append(for_array); |
| 2301 arguments->Add(PushArgument(for_array.value())); | 2336 arguments->Add(PushArgument(for_array.value())); |
| 2302 | 2337 |
| 2303 ValueGraphVisitor for_index(owner(), temp_index()); | 2338 ValueGraphVisitor for_index(owner(), temp_index(), loop_depth()); |
| 2304 node->index_expr()->Visit(&for_index); | 2339 node->index_expr()->Visit(&for_index); |
| 2305 Append(for_index); | 2340 Append(for_index); |
| 2306 arguments->Add(PushArgument(for_index.value())); | 2341 arguments->Add(PushArgument(for_index.value())); |
| 2307 | 2342 |
| 2308 ValueGraphVisitor for_value(owner(), temp_index()); | 2343 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); |
| 2309 node->value()->Visit(&for_value); | 2344 node->value()->Visit(&for_value); |
| 2310 Append(for_value); | 2345 Append(for_value); |
| 2311 Value* value = NULL; | 2346 Value* value = NULL; |
| 2312 if (result_is_needed) { | 2347 if (result_is_needed) { |
| 2313 value = Bind(BuildStoreExprTemp(for_value.value())); | 2348 value = Bind(BuildStoreExprTemp(for_value.value())); |
| 2314 } else { | 2349 } else { |
| 2315 value = for_value.value(); | 2350 value = for_value.value(); |
| 2316 } | 2351 } |
| 2317 arguments->Add(PushArgument(value)); | 2352 arguments->Add(PushArgument(value)); |
| 2318 | 2353 |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2464 // variable so that ssa renaming detects the dependency and makes use | 2499 // variable so that ssa renaming detects the dependency and makes use |
| 2465 // of the checked type in type propagation. | 2500 // of the checked type in type propagation. |
| 2466 Do(BuildStoreLocal(parameter, parameter_value, kResultNotNeeded)); | 2501 Do(BuildStoreLocal(parameter, parameter_value, kResultNotNeeded)); |
| 2467 } | 2502 } |
| 2468 pos++; | 2503 pos++; |
| 2469 } | 2504 } |
| 2470 } | 2505 } |
| 2471 | 2506 |
| 2472 intptr_t i = 0; | 2507 intptr_t i = 0; |
| 2473 while (is_open() && (i < node->length())) { | 2508 while (is_open() && (i < node->length())) { |
| 2474 EffectGraphVisitor for_effect(owner(), temp_index()); | 2509 EffectGraphVisitor for_effect(owner(), temp_index(), loop_depth()); |
| 2475 node->NodeAt(i++)->Visit(&for_effect); | 2510 node->NodeAt(i++)->Visit(&for_effect); |
| 2476 Append(for_effect); | 2511 Append(for_effect); |
| 2477 if (!is_open()) { | 2512 if (!is_open()) { |
| 2478 // E.g., because of a JumpNode. | 2513 // E.g., because of a JumpNode. |
| 2479 break; | 2514 break; |
| 2480 } | 2515 } |
| 2481 } | 2516 } |
| 2482 | 2517 |
| 2483 if (is_open()) { | 2518 if (is_open()) { |
| 2484 if (MustSaveRestoreContext(node)) { | 2519 if (MustSaveRestoreContext(node)) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2509 | 2544 |
| 2510 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { | 2545 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { |
| 2511 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)"); | 2546 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)"); |
| 2512 // NOTE: The implicit variables ':saved_context', ':exception_var' | 2547 // NOTE: The implicit variables ':saved_context', ':exception_var' |
| 2513 // and ':stacktrace_var' can never be captured variables. | 2548 // and ':stacktrace_var' can never be captured variables. |
| 2514 // Restores CTX from local variable ':saved_context'. | 2549 // Restores CTX from local variable ':saved_context'. |
| 2515 AddInstruction( | 2550 AddInstruction( |
| 2516 new CatchEntryInstr(node->exception_var(), node->stacktrace_var())); | 2551 new CatchEntryInstr(node->exception_var(), node->stacktrace_var())); |
| 2517 BuildLoadContext(node->context_var()); | 2552 BuildLoadContext(node->context_var()); |
| 2518 | 2553 |
| 2519 EffectGraphVisitor for_catch(owner(), temp_index()); | 2554 EffectGraphVisitor for_catch(owner(), temp_index(), loop_depth()); |
| 2520 node->VisitChildren(&for_catch); | 2555 node->VisitChildren(&for_catch); |
| 2521 Append(for_catch); | 2556 Append(for_catch); |
| 2522 } | 2557 } |
| 2523 | 2558 |
| 2524 | 2559 |
| 2525 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { | 2560 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { |
| 2526 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); | 2561 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); |
| 2527 intptr_t old_try_index = owner()->try_index(); | 2562 intptr_t old_try_index = owner()->try_index(); |
| 2528 intptr_t try_index = owner()->AllocateTryIndex(); | 2563 intptr_t try_index = owner()->AllocateTryIndex(); |
| 2529 owner()->set_try_index(try_index); | 2564 owner()->set_try_index(try_index); |
| 2530 | 2565 |
| 2531 // Preserve CTX into local variable '%saved_context'. | 2566 // Preserve CTX into local variable '%saved_context'. |
| 2532 BuildStoreContext(node->context_var()); | 2567 BuildStoreContext(node->context_var()); |
| 2533 | 2568 |
| 2534 EffectGraphVisitor for_try_block(owner(), temp_index()); | 2569 EffectGraphVisitor for_try_block(owner(), temp_index(), loop_depth()); |
| 2535 node->try_block()->Visit(&for_try_block); | 2570 node->try_block()->Visit(&for_try_block); |
| 2536 | 2571 |
| 2537 if (for_try_block.is_open()) { | 2572 if (for_try_block.is_open()) { |
| 2538 JoinEntryInstr* after_try = | 2573 JoinEntryInstr* after_try = |
| 2539 new JoinEntryInstr(owner()->AllocateBlockId(), old_try_index); | 2574 new JoinEntryInstr(owner()->AllocateBlockId(), |
| 2575 old_try_index, |
| 2576 loop_depth()); |
| 2540 for_try_block.Goto(after_try); | 2577 for_try_block.Goto(after_try); |
| 2541 for_try_block.exit_ = after_try; | 2578 for_try_block.exit_ = after_try; |
| 2542 } | 2579 } |
| 2543 | 2580 |
| 2544 JoinEntryInstr* try_entry = | 2581 JoinEntryInstr* try_entry = |
| 2545 new JoinEntryInstr(owner()->AllocateBlockId(), try_index); | 2582 new JoinEntryInstr(owner()->AllocateBlockId(), try_index, loop_depth()); |
| 2546 | 2583 |
| 2547 Goto(try_entry); | 2584 Goto(try_entry); |
| 2548 AppendFragment(try_entry, for_try_block); | 2585 AppendFragment(try_entry, for_try_block); |
| 2549 exit_ = for_try_block.exit_; | 2586 exit_ = for_try_block.exit_; |
| 2550 | 2587 |
| 2551 // We are done generating code for the try block. | 2588 // We are done generating code for the try block. |
| 2552 owner()->set_try_index(old_try_index); | 2589 owner()->set_try_index(old_try_index); |
| 2553 | 2590 |
| 2554 CatchClauseNode* catch_block = node->catch_block(); | 2591 CatchClauseNode* catch_block = node->catch_block(); |
| 2555 if (catch_block != NULL) { | 2592 if (catch_block != NULL) { |
| 2556 // Set the corresponding try index for this catch block so | 2593 // Set the corresponding try index for this catch block so |
| 2557 // that we can set the appropriate handler pc when we generate | 2594 // that we can set the appropriate handler pc when we generate |
| 2558 // code for this catch block. | 2595 // code for this catch block. |
| 2559 catch_block->set_try_index(try_index); | 2596 catch_block->set_try_index(try_index); |
| 2560 EffectGraphVisitor for_catch_block(owner(), temp_index()); | 2597 EffectGraphVisitor for_catch_block(owner(), temp_index(), loop_depth()); |
| 2561 catch_block->Visit(&for_catch_block); | 2598 catch_block->Visit(&for_catch_block); |
| 2562 TargetEntryInstr* catch_entry = | 2599 TargetEntryInstr* catch_entry = |
| 2563 new TargetEntryInstr(owner()->AllocateBlockId(), old_try_index); | 2600 new TargetEntryInstr(owner()->AllocateBlockId(), |
| 2601 old_try_index, |
| 2602 loop_depth()); |
| 2564 catch_entry->set_catch_try_index(try_index); | 2603 catch_entry->set_catch_try_index(try_index); |
| 2565 owner()->AddCatchEntry(catch_entry); | 2604 owner()->AddCatchEntry(catch_entry); |
| 2566 ASSERT(!for_catch_block.is_open()); | 2605 ASSERT(!for_catch_block.is_open()); |
| 2567 AppendFragment(catch_entry, for_catch_block); | 2606 AppendFragment(catch_entry, for_catch_block); |
| 2568 if (node->end_catch_label() != NULL) { | 2607 if (node->end_catch_label() != NULL) { |
| 2569 JoinEntryInstr* join = node->end_catch_label()->join_for_continue(); | 2608 JoinEntryInstr* join = node->end_catch_label()->join_for_continue(); |
| 2570 if (join != NULL) { | 2609 if (join != NULL) { |
| 2571 if (is_open()) Goto(join); | 2610 if (is_open()) Goto(join); |
| 2572 exit_ = join; | 2611 exit_ = join; |
| 2573 } | 2612 } |
| 2574 } | 2613 } |
| 2575 } | 2614 } |
| 2576 | 2615 |
| 2577 // Generate code for the finally block if one exists. | 2616 // Generate code for the finally block if one exists. |
| 2578 if ((node->finally_block() != NULL) && is_open()) { | 2617 if ((node->finally_block() != NULL) && is_open()) { |
| 2579 EffectGraphVisitor for_finally_block(owner(), temp_index()); | 2618 EffectGraphVisitor for_finally_block(owner(), temp_index(), loop_depth()); |
| 2580 node->finally_block()->Visit(&for_finally_block); | 2619 node->finally_block()->Visit(&for_finally_block); |
| 2581 Append(for_finally_block); | 2620 Append(for_finally_block); |
| 2582 } | 2621 } |
| 2583 } | 2622 } |
| 2584 | 2623 |
| 2585 | 2624 |
| 2586 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { | 2625 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { |
| 2587 // TODO(kmillikin) non-local control flow is not handled correctly | 2626 // TODO(kmillikin) non-local control flow is not handled correctly |
| 2588 // by the inliner. | 2627 // by the inliner. |
| 2589 InlineBailout("EffectGraphVisitor::BuildThrowNode (exception)"); | 2628 InlineBailout("EffectGraphVisitor::BuildThrowNode (exception)"); |
| 2590 ValueGraphVisitor for_exception(owner(), temp_index()); | 2629 ValueGraphVisitor for_exception(owner(), temp_index(), loop_depth()); |
| 2591 node->exception()->Visit(&for_exception); | 2630 node->exception()->Visit(&for_exception); |
| 2592 Append(for_exception); | 2631 Append(for_exception); |
| 2593 PushArgument(for_exception.value()); | 2632 PushArgument(for_exception.value()); |
| 2594 Instruction* instr = NULL; | 2633 Instruction* instr = NULL; |
| 2595 if (node->stacktrace() == NULL) { | 2634 if (node->stacktrace() == NULL) { |
| 2596 instr = new ThrowInstr(node->token_pos()); | 2635 instr = new ThrowInstr(node->token_pos()); |
| 2597 } else { | 2636 } else { |
| 2598 ValueGraphVisitor for_stack_trace(owner(), temp_index()); | 2637 ValueGraphVisitor for_stack_trace(owner(), temp_index(), loop_depth()); |
| 2599 node->stacktrace()->Visit(&for_stack_trace); | 2638 node->stacktrace()->Visit(&for_stack_trace); |
| 2600 Append(for_stack_trace); | 2639 Append(for_stack_trace); |
| 2601 PushArgument(for_stack_trace.value()); | 2640 PushArgument(for_stack_trace.value()); |
| 2602 instr = new ReThrowInstr(node->token_pos()); | 2641 instr = new ReThrowInstr(node->token_pos()); |
| 2603 } | 2642 } |
| 2604 AddInstruction(instr); | 2643 AddInstruction(instr); |
| 2605 } | 2644 } |
| 2606 | 2645 |
| 2607 | 2646 |
| 2608 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { | 2647 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2625 const intptr_t try_index = owner()->try_index(); | 2664 const intptr_t try_index = owner()->try_index(); |
| 2626 if (try_index >= 0) { | 2665 if (try_index >= 0) { |
| 2627 // We are about to generate code for an inlined finally block. Exceptions | 2666 // We are about to generate code for an inlined finally block. Exceptions |
| 2628 // thrown in this block of code should be treated as though they are | 2667 // thrown in this block of code should be treated as though they are |
| 2629 // thrown not from the current try block but the outer try block if any. | 2668 // thrown not from the current try block but the outer try block if any. |
| 2630 owner()->set_try_index((try_index - 1)); | 2669 owner()->set_try_index((try_index - 1)); |
| 2631 } | 2670 } |
| 2632 BuildLoadContext(node->context_var()); | 2671 BuildLoadContext(node->context_var()); |
| 2633 | 2672 |
| 2634 JoinEntryInstr* finally_entry = | 2673 JoinEntryInstr* finally_entry = |
| 2635 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 2674 new JoinEntryInstr(owner()->AllocateBlockId(), |
| 2636 EffectGraphVisitor for_finally_block(owner(), temp_index()); | 2675 owner()->try_index(), |
| 2676 loop_depth()); |
| 2677 EffectGraphVisitor for_finally_block(owner(), temp_index(), loop_depth()); |
| 2637 node->finally_block()->Visit(&for_finally_block); | 2678 node->finally_block()->Visit(&for_finally_block); |
| 2638 | 2679 |
| 2639 if (try_index >= 0) { | 2680 if (try_index >= 0) { |
| 2640 owner()->set_try_index(try_index); | 2681 owner()->set_try_index(try_index); |
| 2641 } | 2682 } |
| 2642 | 2683 |
| 2643 if (for_finally_block.is_open()) { | 2684 if (for_finally_block.is_open()) { |
| 2644 JoinEntryInstr* after_finally = | 2685 JoinEntryInstr* after_finally = |
| 2645 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 2686 new JoinEntryInstr(owner()->AllocateBlockId(), |
| 2687 owner()->try_index(), |
| 2688 loop_depth()); |
| 2646 for_finally_block.Goto(after_finally); | 2689 for_finally_block.Goto(after_finally); |
| 2647 for_finally_block.exit_ = after_finally; | 2690 for_finally_block.exit_ = after_finally; |
| 2648 } | 2691 } |
| 2649 | 2692 |
| 2650 Goto(finally_entry); | 2693 Goto(finally_entry); |
| 2651 AppendFragment(finally_entry, for_finally_block); | 2694 AppendFragment(finally_entry, for_finally_block); |
| 2652 exit_ = for_finally_block.exit_; | 2695 exit_ = for_finally_block.exit_; |
| 2653 } | 2696 } |
| 2654 | 2697 |
| 2655 | 2698 |
| 2656 FlowGraph* FlowGraphBuilder::BuildGraph(InliningContext context) { | 2699 FlowGraph* FlowGraphBuilder::BuildGraph(InliningContext context, |
| 2700 intptr_t initial_loop_depth) { |
| 2657 if (FLAG_print_ast) { | 2701 if (FLAG_print_ast) { |
| 2658 // Print the function ast before IL generation. | 2702 // Print the function ast before IL generation. |
| 2659 AstPrinter::PrintFunctionNodes(parsed_function()); | 2703 AstPrinter::PrintFunctionNodes(parsed_function()); |
| 2660 } | 2704 } |
| 2661 // Set the inlining context. | 2705 // Set the inlining context. |
| 2662 ASSERT(inlining_context_ == kNotInlining); | 2706 ASSERT(inlining_context_ == kNotInlining); |
| 2663 inlining_context_ = context; | 2707 inlining_context_ = context; |
| 2664 if (InInliningContext()) exits_ = new ZoneGrowableArray<ReturnInstr*>(); | 2708 if (InInliningContext()) exits_ = new ZoneGrowableArray<ReturnInstr*>(); |
| 2665 // Compilation can be nested, preserve the computation-id. | 2709 // Compilation can be nested, preserve the computation-id. |
| 2666 const Function& function = parsed_function().function(); | 2710 const Function& function = parsed_function().function(); |
| 2667 TargetEntryInstr* normal_entry = | 2711 TargetEntryInstr* normal_entry = |
| 2668 new TargetEntryInstr(AllocateBlockId(), | 2712 new TargetEntryInstr(AllocateBlockId(), |
| 2669 CatchClauseNode::kInvalidTryIndex); | 2713 CatchClauseNode::kInvalidTryIndex, |
| 2714 initial_loop_depth); |
| 2670 graph_entry_ = new GraphEntryInstr(normal_entry); | 2715 graph_entry_ = new GraphEntryInstr(normal_entry); |
| 2671 EffectGraphVisitor for_effect(this, 0); | 2716 EffectGraphVisitor for_effect(this, 0, initial_loop_depth); |
| 2672 if (InInliningContext()) { | 2717 if (InInliningContext()) { |
| 2673 exits_ = new ZoneGrowableArray<ReturnInstr*>(); | 2718 exits_ = new ZoneGrowableArray<ReturnInstr*>(); |
| 2674 } | 2719 } |
| 2675 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the | 2720 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the |
| 2676 // stack check on entry for leaf routines). | 2721 // stack check on entry for leaf routines). |
| 2677 Instruction* check = new CheckStackOverflowInstr(function.token_pos()); | 2722 Instruction* check = new CheckStackOverflowInstr(function.token_pos()); |
| 2678 // If we are inlining don't actually attach the stack check. We must still | 2723 // If we are inlining don't actually attach the stack check. We must still |
| 2679 // create the stack check inorder to allocate a deopt id. | 2724 // create the stack check inorder to allocate a deopt id. |
| 2680 if (!InInliningContext()) for_effect.AddInstruction(check); | 2725 if (!InInliningContext()) for_effect.AddInstruction(check); |
| 2681 parsed_function().node_sequence()->Visit(&for_effect); | 2726 parsed_function().node_sequence()->Visit(&for_effect); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2694 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 2739 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 2695 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 2740 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 2696 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2741 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2697 const Error& error = Error::Handle( | 2742 const Error& error = Error::Handle( |
| 2698 LanguageError::New(String::Handle(String::New(chars)))); | 2743 LanguageError::New(String::Handle(String::New(chars)))); |
| 2699 Isolate::Current()->long_jump_base()->Jump(1, error); | 2744 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2700 } | 2745 } |
| 2701 | 2746 |
| 2702 | 2747 |
| 2703 } // namespace dart | 2748 } // namespace dart |
| OLD | NEW |