| 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() + 1); |
| 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)) { |
| 1075 node->label()->join_for_break()->set_loop_depth(loop_depth()); |
| 1058 if (is_open()) Goto(node->label()->join_for_break()); | 1076 if (is_open()) Goto(node->label()->join_for_break()); |
| 1059 exit_ = node->label()->join_for_break(); | 1077 exit_ = node->label()->join_for_break(); |
| 1060 } | 1078 } |
| 1061 // No continue label allowed. | 1079 // No continue label allowed. |
| 1062 ASSERT((node->label() == NULL) || | 1080 ASSERT((node->label() == NULL) || |
| 1063 (node->label()->join_for_continue() == NULL)); | 1081 (node->label()->join_for_continue() == NULL)); |
| 1064 } | 1082 } |
| 1065 | 1083 |
| 1066 | 1084 |
| 1067 // A case node contains zero or more case expressions, can contain default | 1085 // A case node contains zero or more case expressions, can contain default |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1081 // g) case-statements-join | 1099 // g) case-statements-join |
| 1082 // h) [ case-statements ] -> exit-join | 1100 // h) [ case-statements ] -> exit-join |
| 1083 // i) exit-target -> exit-join | 1101 // i) exit-target -> exit-join |
| 1084 // j) exit-join | 1102 // j) exit-join |
| 1085 // | 1103 // |
| 1086 // Note: The specification of switch/case is under discussion and may change | 1104 // Note: The specification of switch/case is under discussion and may change |
| 1087 // drastically. | 1105 // drastically. |
| 1088 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { | 1106 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { |
| 1089 const intptr_t len = node->case_expressions()->length(); | 1107 const intptr_t len = node->case_expressions()->length(); |
| 1090 // Create case statements instructions. | 1108 // Create case statements instructions. |
| 1091 EffectGraphVisitor for_case_statements(owner(), temp_index()); | 1109 EffectGraphVisitor for_case_statements(owner(), temp_index(), loop_depth()); |
| 1092 // Compute start of statements fragment. | 1110 // Compute start of statements fragment. |
| 1093 JoinEntryInstr* statement_start = NULL; | 1111 JoinEntryInstr* statement_start = NULL; |
| 1094 if ((node->label() != NULL) && node->label()->is_continue_target()) { | 1112 if ((node->label() != NULL) && node->label()->is_continue_target()) { |
| 1095 // Since a labeled jump continue statement occur in a different case node, | 1113 // Since a labeled jump continue statement occur in a different case node, |
| 1096 // allocate JoinNode here and use it as statement start. | 1114 // allocate JoinNode here and use it as statement start. |
| 1097 statement_start = node->label()->join_for_continue(); | 1115 statement_start = node->label()->join_for_continue(); |
| 1098 if (statement_start == NULL) { | 1116 if (statement_start == NULL) { |
| 1099 statement_start = | 1117 statement_start = new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1100 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 1118 owner()->try_index(), |
| 1119 loop_depth()); |
| 1101 node->label()->set_join_for_continue(statement_start); | 1120 node->label()->set_join_for_continue(statement_start); |
| 1102 } | 1121 } |
| 1103 } else { | 1122 } else { |
| 1104 statement_start = | 1123 statement_start = new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1105 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 1124 owner()->try_index(), |
| 1125 loop_depth()); |
| 1106 } | 1126 } |
| 1107 node->statements()->Visit(&for_case_statements); | 1127 node->statements()->Visit(&for_case_statements); |
| 1108 Instruction* statement_exit = | 1128 Instruction* statement_exit = |
| 1109 AppendFragment(statement_start, for_case_statements); | 1129 AppendFragment(statement_start, for_case_statements); |
| 1110 if (is_open() && (len == 0)) { | 1130 if (is_open() && (len == 0)) { |
| 1111 ASSERT(node->contains_default()); | 1131 ASSERT(node->contains_default()); |
| 1112 // Default only case node. | 1132 // Default only case node. |
| 1113 Goto(statement_start); | 1133 Goto(statement_start); |
| 1114 exit_ = statement_exit; | 1134 exit_ = statement_exit; |
| 1115 return; | 1135 return; |
| 1116 } | 1136 } |
| 1117 | 1137 |
| 1118 // Generate instructions for all case expressions. | 1138 // Generate instructions for all case expressions. |
| 1119 TargetEntryInstr* next_target = NULL; | 1139 TargetEntryInstr* next_target = NULL; |
| 1120 for (intptr_t i = 0; i < len; i++) { | 1140 for (intptr_t i = 0; i < len; i++) { |
| 1121 AstNode* case_expr = node->case_expressions()->NodeAt(i); | 1141 AstNode* case_expr = node->case_expressions()->NodeAt(i); |
| 1122 TestGraphVisitor for_case_expression(owner(), | 1142 TestGraphVisitor for_case_expression(owner(), |
| 1123 temp_index(), | 1143 temp_index(), |
| 1144 loop_depth(), |
| 1124 case_expr->token_pos()); | 1145 case_expr->token_pos()); |
| 1125 case_expr->Visit(&for_case_expression); | 1146 case_expr->Visit(&for_case_expression); |
| 1126 if (i == 0) { | 1147 if (i == 0) { |
| 1127 // Append only the first one, everything else is connected from it. | 1148 // Append only the first one, everything else is connected from it. |
| 1128 Append(for_case_expression); | 1149 Append(for_case_expression); |
| 1129 } else { | 1150 } else { |
| 1130 ASSERT(next_target != NULL); | 1151 ASSERT(next_target != NULL); |
| 1131 AppendFragment(next_target, for_case_expression); | 1152 AppendFragment(next_target, for_case_expression); |
| 1132 } | 1153 } |
| 1133 for_case_expression.IfTrueGoto(statement_start); | 1154 for_case_expression.IfTrueGoto(statement_start); |
| 1134 next_target = for_case_expression.CreateFalseSuccessor()->AsTargetEntry(); | 1155 next_target = for_case_expression.CreateFalseSuccessor()->AsTargetEntry(); |
| 1135 } | 1156 } |
| 1136 | 1157 |
| 1137 // Once a test fragment has been added, this fragment is closed. | 1158 // Once a test fragment has been added, this fragment is closed. |
| 1138 ASSERT(!is_open()); | 1159 ASSERT(!is_open()); |
| 1139 | 1160 |
| 1140 Instruction* exit_instruction = NULL; | 1161 Instruction* exit_instruction = NULL; |
| 1141 // Handle last (or only) case: false goes to exit or to statement if this | 1162 // Handle last (or only) case: false goes to exit or to statement if this |
| 1142 // node contains default. | 1163 // node contains default. |
| 1143 if (len > 0) { | 1164 if (len > 0) { |
| 1144 ASSERT(next_target != NULL); | 1165 ASSERT(next_target != NULL); |
| 1145 if (node->contains_default()) { | 1166 if (node->contains_default()) { |
| 1146 // True and false go to statement start. | 1167 // True and false go to statement start. |
| 1147 next_target->Goto(statement_start); | 1168 next_target->Goto(statement_start); |
| 1148 exit_instruction = statement_exit; | 1169 exit_instruction = statement_exit; |
| 1149 } else { | 1170 } else { |
| 1150 if (statement_exit != NULL) { | 1171 if (statement_exit != NULL) { |
| 1151 JoinEntryInstr* join = new JoinEntryInstr(owner()->AllocateBlockId(), | 1172 JoinEntryInstr* join = new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1152 owner()->try_index()); | 1173 owner()->try_index(), |
| 1174 loop_depth()); |
| 1153 statement_exit->Goto(join); | 1175 statement_exit->Goto(join); |
| 1154 next_target->Goto(join); | 1176 next_target->Goto(join); |
| 1155 exit_instruction = join; | 1177 exit_instruction = join; |
| 1156 } else { | 1178 } else { |
| 1157 exit_instruction = next_target; | 1179 exit_instruction = next_target; |
| 1158 } | 1180 } |
| 1159 } | 1181 } |
| 1160 } else { | 1182 } else { |
| 1161 // A CaseNode without case expressions must contain default. | 1183 // A CaseNode without case expressions must contain default. |
| 1162 ASSERT(node->contains_default()); | 1184 ASSERT(node->contains_default()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1176 // a) loop-join | 1198 // a) loop-join |
| 1177 // b) [ test ] -> (body-entry-target, loop-exit-target) | 1199 // b) [ test ] -> (body-entry-target, loop-exit-target) |
| 1178 // c) body-entry-target | 1200 // c) body-entry-target |
| 1179 // d) [ body ] -> (continue-join) | 1201 // d) [ body ] -> (continue-join) |
| 1180 // e) continue-join -> (loop-join) | 1202 // e) continue-join -> (loop-join) |
| 1181 // f) loop-exit-target | 1203 // f) loop-exit-target |
| 1182 // g) break-join (optional) | 1204 // g) break-join (optional) |
| 1183 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { | 1205 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { |
| 1184 TestGraphVisitor for_test(owner(), | 1206 TestGraphVisitor for_test(owner(), |
| 1185 temp_index(), | 1207 temp_index(), |
| 1208 loop_depth() + 1, |
| 1186 node->condition()->token_pos()); | 1209 node->condition()->token_pos()); |
| 1187 node->condition()->Visit(&for_test); | 1210 node->condition()->Visit(&for_test); |
| 1188 ASSERT(!for_test.is_empty()); // Language spec. | 1211 ASSERT(!for_test.is_empty()); // Language spec. |
| 1189 | 1212 |
| 1190 EffectGraphVisitor for_body(owner(), temp_index()); | 1213 EffectGraphVisitor for_body(owner(), temp_index(), loop_depth() + 1); |
| 1191 for_body.AddInstruction( | 1214 for_body.AddInstruction( |
| 1192 new CheckStackOverflowInstr(node->token_pos())); | 1215 new CheckStackOverflowInstr(node->token_pos())); |
| 1193 node->body()->Visit(&for_body); | 1216 node->body()->Visit(&for_body); |
| 1194 | 1217 |
| 1195 // Labels are set after body traversal. | 1218 // Labels are set after body traversal. |
| 1196 SourceLabel* lbl = node->label(); | 1219 SourceLabel* lbl = node->label(); |
| 1197 ASSERT(lbl != NULL); | 1220 ASSERT(lbl != NULL); |
| 1198 JoinEntryInstr* join = lbl->join_for_continue(); | 1221 JoinEntryInstr* join = lbl->join_for_continue(); |
| 1199 if (join != NULL) { | 1222 if (join != NULL) { |
| 1223 join->set_loop_depth(loop_depth() + 1); |
| 1200 if (for_body.is_open()) for_body.Goto(join); | 1224 if (for_body.is_open()) for_body.Goto(join); |
| 1201 for_body.exit_ = join; | 1225 for_body.exit_ = join; |
| 1202 } | 1226 } |
| 1203 TieLoop(for_test, for_body); | 1227 TieLoop(for_test, for_body); |
| 1204 join = lbl->join_for_break(); | 1228 join = lbl->join_for_break(); |
| 1205 if (join != NULL) { | 1229 if (join != NULL) { |
| 1230 join->set_loop_depth(loop_depth()); |
| 1206 Goto(join); | 1231 Goto(join); |
| 1207 exit_ = join; | 1232 exit_ = join; |
| 1208 } | 1233 } |
| 1209 } | 1234 } |
| 1210 | 1235 |
| 1211 | 1236 |
| 1212 // The fragment is composed as follows: | 1237 // The fragment is composed as follows: |
| 1213 // a) body-entry-join | 1238 // a) body-entry-join |
| 1214 // b) [ body ] | 1239 // b) [ body ] |
| 1215 // c) test-entry (continue-join or body-exit-target) | 1240 // c) test-entry (continue-join or body-exit-target) |
| 1216 // d) [ test-entry ] -> (back-target, loop-exit-target) | 1241 // d) [ test-entry ] -> (back-target, loop-exit-target) |
| 1217 // e) back-target -> (body-entry-join) | 1242 // e) back-target -> (body-entry-join) |
| 1218 // f) loop-exit-target | 1243 // f) loop-exit-target |
| 1219 // g) break-join | 1244 // g) break-join |
| 1220 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { | 1245 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { |
| 1221 // Traverse body first in order to generate continue and break labels. | 1246 // Traverse body first in order to generate continue and break labels. |
| 1222 EffectGraphVisitor for_body(owner(), temp_index()); | 1247 EffectGraphVisitor for_body(owner(), temp_index(), loop_depth() + 1); |
| 1223 for_body.AddInstruction( | 1248 for_body.AddInstruction( |
| 1224 new CheckStackOverflowInstr(node->token_pos())); | 1249 new CheckStackOverflowInstr(node->token_pos())); |
| 1225 node->body()->Visit(&for_body); | 1250 node->body()->Visit(&for_body); |
| 1226 | 1251 |
| 1227 TestGraphVisitor for_test(owner(), | 1252 TestGraphVisitor for_test(owner(), |
| 1228 temp_index(), | 1253 temp_index(), |
| 1254 loop_depth() + 1, |
| 1229 node->condition()->token_pos()); | 1255 node->condition()->token_pos()); |
| 1230 node->condition()->Visit(&for_test); | 1256 node->condition()->Visit(&for_test); |
| 1231 ASSERT(is_open()); | 1257 ASSERT(is_open()); |
| 1232 | 1258 |
| 1233 // Tie do-while loop (test is after the body). | 1259 // Tie do-while loop (test is after the body). |
| 1234 JoinEntryInstr* body_entry_join = | 1260 JoinEntryInstr* body_entry_join = |
| 1235 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 1261 new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1262 owner()->try_index(), |
| 1263 loop_depth() + 1); |
| 1236 Goto(body_entry_join); | 1264 Goto(body_entry_join); |
| 1237 Instruction* body_exit = AppendFragment(body_entry_join, for_body); | 1265 Instruction* body_exit = AppendFragment(body_entry_join, for_body); |
| 1238 | 1266 |
| 1239 JoinEntryInstr* join = node->label()->join_for_continue(); | 1267 JoinEntryInstr* join = node->label()->join_for_continue(); |
| 1240 if ((body_exit != NULL) || (join != NULL)) { | 1268 if ((body_exit != NULL) || (join != NULL)) { |
| 1241 if (join == NULL) { | 1269 if (join == NULL) { |
| 1242 join = | 1270 join = new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1243 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 1271 owner()->try_index(), |
| 1272 loop_depth() + 1); |
| 1273 } else { |
| 1274 join->set_loop_depth(loop_depth() + 1); |
| 1244 } | 1275 } |
| 1245 join->LinkTo(for_test.entry()); | 1276 join->LinkTo(for_test.entry()); |
| 1246 if (body_exit != NULL) { | 1277 if (body_exit != NULL) { |
| 1247 body_exit->Goto(join); | 1278 body_exit->Goto(join); |
| 1248 } | 1279 } |
| 1249 } | 1280 } |
| 1250 | 1281 |
| 1251 | |
| 1252 for_test.IfTrueGoto(body_entry_join); | 1282 for_test.IfTrueGoto(body_entry_join); |
| 1253 if (node->label()->join_for_break() == NULL) { | 1283 join = node->label()->join_for_break(); |
| 1284 if (join == NULL) { |
| 1254 exit_ = for_test.CreateFalseSuccessor(); | 1285 exit_ = for_test.CreateFalseSuccessor(); |
| 1255 } else { | 1286 } else { |
| 1256 for_test.IfFalseGoto(node->label()->join_for_break()); | 1287 join->set_loop_depth(loop_depth()); |
| 1257 exit_ = node->label()->join_for_break(); | 1288 for_test.IfFalseGoto(join); |
| 1289 exit_ = join; |
| 1258 } | 1290 } |
| 1259 } | 1291 } |
| 1260 | 1292 |
| 1261 | 1293 |
| 1262 // A ForNode can contain break and continue jumps. 'break' joins to | 1294 // A ForNode can contain break and continue jumps. 'break' joins to |
| 1263 // ForNode exit, 'continue' joins at increment entry. The fragment is composed | 1295 // ForNode exit, 'continue' joins at increment entry. The fragment is composed |
| 1264 // as follows: | 1296 // as follows: |
| 1265 // a) [ initializer ] | 1297 // a) [ initializer ] |
| 1266 // b) loop-join | 1298 // b) loop-join |
| 1267 // c) [ test ] -> (body-entry-target, loop-exit-target) | 1299 // c) [ test ] -> (body-entry-target, loop-exit-target) |
| 1268 // d) body-entry-target | 1300 // d) body-entry-target |
| 1269 // e) [ body ] | 1301 // e) [ body ] |
| 1270 // f) continue-join (optional) | 1302 // f) continue-join (optional) |
| 1271 // g) [ increment ] -> (loop-join) | 1303 // g) [ increment ] -> (loop-join) |
| 1272 // h) loop-exit-target | 1304 // h) loop-exit-target |
| 1273 // i) break-join | 1305 // i) break-join |
| 1274 void EffectGraphVisitor::VisitForNode(ForNode* node) { | 1306 void EffectGraphVisitor::VisitForNode(ForNode* node) { |
| 1275 EffectGraphVisitor for_initializer(owner(), temp_index()); | 1307 EffectGraphVisitor for_initializer(owner(), temp_index(), loop_depth()); |
| 1276 node->initializer()->Visit(&for_initializer); | 1308 node->initializer()->Visit(&for_initializer); |
| 1277 Append(for_initializer); | 1309 Append(for_initializer); |
| 1278 ASSERT(is_open()); | 1310 ASSERT(is_open()); |
| 1279 | 1311 |
| 1280 // Compose body to set any jump labels. | 1312 // Compose body to set any jump labels. |
| 1281 EffectGraphVisitor for_body(owner(), temp_index()); | 1313 EffectGraphVisitor for_body(owner(), temp_index(), loop_depth() + 1); |
| 1282 for_body.AddInstruction( | 1314 for_body.AddInstruction( |
| 1283 new CheckStackOverflowInstr(node->token_pos())); | 1315 new CheckStackOverflowInstr(node->token_pos())); |
| 1284 node->body()->Visit(&for_body); | 1316 node->body()->Visit(&for_body); |
| 1285 | 1317 |
| 1286 // Join loop body, increment and compute their end instruction. | 1318 // Join loop body, increment and compute their end instruction. |
| 1287 ASSERT(!for_body.is_empty()); | 1319 ASSERT(!for_body.is_empty()); |
| 1288 Instruction* loop_increment_end = NULL; | 1320 Instruction* loop_increment_end = NULL; |
| 1289 EffectGraphVisitor for_increment(owner(), temp_index()); | 1321 EffectGraphVisitor for_increment(owner(), temp_index(), loop_depth() + 1); |
| 1290 node->increment()->Visit(&for_increment); | 1322 node->increment()->Visit(&for_increment); |
| 1291 JoinEntryInstr* join = node->label()->join_for_continue(); | 1323 JoinEntryInstr* join = node->label()->join_for_continue(); |
| 1292 if (join != NULL) { | 1324 if (join != NULL) { |
| 1325 join->set_loop_depth(loop_depth() + 1); |
| 1293 // Insert the join between the body and increment. | 1326 // Insert the join between the body and increment. |
| 1294 if (for_body.is_open()) for_body.Goto(join); | 1327 if (for_body.is_open()) for_body.Goto(join); |
| 1295 loop_increment_end = AppendFragment(join, for_increment); | 1328 loop_increment_end = AppendFragment(join, for_increment); |
| 1296 ASSERT(loop_increment_end != NULL); | 1329 ASSERT(loop_increment_end != NULL); |
| 1297 } else if (for_body.is_open()) { | 1330 } else if (for_body.is_open()) { |
| 1298 // Do not insert an extra basic block. | 1331 // Do not insert an extra basic block. |
| 1299 for_body.Append(for_increment); | 1332 for_body.Append(for_increment); |
| 1300 loop_increment_end = for_body.exit(); | 1333 loop_increment_end = for_body.exit(); |
| 1301 // 'for_body' contains at least the stack check. | 1334 // 'for_body' contains at least the stack check. |
| 1302 ASSERT(loop_increment_end != NULL); | 1335 ASSERT(loop_increment_end != NULL); |
| 1303 } else { | 1336 } else { |
| 1304 loop_increment_end = NULL; | 1337 loop_increment_end = NULL; |
| 1305 } | 1338 } |
| 1306 | 1339 |
| 1307 // 'loop_increment_end' is NULL only if there is no join for continue and the | 1340 // '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. | 1341 // body is not open, i.e., no backward branch exists. |
| 1309 if (loop_increment_end != NULL) { | 1342 if (loop_increment_end != NULL) { |
| 1310 JoinEntryInstr* loop_start = | 1343 JoinEntryInstr* loop_start = |
| 1311 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 1344 new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1345 owner()->try_index(), |
| 1346 loop_depth() + 1); |
| 1312 Goto(loop_start); | 1347 Goto(loop_start); |
| 1313 loop_increment_end->Goto(loop_start); | 1348 loop_increment_end->Goto(loop_start); |
| 1314 exit_ = loop_start; | 1349 exit_ = loop_start; |
| 1315 } | 1350 } |
| 1316 | 1351 |
| 1317 if (node->condition() == NULL) { | 1352 if (node->condition() == NULL) { |
| 1318 // Endless loop, no test. | 1353 // Endless loop, no test. |
| 1319 JoinEntryInstr* body_entry = | 1354 JoinEntryInstr* body_entry = |
| 1320 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 1355 new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1356 owner()->try_index(), |
| 1357 loop_depth() + 1); |
| 1321 AppendFragment(body_entry, for_body); | 1358 AppendFragment(body_entry, for_body); |
| 1322 Goto(body_entry); | 1359 Goto(body_entry); |
| 1323 if (node->label()->join_for_break() != NULL) { | 1360 if (node->label()->join_for_break() != NULL) { |
| 1361 node->label()->join_for_break()->set_loop_depth(loop_depth()); |
| 1324 // Control flow of ForLoop continues into join_for_break. | 1362 // Control flow of ForLoop continues into join_for_break. |
| 1325 exit_ = node->label()->join_for_break(); | 1363 exit_ = node->label()->join_for_break(); |
| 1326 } | 1364 } |
| 1327 } else { | 1365 } else { |
| 1328 TestGraphVisitor for_test(owner(), | 1366 TestGraphVisitor for_test(owner(), |
| 1329 temp_index(), | 1367 temp_index(), |
| 1368 loop_depth() + 1, |
| 1330 node->condition()->token_pos()); | 1369 node->condition()->token_pos()); |
| 1331 node->condition()->Visit(&for_test); | 1370 node->condition()->Visit(&for_test); |
| 1332 Append(for_test); | 1371 Append(for_test); |
| 1333 | 1372 |
| 1334 BlockEntryInstr* body_entry = for_test.CreateTrueSuccessor(); | 1373 BlockEntryInstr* body_entry = for_test.CreateTrueSuccessor(); |
| 1335 AppendFragment(body_entry, for_body); | 1374 AppendFragment(body_entry, for_body); |
| 1336 | 1375 |
| 1337 if (node->label()->join_for_break() == NULL) { | 1376 if (node->label()->join_for_break() == NULL) { |
| 1338 exit_ = for_test.CreateFalseSuccessor(); | 1377 exit_ = for_test.CreateFalseSuccessor(); |
| 1339 } else { | 1378 } else { |
| 1379 node->label()->join_for_break()->set_loop_depth(loop_depth()); |
| 1340 for_test.IfFalseGoto(node->label()->join_for_break()); | 1380 for_test.IfFalseGoto(node->label()->join_for_break()); |
| 1341 exit_ = node->label()->join_for_break(); | 1381 exit_ = node->label()->join_for_break(); |
| 1342 } | 1382 } |
| 1343 } | 1383 } |
| 1344 } | 1384 } |
| 1345 | 1385 |
| 1346 | 1386 |
| 1347 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { | 1387 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { |
| 1348 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { | 1388 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { |
| 1349 EffectGraphVisitor for_effect(owner(), temp_index()); | 1389 EffectGraphVisitor for_effect(owner(), temp_index(), loop_depth()); |
| 1350 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); | 1390 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
| 1351 Append(for_effect); | 1391 Append(for_effect); |
| 1352 if (!is_open()) return; | 1392 if (!is_open()) return; |
| 1353 } | 1393 } |
| 1354 | 1394 |
| 1355 // Unchain the context(s) up to the outer context level of the scope which | 1395 // Unchain the context(s) up to the outer context level of the scope which |
| 1356 // contains the destination label. | 1396 // contains the destination label. |
| 1357 SourceLabel* label = node->label(); | 1397 SourceLabel* label = node->label(); |
| 1358 ASSERT(label->owner() != NULL); | 1398 ASSERT(label->owner() != NULL); |
| 1359 int target_context_level = 0; | 1399 int target_context_level = 0; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1377 intptr_t current_context_level = owner()->context_level(); | 1417 intptr_t current_context_level = owner()->context_level(); |
| 1378 ASSERT(current_context_level >= target_context_level); | 1418 ASSERT(current_context_level >= target_context_level); |
| 1379 while (current_context_level-- > target_context_level) { | 1419 while (current_context_level-- > target_context_level) { |
| 1380 UnchainContext(); | 1420 UnchainContext(); |
| 1381 } | 1421 } |
| 1382 | 1422 |
| 1383 JoinEntryInstr* jump_target = NULL; | 1423 JoinEntryInstr* jump_target = NULL; |
| 1384 if (node->kind() == Token::kBREAK) { | 1424 if (node->kind() == Token::kBREAK) { |
| 1385 if (node->label()->join_for_break() == NULL) { | 1425 if (node->label()->join_for_break() == NULL) { |
| 1386 node->label()->set_join_for_break( | 1426 node->label()->set_join_for_break( |
| 1387 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index())); | 1427 new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1428 owner()->try_index(), |
| 1429 BlockEntryInstr::kInvalidLoopDepth)); |
| 1388 } | 1430 } |
| 1389 jump_target = node->label()->join_for_break(); | 1431 jump_target = node->label()->join_for_break(); |
| 1390 } else { | 1432 } else { |
| 1391 if (node->label()->join_for_continue() == NULL) { | 1433 if (node->label()->join_for_continue() == NULL) { |
| 1392 node->label()->set_join_for_continue( | 1434 node->label()->set_join_for_continue( |
| 1393 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index())); | 1435 new JoinEntryInstr(owner()->AllocateBlockId(), |
| 1436 owner()->try_index(), |
| 1437 BlockEntryInstr::kInvalidLoopDepth)); |
| 1394 } | 1438 } |
| 1395 jump_target = node->label()->join_for_continue(); | 1439 jump_target = node->label()->join_for_continue(); |
| 1396 } | 1440 } |
| 1397 Goto(jump_target); | 1441 Goto(jump_target); |
| 1398 } | 1442 } |
| 1399 | 1443 |
| 1400 | 1444 |
| 1401 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { | 1445 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { |
| 1402 UNREACHABLE(); | 1446 UNREACHABLE(); |
| 1403 } | 1447 } |
| 1404 | 1448 |
| 1405 | 1449 |
| 1406 void EffectGraphVisitor::VisitArgumentDefinitionTestNode( | 1450 void EffectGraphVisitor::VisitArgumentDefinitionTestNode( |
| 1407 ArgumentDefinitionTestNode* node) { | 1451 ArgumentDefinitionTestNode* node) { |
| 1408 InlineBailout("EffectGraphVisitor::VisitArgumentDefinitionTestNode"); | 1452 InlineBailout("EffectGraphVisitor::VisitArgumentDefinitionTestNode"); |
| 1409 Definition* load = BuildLoadLocal(node->saved_arguments_descriptor()); | 1453 Definition* load = BuildLoadLocal(node->saved_arguments_descriptor()); |
| 1410 Value* arguments_descriptor = Bind(load); | 1454 Value* arguments_descriptor = Bind(load); |
| 1411 ArgumentDefinitionTestInstr* arg_def_test = | 1455 ArgumentDefinitionTestInstr* arg_def_test = |
| 1412 new ArgumentDefinitionTestInstr(node, arguments_descriptor); | 1456 new ArgumentDefinitionTestInstr(node, arguments_descriptor); |
| 1413 ReturnDefinition(arg_def_test); | 1457 ReturnDefinition(arg_def_test); |
| 1414 } | 1458 } |
| 1415 | 1459 |
| 1416 | 1460 |
| 1417 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { | 1461 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { |
| 1418 // Translate the array elements and collect their values. | 1462 // Translate the array elements and collect their values. |
| 1419 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1463 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1420 new ZoneGrowableArray<PushArgumentInstr*>(node->length()); | 1464 new ZoneGrowableArray<PushArgumentInstr*>(node->length()); |
| 1421 for (int i = 0; i < node->length(); ++i) { | 1465 for (int i = 0; i < node->length(); ++i) { |
| 1422 ValueGraphVisitor for_value(owner(), temp_index()); | 1466 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); |
| 1423 node->ElementAt(i)->Visit(&for_value); | 1467 node->ElementAt(i)->Visit(&for_value); |
| 1424 Append(for_value); | 1468 Append(for_value); |
| 1425 arguments->Add(PushArgument(for_value.value())); | 1469 arguments->Add(PushArgument(for_value.value())); |
| 1426 } | 1470 } |
| 1427 const AbstractTypeArguments& type_args = | 1471 const AbstractTypeArguments& type_args = |
| 1428 AbstractTypeArguments::ZoneHandle(node->type().arguments()); | 1472 AbstractTypeArguments::ZoneHandle(node->type().arguments()); |
| 1429 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), | 1473 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), |
| 1430 type_args); | 1474 type_args); |
| 1431 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), | 1475 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), |
| 1432 arguments, | 1476 arguments, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1446 if (function.context_scope() == ContextScope::null()) { | 1490 if (function.context_scope() == ContextScope::null()) { |
| 1447 // TODO(regis): Why are we not doing this in the parser? | 1491 // TODO(regis): Why are we not doing this in the parser? |
| 1448 const ContextScope& context_scope = ContextScope::ZoneHandle( | 1492 const ContextScope& context_scope = ContextScope::ZoneHandle( |
| 1449 node->scope()->PreserveOuterScope(owner()->context_level())); | 1493 node->scope()->PreserveOuterScope(owner()->context_level())); |
| 1450 ASSERT(!function.HasCode()); | 1494 ASSERT(!function.HasCode()); |
| 1451 ASSERT(function.context_scope() == ContextScope::null()); | 1495 ASSERT(function.context_scope() == ContextScope::null()); |
| 1452 function.set_context_scope(context_scope); | 1496 function.set_context_scope(context_scope); |
| 1453 } | 1497 } |
| 1454 receiver = BuildNullValue(); | 1498 receiver = BuildNullValue(); |
| 1455 } else if (function.IsImplicitInstanceClosureFunction()) { | 1499 } else if (function.IsImplicitInstanceClosureFunction()) { |
| 1456 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1500 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); |
| 1457 node->receiver()->Visit(&for_receiver); | 1501 node->receiver()->Visit(&for_receiver); |
| 1458 Append(for_receiver); | 1502 Append(for_receiver); |
| 1459 receiver = for_receiver.value(); | 1503 receiver = for_receiver.value(); |
| 1460 } else { | 1504 } else { |
| 1461 receiver = BuildNullValue(); | 1505 receiver = BuildNullValue(); |
| 1462 } | 1506 } |
| 1463 PushArgumentInstr* push_receiver = PushArgument(receiver); | 1507 PushArgumentInstr* push_receiver = PushArgument(receiver); |
| 1464 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1508 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1465 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1509 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1466 arguments->Add(push_receiver); | 1510 arguments->Add(push_receiver); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1481 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments); | 1525 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments); |
| 1482 arguments->Add(push_type_arguments); | 1526 arguments->Add(push_type_arguments); |
| 1483 ReturnDefinition(new CreateClosureInstr(node, arguments)); | 1527 ReturnDefinition(new CreateClosureInstr(node, arguments)); |
| 1484 } | 1528 } |
| 1485 | 1529 |
| 1486 | 1530 |
| 1487 void EffectGraphVisitor::TranslateArgumentList( | 1531 void EffectGraphVisitor::TranslateArgumentList( |
| 1488 const ArgumentListNode& node, | 1532 const ArgumentListNode& node, |
| 1489 ZoneGrowableArray<Value*>* values) { | 1533 ZoneGrowableArray<Value*>* values) { |
| 1490 for (intptr_t i = 0; i < node.length(); ++i) { | 1534 for (intptr_t i = 0; i < node.length(); ++i) { |
| 1491 ValueGraphVisitor for_argument(owner(), temp_index()); | 1535 ValueGraphVisitor for_argument(owner(), temp_index(), loop_depth()); |
| 1492 node.NodeAt(i)->Visit(&for_argument); | 1536 node.NodeAt(i)->Visit(&for_argument); |
| 1493 Append(for_argument); | 1537 Append(for_argument); |
| 1494 values->Add(for_argument.value()); | 1538 values->Add(for_argument.value()); |
| 1495 } | 1539 } |
| 1496 } | 1540 } |
| 1497 | 1541 |
| 1498 | 1542 |
| 1499 void EffectGraphVisitor::BuildPushArguments( | 1543 void EffectGraphVisitor::BuildPushArguments( |
| 1500 const ArgumentListNode& node, | 1544 const ArgumentListNode& node, |
| 1501 ZoneGrowableArray<PushArgumentInstr*>* values) { | 1545 ZoneGrowableArray<PushArgumentInstr*>* values) { |
| 1502 for (intptr_t i = 0; i < node.length(); ++i) { | 1546 for (intptr_t i = 0; i < node.length(); ++i) { |
| 1503 ValueGraphVisitor for_argument(owner(), temp_index()); | 1547 ValueGraphVisitor for_argument(owner(), temp_index(), loop_depth()); |
| 1504 node.NodeAt(i)->Visit(&for_argument); | 1548 node.NodeAt(i)->Visit(&for_argument); |
| 1505 Append(for_argument); | 1549 Append(for_argument); |
| 1506 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); | 1550 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); |
| 1507 values->Add(push_arg); | 1551 values->Add(push_arg); |
| 1508 } | 1552 } |
| 1509 } | 1553 } |
| 1510 | 1554 |
| 1511 | 1555 |
| 1512 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { | 1556 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { |
| 1513 ValueGraphVisitor for_receiver(owner(), temp_index()); | 1557 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); |
| 1514 node->receiver()->Visit(&for_receiver); | 1558 node->receiver()->Visit(&for_receiver); |
| 1515 Append(for_receiver); | 1559 Append(for_receiver); |
| 1516 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 1560 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 1517 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1561 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1518 new ZoneGrowableArray<PushArgumentInstr*>( | 1562 new ZoneGrowableArray<PushArgumentInstr*>( |
| 1519 node->arguments()->length() + 1); | 1563 node->arguments()->length() + 1); |
| 1520 arguments->Add(push_receiver); | 1564 arguments->Add(push_receiver); |
| 1521 | 1565 |
| 1522 BuildPushArguments(*node->arguments(), arguments); | 1566 BuildPushArguments(*node->arguments(), arguments); |
| 1523 InstanceCallInstr* call = new InstanceCallInstr( | 1567 InstanceCallInstr* call = new InstanceCallInstr( |
| 1524 node->token_pos(), | 1568 node->token_pos(), |
| 1525 node->function_name(), Token::kILLEGAL, arguments, | 1569 node->function_name(), Token::kILLEGAL, arguments, |
| 1526 node->arguments()->names(), 1); | 1570 node->arguments()->names(), 1); |
| 1527 ReturnDefinition(call); | 1571 ReturnDefinition(call); |
| 1528 } | 1572 } |
| 1529 | 1573 |
| 1530 | 1574 |
| 1531 // <Expression> ::= StaticCall { function: Function | 1575 // <Expression> ::= StaticCall { function: Function |
| 1532 // arguments: <ArgumentList> } | 1576 // arguments: <ArgumentList> } |
| 1533 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { | 1577 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { |
| 1534 if (node->function().name() == Symbols::Identical()) { | 1578 if (node->function().name() == Symbols::Identical()) { |
| 1535 // Attempt to replace identical with strcit equal early on. | 1579 // Attempt to replace identical with strcit equal early on. |
| 1536 // TODO(hausner): Evaluate if this can happen at AST building time. | 1580 // TODO(hausner): Evaluate if this can happen at AST building time. |
| 1537 const Class& cls = Class::Handle(node->function().Owner()); | 1581 const Class& cls = Class::Handle(node->function().Owner()); |
| 1538 if (cls.IsTopLevel()) { | 1582 if (cls.IsTopLevel()) { |
| 1539 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 1583 const Library& core_lib = Library::Handle(Library::CoreLibrary()); |
| 1540 if (cls.library() == core_lib.raw()) { | 1584 if (cls.library() == core_lib.raw()) { |
| 1541 ASSERT(node->arguments()->length() == 2); | 1585 ASSERT(node->arguments()->length() == 2); |
| 1542 ValueGraphVisitor for_left_value(owner(), temp_index()); | 1586 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); |
| 1543 node->arguments()->NodeAt(0)->Visit(&for_left_value); | 1587 node->arguments()->NodeAt(0)->Visit(&for_left_value); |
| 1544 Append(for_left_value); | 1588 Append(for_left_value); |
| 1545 ValueGraphVisitor for_right_value(owner(), temp_index()); | 1589 ValueGraphVisitor for_right_value(owner(), temp_index(), loop_depth()); |
| 1546 node->arguments()->NodeAt(1)->Visit(&for_right_value); | 1590 node->arguments()->NodeAt(1)->Visit(&for_right_value); |
| 1547 Append(for_right_value); | 1591 Append(for_right_value); |
| 1548 StrictCompareInstr* comp = new StrictCompareInstr( | 1592 StrictCompareInstr* comp = new StrictCompareInstr( |
| 1549 Token::kEQ_STRICT, | 1593 Token::kEQ_STRICT, |
| 1550 for_left_value.value(), | 1594 for_left_value.value(), |
| 1551 for_right_value.value()); | 1595 for_right_value.value()); |
| 1552 ReturnDefinition(comp); | 1596 ReturnDefinition(comp); |
| 1553 return; | 1597 return; |
| 1554 } | 1598 } |
| 1555 } | 1599 } |
| 1556 } | 1600 } |
| 1557 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1601 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1558 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 1602 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 1559 BuildPushArguments(*node->arguments(), arguments); | 1603 BuildPushArguments(*node->arguments(), arguments); |
| 1560 StaticCallInstr* call = | 1604 StaticCallInstr* call = |
| 1561 new StaticCallInstr(node->token_pos(), | 1605 new StaticCallInstr(node->token_pos(), |
| 1562 node->function(), | 1606 node->function(), |
| 1563 node->arguments()->names(), | 1607 node->arguments()->names(), |
| 1564 arguments); | 1608 arguments); |
| 1565 ReturnDefinition(call); | 1609 ReturnDefinition(call); |
| 1566 } | 1610 } |
| 1567 | 1611 |
| 1568 | 1612 |
| 1569 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall( | 1613 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall( |
| 1570 ClosureCallNode* node) { | 1614 ClosureCallNode* node) { |
| 1571 ValueGraphVisitor for_closure(owner(), temp_index()); | 1615 ValueGraphVisitor for_closure(owner(), temp_index(), loop_depth()); |
| 1572 node->closure()->Visit(&for_closure); | 1616 node->closure()->Visit(&for_closure); |
| 1573 Append(for_closure); | 1617 Append(for_closure); |
| 1574 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); | 1618 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); |
| 1575 | 1619 |
| 1576 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1620 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1577 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 1621 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 1578 arguments->Add(push_closure); | 1622 arguments->Add(push_closure); |
| 1579 BuildPushArguments(*node->arguments(), arguments); | 1623 BuildPushArguments(*node->arguments(), arguments); |
| 1580 | 1624 |
| 1581 // Save context around the call. | 1625 // Save context around the call. |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1764 Function& outer_function = | 1808 Function& outer_function = |
| 1765 Function::Handle(owner()->parsed_function().function().raw()); | 1809 Function::Handle(owner()->parsed_function().function().raw()); |
| 1766 while (outer_function.IsLocalFunction()) { | 1810 while (outer_function.IsLocalFunction()) { |
| 1767 outer_function = outer_function.parent_function(); | 1811 outer_function = outer_function.parent_function(); |
| 1768 } | 1812 } |
| 1769 if (outer_function.IsFactory()) { | 1813 if (outer_function.IsFactory()) { |
| 1770 return NULL; | 1814 return NULL; |
| 1771 } | 1815 } |
| 1772 | 1816 |
| 1773 ASSERT(owner()->parsed_function().instantiator() != NULL); | 1817 ASSERT(owner()->parsed_function().instantiator() != NULL); |
| 1774 ValueGraphVisitor for_instantiator(owner(), temp_index()); | 1818 ValueGraphVisitor for_instantiator(owner(), temp_index(), loop_depth()); |
| 1775 owner()->parsed_function().instantiator()->Visit(&for_instantiator); | 1819 owner()->parsed_function().instantiator()->Visit(&for_instantiator); |
| 1776 Append(for_instantiator); | 1820 Append(for_instantiator); |
| 1777 return for_instantiator.value(); | 1821 return for_instantiator.value(); |
| 1778 } | 1822 } |
| 1779 | 1823 |
| 1780 | 1824 |
| 1781 // 'expression_temp_var' may not be used inside this method if 'instantiator' | 1825 // 'expression_temp_var' may not be used inside this method if 'instantiator' |
| 1782 // is not NULL. | 1826 // is not NULL. |
| 1783 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( | 1827 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( |
| 1784 intptr_t token_pos, Value* instantiator) { | 1828 intptr_t token_pos, Value* instantiator) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1799 } | 1843 } |
| 1800 Function& outer_function = | 1844 Function& outer_function = |
| 1801 Function::Handle(owner()->parsed_function().function().raw()); | 1845 Function::Handle(owner()->parsed_function().function().raw()); |
| 1802 while (outer_function.IsLocalFunction()) { | 1846 while (outer_function.IsLocalFunction()) { |
| 1803 outer_function = outer_function.parent_function(); | 1847 outer_function = outer_function.parent_function(); |
| 1804 } | 1848 } |
| 1805 if (outer_function.IsFactory()) { | 1849 if (outer_function.IsFactory()) { |
| 1806 // No instantiator for factories. | 1850 // No instantiator for factories. |
| 1807 ASSERT(instantiator == NULL); | 1851 ASSERT(instantiator == NULL); |
| 1808 ASSERT(owner()->parsed_function().instantiator() != NULL); | 1852 ASSERT(owner()->parsed_function().instantiator() != NULL); |
| 1809 ValueGraphVisitor for_instantiator(owner(), temp_index()); | 1853 ValueGraphVisitor for_instantiator(owner(), temp_index(), loop_depth()); |
| 1810 owner()->parsed_function().instantiator()->Visit(&for_instantiator); | 1854 owner()->parsed_function().instantiator()->Visit(&for_instantiator); |
| 1811 Append(for_instantiator); | 1855 Append(for_instantiator); |
| 1812 return for_instantiator.value(); | 1856 return for_instantiator.value(); |
| 1813 } | 1857 } |
| 1814 if (instantiator == NULL) { | 1858 if (instantiator == NULL) { |
| 1815 instantiator = BuildInstantiator(); | 1859 instantiator = BuildInstantiator(); |
| 1816 } | 1860 } |
| 1817 // The instantiator is the receiver of the caller, which is not a factory. | 1861 // The instantiator is the receiver of the caller, which is not a factory. |
| 1818 // The receiver cannot be null; extract its AbstractTypeArguments object. | 1862 // The receiver cannot be null; extract its AbstractTypeArguments object. |
| 1819 // Note that in the factory case, the instantiator is the first parameter | 1863 // 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... |
| 1947 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); | 1991 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); |
| 1948 BuildConstructorCall(node, push_allocated_value); | 1992 BuildConstructorCall(node, push_allocated_value); |
| 1949 Definition* load_allocated = BuildLoadLocal( | 1993 Definition* load_allocated = BuildLoadLocal( |
| 1950 node->allocated_object_var()); | 1994 node->allocated_object_var()); |
| 1951 allocated_value = Bind(load_allocated); | 1995 allocated_value = Bind(load_allocated); |
| 1952 ReturnValue(allocated_value); | 1996 ReturnValue(allocated_value); |
| 1953 } | 1997 } |
| 1954 | 1998 |
| 1955 | 1999 |
| 1956 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { | 2000 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { |
| 1957 ValueGraphVisitor for_receiver(owner(), temp_index()); | 2001 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); |
| 1958 node->receiver()->Visit(&for_receiver); | 2002 node->receiver()->Visit(&for_receiver); |
| 1959 Append(for_receiver); | 2003 Append(for_receiver); |
| 1960 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 2004 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 1961 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2005 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1962 new ZoneGrowableArray<PushArgumentInstr*>(1); | 2006 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 1963 arguments->Add(push_receiver); | 2007 arguments->Add(push_receiver); |
| 1964 const String& name = | 2008 const String& name = |
| 1965 String::ZoneHandle(Field::GetterSymbol(node->field_name())); | 2009 String::ZoneHandle(Field::GetterSymbol(node->field_name())); |
| 1966 InstanceCallInstr* call = new InstanceCallInstr( | 2010 InstanceCallInstr* call = new InstanceCallInstr( |
| 1967 node->token_pos(), name, Token::kGET, | 2011 node->token_pos(), name, Token::kGET, |
| 1968 arguments, Array::ZoneHandle(), 1); | 2012 arguments, Array::ZoneHandle(), 1); |
| 1969 ReturnDefinition(call); | 2013 ReturnDefinition(call); |
| 1970 } | 2014 } |
| 1971 | 2015 |
| 1972 | 2016 |
| 1973 void EffectGraphVisitor::BuildInstanceSetterArguments( | 2017 void EffectGraphVisitor::BuildInstanceSetterArguments( |
| 1974 InstanceSetterNode* node, | 2018 InstanceSetterNode* node, |
| 1975 ZoneGrowableArray<PushArgumentInstr*>* arguments, | 2019 ZoneGrowableArray<PushArgumentInstr*>* arguments, |
| 1976 bool result_is_needed) { | 2020 bool result_is_needed) { |
| 1977 ValueGraphVisitor for_receiver(owner(), temp_index()); | 2021 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); |
| 1978 node->receiver()->Visit(&for_receiver); | 2022 node->receiver()->Visit(&for_receiver); |
| 1979 Append(for_receiver); | 2023 Append(for_receiver); |
| 1980 arguments->Add(PushArgument(for_receiver.value())); | 2024 arguments->Add(PushArgument(for_receiver.value())); |
| 1981 | 2025 |
| 1982 ValueGraphVisitor for_value(owner(), temp_index()); | 2026 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); |
| 1983 node->value()->Visit(&for_value); | 2027 node->value()->Visit(&for_value); |
| 1984 Append(for_value); | 2028 Append(for_value); |
| 1985 | 2029 |
| 1986 Value* value = NULL; | 2030 Value* value = NULL; |
| 1987 if (result_is_needed) { | 2031 if (result_is_needed) { |
| 1988 value = Bind(BuildStoreExprTemp(for_value.value())); | 2032 value = Bind(BuildStoreExprTemp(for_value.value())); |
| 1989 } else { | 2033 } else { |
| 1990 value = for_value.value(); | 2034 value = for_value.value(); |
| 1991 } | 2035 } |
| 1992 arguments->Add(PushArgument(value)); | 2036 arguments->Add(PushArgument(value)); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2030 String::Handle(Field::GetterName(node->field_name())); | 2074 String::Handle(Field::GetterName(node->field_name())); |
| 2031 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2075 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2032 new ZoneGrowableArray<PushArgumentInstr*>(); | 2076 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 2033 Function& getter_function = Function::ZoneHandle(); | 2077 Function& getter_function = Function::ZoneHandle(); |
| 2034 if (node->is_super_getter()) { | 2078 if (node->is_super_getter()) { |
| 2035 // Statically resolved instance getter, i.e. "super getter". | 2079 // Statically resolved instance getter, i.e. "super getter". |
| 2036 getter_function = | 2080 getter_function = |
| 2037 Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); | 2081 Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); |
| 2038 ASSERT(!getter_function.IsNull()); | 2082 ASSERT(!getter_function.IsNull()); |
| 2039 ASSERT(node->receiver() != NULL); | 2083 ASSERT(node->receiver() != NULL); |
| 2040 ValueGraphVisitor receiver_value(owner(), temp_index()); | 2084 ValueGraphVisitor receiver_value(owner(), temp_index(), loop_depth()); |
| 2041 node->receiver()->Visit(&receiver_value); | 2085 node->receiver()->Visit(&receiver_value); |
| 2042 Append(receiver_value); | 2086 Append(receiver_value); |
| 2043 arguments->Add(PushArgument(receiver_value.value())); | 2087 arguments->Add(PushArgument(receiver_value.value())); |
| 2044 } else { | 2088 } else { |
| 2045 getter_function = node->cls().LookupStaticFunction(getter_name); | 2089 getter_function = node->cls().LookupStaticFunction(getter_name); |
| 2046 if (getter_function.IsNull()) { | 2090 if (getter_function.IsNull()) { |
| 2047 // When the parser encounters a reference to a static field materialized | 2091 // When the parser encounters a reference to a static field materialized |
| 2048 // only by a static setter, but no corresponding static getter, it creates | 2092 // only by a static setter, but no corresponding static getter, it creates |
| 2049 // a StaticGetterNode ast node referring to the non-existing static getter | 2093 // a StaticGetterNode ast node referring to the non-existing static getter |
| 2050 // for the case this field reference appears in a left hand side | 2094 // 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... |
| 2098 const Function& setter_function = | 2142 const Function& setter_function = |
| 2099 Function::ZoneHandle(is_super_setter | 2143 Function::ZoneHandle(is_super_setter |
| 2100 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name) | 2144 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name) |
| 2101 : node->cls().LookupStaticFunction(setter_name)); | 2145 : node->cls().LookupStaticFunction(setter_name)); |
| 2102 ASSERT(!setter_function.IsNull()); | 2146 ASSERT(!setter_function.IsNull()); |
| 2103 | 2147 |
| 2104 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2148 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2105 new ZoneGrowableArray<PushArgumentInstr*>(1); | 2149 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 2106 if (is_super_setter) { | 2150 if (is_super_setter) { |
| 2107 // Add receiver of instance getter. | 2151 // Add receiver of instance getter. |
| 2108 ValueGraphVisitor for_receiver(owner(), temp_index()); | 2152 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); |
| 2109 node->receiver()->Visit(&for_receiver); | 2153 node->receiver()->Visit(&for_receiver); |
| 2110 Append(for_receiver); | 2154 Append(for_receiver); |
| 2111 arguments->Add(PushArgument(for_receiver.value())); | 2155 arguments->Add(PushArgument(for_receiver.value())); |
| 2112 } | 2156 } |
| 2113 ValueGraphVisitor for_value(owner(), temp_index()); | 2157 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); |
| 2114 node->value()->Visit(&for_value); | 2158 node->value()->Visit(&for_value); |
| 2115 Append(for_value); | 2159 Append(for_value); |
| 2116 Value* value = NULL; | 2160 Value* value = NULL; |
| 2117 if (result_is_needed) { | 2161 if (result_is_needed) { |
| 2118 value = Bind(BuildStoreExprTemp(for_value.value())); | 2162 value = Bind(BuildStoreExprTemp(for_value.value())); |
| 2119 } else { | 2163 } else { |
| 2120 value = for_value.value(); | 2164 value = for_value.value(); |
| 2121 } | 2165 } |
| 2122 arguments->Add(PushArgument(value)); | 2166 arguments->Add(PushArgument(value)); |
| 2123 | 2167 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2153 | 2197 |
| 2154 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { | 2198 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { |
| 2155 // PrimaryNodes are temporary during parsing. | 2199 // PrimaryNodes are temporary during parsing. |
| 2156 UNREACHABLE(); | 2200 UNREACHABLE(); |
| 2157 } | 2201 } |
| 2158 | 2202 |
| 2159 | 2203 |
| 2160 // <Expression> ::= LoadLocal { local: LocalVariable } | 2204 // <Expression> ::= LoadLocal { local: LocalVariable } |
| 2161 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { | 2205 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| 2162 if (node->HasPseudo()) { | 2206 if (node->HasPseudo()) { |
| 2163 EffectGraphVisitor for_pseudo(owner(), temp_index()); | 2207 EffectGraphVisitor for_pseudo(owner(), temp_index(), loop_depth()); |
| 2164 node->pseudo()->Visit(&for_pseudo); | 2208 node->pseudo()->Visit(&for_pseudo); |
| 2165 Append(for_pseudo); | 2209 Append(for_pseudo); |
| 2166 } | 2210 } |
| 2167 } | 2211 } |
| 2168 | 2212 |
| 2169 | 2213 |
| 2170 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { | 2214 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| 2171 EffectGraphVisitor::VisitLoadLocalNode(node); | 2215 EffectGraphVisitor::VisitLoadLocalNode(node); |
| 2172 Definition* load = BuildLoadLocal(node->local()); | 2216 Definition* load = BuildLoadLocal(node->local()); |
| 2173 ReturnDefinition(load); | 2217 ReturnDefinition(load); |
| 2174 } | 2218 } |
| 2175 | 2219 |
| 2176 | 2220 |
| 2177 // <Expression> ::= StoreLocal { local: LocalVariable | 2221 // <Expression> ::= StoreLocal { local: LocalVariable |
| 2178 // value: <Expression> } | 2222 // value: <Expression> } |
| 2179 void EffectGraphVisitor::HandleStoreLocal(StoreLocalNode* node, | 2223 void EffectGraphVisitor::HandleStoreLocal(StoreLocalNode* node, |
| 2180 bool result_is_needed) { | 2224 bool result_is_needed) { |
| 2181 ValueGraphVisitor for_value(owner(), temp_index()); | 2225 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); |
| 2182 node->value()->Visit(&for_value); | 2226 node->value()->Visit(&for_value); |
| 2183 Append(for_value); | 2227 Append(for_value); |
| 2184 Value* store_value = for_value.value(); | 2228 Value* store_value = for_value.value(); |
| 2185 if (FLAG_enable_type_checks) { | 2229 if (FLAG_enable_type_checks) { |
| 2186 store_value = BuildAssignableValue(node->value()->token_pos(), | 2230 store_value = BuildAssignableValue(node->value()->token_pos(), |
| 2187 store_value, | 2231 store_value, |
| 2188 node->local().type(), | 2232 node->local().type(), |
| 2189 node->local().name()); | 2233 node->local().name()); |
| 2190 } | 2234 } |
| 2191 Definition* store = BuildStoreLocal(node->local(), | 2235 Definition* store = BuildStoreLocal(node->local(), |
| 2192 store_value, | 2236 store_value, |
| 2193 result_is_needed); | 2237 result_is_needed); |
| 2194 ReturnDefinition(store); | 2238 ReturnDefinition(store); |
| 2195 } | 2239 } |
| 2196 | 2240 |
| 2197 | 2241 |
| 2198 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { | 2242 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| 2199 HandleStoreLocal(node, kResultNotNeeded); | 2243 HandleStoreLocal(node, kResultNotNeeded); |
| 2200 } | 2244 } |
| 2201 | 2245 |
| 2202 | 2246 |
| 2203 void ValueGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { | 2247 void ValueGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| 2204 HandleStoreLocal(node, kResultNeeded); | 2248 HandleStoreLocal(node, kResultNeeded); |
| 2205 } | 2249 } |
| 2206 | 2250 |
| 2207 | 2251 |
| 2208 void EffectGraphVisitor::VisitLoadInstanceFieldNode( | 2252 void EffectGraphVisitor::VisitLoadInstanceFieldNode( |
| 2209 LoadInstanceFieldNode* node) { | 2253 LoadInstanceFieldNode* node) { |
| 2210 ValueGraphVisitor for_instance(owner(), temp_index()); | 2254 ValueGraphVisitor for_instance(owner(), temp_index(), loop_depth()); |
| 2211 node->instance()->Visit(&for_instance); | 2255 node->instance()->Visit(&for_instance); |
| 2212 Append(for_instance); | 2256 Append(for_instance); |
| 2213 LoadFieldInstr* load = new LoadFieldInstr( | 2257 LoadFieldInstr* load = new LoadFieldInstr( |
| 2214 for_instance.value(), | 2258 for_instance.value(), |
| 2215 node->field().Offset(), | 2259 node->field().Offset(), |
| 2216 AbstractType::ZoneHandle(node->field().type())); | 2260 AbstractType::ZoneHandle(node->field().type())); |
| 2217 ReturnDefinition(load); | 2261 ReturnDefinition(load); |
| 2218 } | 2262 } |
| 2219 | 2263 |
| 2220 | 2264 |
| 2221 void EffectGraphVisitor::VisitStoreInstanceFieldNode( | 2265 void EffectGraphVisitor::VisitStoreInstanceFieldNode( |
| 2222 StoreInstanceFieldNode* node) { | 2266 StoreInstanceFieldNode* node) { |
| 2223 ValueGraphVisitor for_instance(owner(), temp_index()); | 2267 ValueGraphVisitor for_instance(owner(), temp_index(), loop_depth()); |
| 2224 node->instance()->Visit(&for_instance); | 2268 node->instance()->Visit(&for_instance); |
| 2225 Append(for_instance); | 2269 Append(for_instance); |
| 2226 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); | 2270 ValueGraphVisitor for_value(owner(), for_instance.temp_index(), loop_depth()); |
| 2227 node->value()->Visit(&for_value); | 2271 node->value()->Visit(&for_value); |
| 2228 Append(for_value); | 2272 Append(for_value); |
| 2229 Value* store_value = for_value.value(); | 2273 Value* store_value = for_value.value(); |
| 2230 if (FLAG_enable_type_checks) { | 2274 if (FLAG_enable_type_checks) { |
| 2231 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 2275 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| 2232 const String& dst_name = String::ZoneHandle(node->field().name()); | 2276 const String& dst_name = String::ZoneHandle(node->field().name()); |
| 2233 store_value = BuildAssignableValue(node->value()->token_pos(), | 2277 store_value = BuildAssignableValue(node->value()->token_pos(), |
| 2234 store_value, | 2278 store_value, |
| 2235 type, | 2279 type, |
| 2236 dst_name); | 2280 dst_name); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2250 | 2294 |
| 2251 | 2295 |
| 2252 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { | 2296 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { |
| 2253 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(node->field()); | 2297 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(node->field()); |
| 2254 ReturnDefinition(load); | 2298 ReturnDefinition(load); |
| 2255 } | 2299 } |
| 2256 | 2300 |
| 2257 | 2301 |
| 2258 Definition* EffectGraphVisitor::BuildStoreStaticField( | 2302 Definition* EffectGraphVisitor::BuildStoreStaticField( |
| 2259 StoreStaticFieldNode* node, bool result_is_needed) { | 2303 StoreStaticFieldNode* node, bool result_is_needed) { |
| 2260 ValueGraphVisitor for_value(owner(), temp_index()); | 2304 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); |
| 2261 node->value()->Visit(&for_value); | 2305 node->value()->Visit(&for_value); |
| 2262 Append(for_value); | 2306 Append(for_value); |
| 2263 Value* store_value = NULL; | 2307 Value* store_value = NULL; |
| 2264 if (result_is_needed) { | 2308 if (result_is_needed) { |
| 2265 store_value = Bind(BuildStoreExprTemp(for_value.value())); | 2309 store_value = Bind(BuildStoreExprTemp(for_value.value())); |
| 2266 } else { | 2310 } else { |
| 2267 store_value = for_value.value(); | 2311 store_value = for_value.value(); |
| 2268 } | 2312 } |
| 2269 if (FLAG_enable_type_checks) { | 2313 if (FLAG_enable_type_checks) { |
| 2270 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 2314 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2314 BuildStaticNoSuchMethodCall(node->super_class(), | 2358 BuildStaticNoSuchMethodCall(node->super_class(), |
| 2315 node->array(), | 2359 node->array(), |
| 2316 index_operator_name, | 2360 index_operator_name, |
| 2317 arguments); | 2361 arguments); |
| 2318 ReturnDefinition(call); | 2362 ReturnDefinition(call); |
| 2319 return; | 2363 return; |
| 2320 } | 2364 } |
| 2321 } | 2365 } |
| 2322 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2366 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2323 new ZoneGrowableArray<PushArgumentInstr*>(2); | 2367 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 2324 ValueGraphVisitor for_array(owner(), temp_index()); | 2368 ValueGraphVisitor for_array(owner(), temp_index(), loop_depth()); |
| 2325 node->array()->Visit(&for_array); | 2369 node->array()->Visit(&for_array); |
| 2326 Append(for_array); | 2370 Append(for_array); |
| 2327 arguments->Add(PushArgument(for_array.value())); | 2371 arguments->Add(PushArgument(for_array.value())); |
| 2328 | 2372 |
| 2329 ValueGraphVisitor for_index(owner(), temp_index()); | 2373 ValueGraphVisitor for_index(owner(), temp_index(), loop_depth()); |
| 2330 node->index_expr()->Visit(&for_index); | 2374 node->index_expr()->Visit(&for_index); |
| 2331 Append(for_index); | 2375 Append(for_index); |
| 2332 arguments->Add(PushArgument(for_index.value())); | 2376 arguments->Add(PushArgument(for_index.value())); |
| 2333 | 2377 |
| 2334 if (super_function != NULL) { | 2378 if (super_function != NULL) { |
| 2335 // Generate static call to super operator. | 2379 // Generate static call to super operator. |
| 2336 StaticCallInstr* load = new StaticCallInstr(node->token_pos(), | 2380 StaticCallInstr* load = new StaticCallInstr(node->token_pos(), |
| 2337 *super_function, | 2381 *super_function, |
| 2338 Array::ZoneHandle(), | 2382 Array::ZoneHandle(), |
| 2339 arguments); | 2383 arguments); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2363 String::ZoneHandle(Symbols::AssignIndexToken()); | 2407 String::ZoneHandle(Symbols::AssignIndexToken()); |
| 2364 super_function = &Function::ZoneHandle( | 2408 super_function = &Function::ZoneHandle( |
| 2365 Resolver::ResolveDynamicAnyArgs(node->super_class(), | 2409 Resolver::ResolveDynamicAnyArgs(node->super_class(), |
| 2366 store_index_op_name)); | 2410 store_index_op_name)); |
| 2367 if (super_function->IsNull()) { | 2411 if (super_function->IsNull()) { |
| 2368 // Could not resolve super operator. Generate call noSuchMethod() of the | 2412 // Could not resolve super operator. Generate call noSuchMethod() of the |
| 2369 // super class instead. | 2413 // super class instead. |
| 2370 if (result_is_needed) { | 2414 if (result_is_needed) { |
| 2371 // Even though noSuchMethod most likely does not return, | 2415 // Even though noSuchMethod most likely does not return, |
| 2372 // we save the stored value if the result is needed. | 2416 // we save the stored value if the result is needed. |
| 2373 ValueGraphVisitor for_value(owner(), temp_index()); | 2417 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); |
| 2374 node->value()->Visit(&for_value); | 2418 node->value()->Visit(&for_value); |
| 2375 Append(for_value); | 2419 Append(for_value); |
| 2376 Bind(BuildStoreExprTemp(for_value.value())); | 2420 Bind(BuildStoreExprTemp(for_value.value())); |
| 2377 } | 2421 } |
| 2378 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); | 2422 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); |
| 2379 arguments->Add(node->index_expr()); | 2423 arguments->Add(node->index_expr()); |
| 2380 arguments->Add(node->value()); | 2424 arguments->Add(node->value()); |
| 2381 StaticCallInstr* call = | 2425 StaticCallInstr* call = |
| 2382 BuildStaticNoSuchMethodCall(node->super_class(), | 2426 BuildStaticNoSuchMethodCall(node->super_class(), |
| 2383 node->array(), | 2427 node->array(), |
| 2384 store_index_op_name, | 2428 store_index_op_name, |
| 2385 arguments); | 2429 arguments); |
| 2386 if (result_is_needed) { | 2430 if (result_is_needed) { |
| 2387 Do(call); | 2431 Do(call); |
| 2388 return BuildLoadExprTemp(); | 2432 return BuildLoadExprTemp(); |
| 2389 } else { | 2433 } else { |
| 2390 return call; | 2434 return call; |
| 2391 } | 2435 } |
| 2392 } | 2436 } |
| 2393 } | 2437 } |
| 2394 | 2438 |
| 2395 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2439 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2396 new ZoneGrowableArray<PushArgumentInstr*>(3); | 2440 new ZoneGrowableArray<PushArgumentInstr*>(3); |
| 2397 ValueGraphVisitor for_array(owner(), temp_index()); | 2441 ValueGraphVisitor for_array(owner(), temp_index(), loop_depth()); |
| 2398 node->array()->Visit(&for_array); | 2442 node->array()->Visit(&for_array); |
| 2399 Append(for_array); | 2443 Append(for_array); |
| 2400 arguments->Add(PushArgument(for_array.value())); | 2444 arguments->Add(PushArgument(for_array.value())); |
| 2401 | 2445 |
| 2402 ValueGraphVisitor for_index(owner(), temp_index()); | 2446 ValueGraphVisitor for_index(owner(), temp_index(), loop_depth()); |
| 2403 node->index_expr()->Visit(&for_index); | 2447 node->index_expr()->Visit(&for_index); |
| 2404 Append(for_index); | 2448 Append(for_index); |
| 2405 arguments->Add(PushArgument(for_index.value())); | 2449 arguments->Add(PushArgument(for_index.value())); |
| 2406 | 2450 |
| 2407 ValueGraphVisitor for_value(owner(), temp_index()); | 2451 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); |
| 2408 node->value()->Visit(&for_value); | 2452 node->value()->Visit(&for_value); |
| 2409 Append(for_value); | 2453 Append(for_value); |
| 2410 Value* value = NULL; | 2454 Value* value = NULL; |
| 2411 if (result_is_needed) { | 2455 if (result_is_needed) { |
| 2412 value = Bind(BuildStoreExprTemp(for_value.value())); | 2456 value = Bind(BuildStoreExprTemp(for_value.value())); |
| 2413 } else { | 2457 } else { |
| 2414 value = for_value.value(); | 2458 value = for_value.value(); |
| 2415 } | 2459 } |
| 2416 arguments->Add(PushArgument(value)); | 2460 arguments->Add(PushArgument(value)); |
| 2417 | 2461 |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2581 // variable so that ssa renaming detects the dependency and makes use | 2625 // variable so that ssa renaming detects the dependency and makes use |
| 2582 // of the checked type in type propagation. | 2626 // of the checked type in type propagation. |
| 2583 Do(BuildStoreLocal(parameter, parameter_value, kResultNotNeeded)); | 2627 Do(BuildStoreLocal(parameter, parameter_value, kResultNotNeeded)); |
| 2584 } | 2628 } |
| 2585 pos++; | 2629 pos++; |
| 2586 } | 2630 } |
| 2587 } | 2631 } |
| 2588 | 2632 |
| 2589 intptr_t i = 0; | 2633 intptr_t i = 0; |
| 2590 while (is_open() && (i < node->length())) { | 2634 while (is_open() && (i < node->length())) { |
| 2591 EffectGraphVisitor for_effect(owner(), temp_index()); | 2635 EffectGraphVisitor for_effect(owner(), temp_index(), loop_depth()); |
| 2592 node->NodeAt(i++)->Visit(&for_effect); | 2636 node->NodeAt(i++)->Visit(&for_effect); |
| 2593 Append(for_effect); | 2637 Append(for_effect); |
| 2594 if (!is_open()) { | 2638 if (!is_open()) { |
| 2595 // E.g., because of a JumpNode. | 2639 // E.g., because of a JumpNode. |
| 2596 break; | 2640 break; |
| 2597 } | 2641 } |
| 2598 } | 2642 } |
| 2599 | 2643 |
| 2600 if (is_open()) { | 2644 if (is_open()) { |
| 2601 if (MustSaveRestoreContext(node)) { | 2645 if (MustSaveRestoreContext(node)) { |
| 2602 ASSERT(num_context_variables > 0); | 2646 ASSERT(num_context_variables > 0); |
| 2603 BuildLoadContext(*owner()->parsed_function().saved_context_var()); | 2647 BuildLoadContext(*owner()->parsed_function().saved_context_var()); |
| 2604 } else if (num_context_variables > 0) { | 2648 } else if (num_context_variables > 0) { |
| 2605 UnchainContext(); | 2649 UnchainContext(); |
| 2606 } | 2650 } |
| 2607 } | 2651 } |
| 2608 | 2652 |
| 2609 // No continue on sequence allowed. | 2653 // No continue on sequence allowed. |
| 2610 ASSERT((node->label() == NULL) || | 2654 ASSERT((node->label() == NULL) || |
| 2611 (node->label()->join_for_continue() == NULL)); | 2655 (node->label()->join_for_continue() == NULL)); |
| 2612 // If this node sequence is labeled, a break out of the sequence will have | 2656 // If this node sequence is labeled, a break out of the sequence will have |
| 2613 // taken care of unchaining the context. | 2657 // taken care of unchaining the context. |
| 2614 if ((node->label() != NULL) && | 2658 if ((node->label() != NULL) && |
| 2615 (node->label()->join_for_break() != NULL)) { | 2659 (node->label()->join_for_break() != NULL)) { |
| 2660 node->label()->join_for_break()->set_loop_depth(loop_depth()); |
| 2616 if (is_open()) Goto(node->label()->join_for_break()); | 2661 if (is_open()) Goto(node->label()->join_for_break()); |
| 2617 exit_ = node->label()->join_for_break(); | 2662 exit_ = node->label()->join_for_break(); |
| 2618 } | 2663 } |
| 2619 | 2664 |
| 2620 // The outermost function sequence cannot contain a label. | 2665 // The outermost function sequence cannot contain a label. |
| 2621 ASSERT((node->label() == NULL) || | 2666 ASSERT((node->label() == NULL) || |
| 2622 (node != owner()->parsed_function().node_sequence())); | 2667 (node != owner()->parsed_function().node_sequence())); |
| 2623 owner()->set_context_level(previous_context_level); | 2668 owner()->set_context_level(previous_context_level); |
| 2624 } | 2669 } |
| 2625 | 2670 |
| 2626 | 2671 |
| 2627 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { | 2672 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { |
| 2628 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)"); | 2673 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)"); |
| 2629 // NOTE: The implicit variables ':saved_context', ':exception_var' | 2674 // NOTE: The implicit variables ':saved_context', ':exception_var' |
| 2630 // and ':stacktrace_var' can never be captured variables. | 2675 // and ':stacktrace_var' can never be captured variables. |
| 2631 // Restores CTX from local variable ':saved_context'. | 2676 // Restores CTX from local variable ':saved_context'. |
| 2632 AddInstruction( | 2677 AddInstruction( |
| 2633 new CatchEntryInstr(node->exception_var(), node->stacktrace_var())); | 2678 new CatchEntryInstr(node->exception_var(), node->stacktrace_var())); |
| 2634 BuildLoadContext(node->context_var()); | 2679 BuildLoadContext(node->context_var()); |
| 2635 | 2680 |
| 2636 EffectGraphVisitor for_catch(owner(), temp_index()); | 2681 EffectGraphVisitor for_catch(owner(), temp_index(), loop_depth()); |
| 2637 node->VisitChildren(&for_catch); | 2682 node->VisitChildren(&for_catch); |
| 2638 Append(for_catch); | 2683 Append(for_catch); |
| 2639 } | 2684 } |
| 2640 | 2685 |
| 2641 | 2686 |
| 2642 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { | 2687 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { |
| 2643 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); | 2688 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); |
| 2644 intptr_t old_try_index = owner()->try_index(); | 2689 intptr_t old_try_index = owner()->try_index(); |
| 2645 intptr_t try_index = owner()->AllocateTryIndex(); | 2690 intptr_t try_index = owner()->AllocateTryIndex(); |
| 2646 owner()->set_try_index(try_index); | 2691 owner()->set_try_index(try_index); |
| 2647 | 2692 |
| 2648 // Preserve CTX into local variable '%saved_context'. | 2693 // Preserve CTX into local variable '%saved_context'. |
| 2649 BuildStoreContext(node->context_var()); | 2694 BuildStoreContext(node->context_var()); |
| 2650 | 2695 |
| 2651 EffectGraphVisitor for_try_block(owner(), temp_index()); | 2696 EffectGraphVisitor for_try_block(owner(), temp_index(), loop_depth()); |
| 2652 node->try_block()->Visit(&for_try_block); | 2697 node->try_block()->Visit(&for_try_block); |
| 2653 | 2698 |
| 2654 if (for_try_block.is_open()) { | 2699 if (for_try_block.is_open()) { |
| 2655 JoinEntryInstr* after_try = | 2700 JoinEntryInstr* after_try = |
| 2656 new JoinEntryInstr(owner()->AllocateBlockId(), old_try_index); | 2701 new JoinEntryInstr(owner()->AllocateBlockId(), |
| 2702 old_try_index, |
| 2703 loop_depth()); |
| 2657 for_try_block.Goto(after_try); | 2704 for_try_block.Goto(after_try); |
| 2658 for_try_block.exit_ = after_try; | 2705 for_try_block.exit_ = after_try; |
| 2659 } | 2706 } |
| 2660 | 2707 |
| 2661 JoinEntryInstr* try_entry = | 2708 JoinEntryInstr* try_entry = |
| 2662 new JoinEntryInstr(owner()->AllocateBlockId(), try_index); | 2709 new JoinEntryInstr(owner()->AllocateBlockId(), try_index, loop_depth()); |
| 2663 | 2710 |
| 2664 Goto(try_entry); | 2711 Goto(try_entry); |
| 2665 AppendFragment(try_entry, for_try_block); | 2712 AppendFragment(try_entry, for_try_block); |
| 2666 exit_ = for_try_block.exit_; | 2713 exit_ = for_try_block.exit_; |
| 2667 | 2714 |
| 2668 // We are done generating code for the try block. | 2715 // We are done generating code for the try block. |
| 2669 owner()->set_try_index(old_try_index); | 2716 owner()->set_try_index(old_try_index); |
| 2670 | 2717 |
| 2671 CatchClauseNode* catch_block = node->catch_block(); | 2718 CatchClauseNode* catch_block = node->catch_block(); |
| 2672 if (catch_block != NULL) { | 2719 if (catch_block != NULL) { |
| 2673 // Set the corresponding try index for this catch block so | 2720 // Set the corresponding try index for this catch block so |
| 2674 // that we can set the appropriate handler pc when we generate | 2721 // that we can set the appropriate handler pc when we generate |
| 2675 // code for this catch block. | 2722 // code for this catch block. |
| 2676 catch_block->set_try_index(try_index); | 2723 catch_block->set_try_index(try_index); |
| 2677 EffectGraphVisitor for_catch_block(owner(), temp_index()); | 2724 EffectGraphVisitor for_catch_block(owner(), temp_index(), loop_depth()); |
| 2678 catch_block->Visit(&for_catch_block); | 2725 catch_block->Visit(&for_catch_block); |
| 2679 TargetEntryInstr* catch_entry = | 2726 TargetEntryInstr* catch_entry = |
| 2680 new TargetEntryInstr(owner()->AllocateBlockId(), old_try_index); | 2727 new TargetEntryInstr(owner()->AllocateBlockId(), |
| 2728 old_try_index, |
| 2729 loop_depth()); |
| 2681 catch_entry->set_catch_try_index(try_index); | 2730 catch_entry->set_catch_try_index(try_index); |
| 2682 owner()->AddCatchEntry(catch_entry); | 2731 owner()->AddCatchEntry(catch_entry); |
| 2683 ASSERT(!for_catch_block.is_open()); | 2732 ASSERT(!for_catch_block.is_open()); |
| 2684 AppendFragment(catch_entry, for_catch_block); | 2733 AppendFragment(catch_entry, for_catch_block); |
| 2685 if (node->end_catch_label() != NULL) { | 2734 if (node->end_catch_label() != NULL) { |
| 2686 JoinEntryInstr* join = node->end_catch_label()->join_for_continue(); | 2735 JoinEntryInstr* join = node->end_catch_label()->join_for_continue(); |
| 2687 if (join != NULL) { | 2736 if (join != NULL) { |
| 2737 join->set_loop_depth(loop_depth()); |
| 2688 if (is_open()) Goto(join); | 2738 if (is_open()) Goto(join); |
| 2689 exit_ = join; | 2739 exit_ = join; |
| 2690 } | 2740 } |
| 2691 } | 2741 } |
| 2692 } | 2742 } |
| 2693 | 2743 |
| 2694 // Generate code for the finally block if one exists. | 2744 // Generate code for the finally block if one exists. |
| 2695 if ((node->finally_block() != NULL) && is_open()) { | 2745 if ((node->finally_block() != NULL) && is_open()) { |
| 2696 EffectGraphVisitor for_finally_block(owner(), temp_index()); | 2746 EffectGraphVisitor for_finally_block(owner(), temp_index(), loop_depth()); |
| 2697 node->finally_block()->Visit(&for_finally_block); | 2747 node->finally_block()->Visit(&for_finally_block); |
| 2698 Append(for_finally_block); | 2748 Append(for_finally_block); |
| 2699 } | 2749 } |
| 2700 } | 2750 } |
| 2701 | 2751 |
| 2702 | 2752 |
| 2703 // Looks up dynamic method noSuchMethod in target_class | 2753 // Looks up dynamic method noSuchMethod in target_class |
| 2704 // (including its super class chain) and builds a static call to it. | 2754 // (including its super class chain) and builds a static call to it. |
| 2705 StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall( | 2755 StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall( |
| 2706 const Class& target_class, | 2756 const Class& target_class, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2717 const String& function_name = String::Handle( | 2767 const String& function_name = String::Handle( |
| 2718 Symbols::AllocateInvocationMirror()); | 2768 Symbols::AllocateInvocationMirror()); |
| 2719 const Function& allocation_function = Function::ZoneHandle( | 2769 const Function& allocation_function = Function::ZoneHandle( |
| 2720 Resolver::ResolveStaticByName(mirror_class, | 2770 Resolver::ResolveStaticByName(mirror_class, |
| 2721 function_name, | 2771 function_name, |
| 2722 Resolver::kIsQualified)); | 2772 Resolver::kIsQualified)); |
| 2723 ASSERT(!allocation_function.IsNull()); | 2773 ASSERT(!allocation_function.IsNull()); |
| 2724 | 2774 |
| 2725 // Evaluate the receiver before the arguments. This will be used | 2775 // Evaluate the receiver before the arguments. This will be used |
| 2726 // as an argument to the noSuchMethod call. | 2776 // as an argument to the noSuchMethod call. |
| 2727 ValueGraphVisitor for_receiver(owner(), temp_index()); | 2777 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); |
| 2728 receiver->Visit(&for_receiver); | 2778 receiver->Visit(&for_receiver); |
| 2729 Append(for_receiver); | 2779 Append(for_receiver); |
| 2730 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 2780 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 2731 | 2781 |
| 2732 // Allocate the arguments and pass them into the construction | 2782 // Allocate the arguments and pass them into the construction |
| 2733 // of the InvocationMirror. | 2783 // of the InvocationMirror. |
| 2734 const intptr_t args_pos = method_arguments->token_pos(); | 2784 const intptr_t args_pos = method_arguments->token_pos(); |
| 2735 ArgumentListNode* arguments = new ArgumentListNode(args_pos); | 2785 ArgumentListNode* arguments = new ArgumentListNode(args_pos); |
| 2736 // The first argument is the original method name. | 2786 // The first argument is the original method name. |
| 2737 arguments->Add(new LiteralNode(args_pos, method_name)); | 2787 arguments->Add(new LiteralNode(args_pos, method_name)); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2766 no_such_method_func, | 2816 no_such_method_func, |
| 2767 Array::ZoneHandle(), | 2817 Array::ZoneHandle(), |
| 2768 args); | 2818 args); |
| 2769 } | 2819 } |
| 2770 | 2820 |
| 2771 | 2821 |
| 2772 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { | 2822 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { |
| 2773 // TODO(kmillikin) non-local control flow is not handled correctly | 2823 // TODO(kmillikin) non-local control flow is not handled correctly |
| 2774 // by the inliner. | 2824 // by the inliner. |
| 2775 InlineBailout("EffectGraphVisitor::BuildThrowNode (exception)"); | 2825 InlineBailout("EffectGraphVisitor::BuildThrowNode (exception)"); |
| 2776 ValueGraphVisitor for_exception(owner(), temp_index()); | 2826 ValueGraphVisitor for_exception(owner(), temp_index(), loop_depth()); |
| 2777 node->exception()->Visit(&for_exception); | 2827 node->exception()->Visit(&for_exception); |
| 2778 Append(for_exception); | 2828 Append(for_exception); |
| 2779 PushArgument(for_exception.value()); | 2829 PushArgument(for_exception.value()); |
| 2780 Instruction* instr = NULL; | 2830 Instruction* instr = NULL; |
| 2781 if (node->stacktrace() == NULL) { | 2831 if (node->stacktrace() == NULL) { |
| 2782 instr = new ThrowInstr(node->token_pos()); | 2832 instr = new ThrowInstr(node->token_pos()); |
| 2783 } else { | 2833 } else { |
| 2784 ValueGraphVisitor for_stack_trace(owner(), temp_index()); | 2834 ValueGraphVisitor for_stack_trace(owner(), temp_index(), loop_depth()); |
| 2785 node->stacktrace()->Visit(&for_stack_trace); | 2835 node->stacktrace()->Visit(&for_stack_trace); |
| 2786 Append(for_stack_trace); | 2836 Append(for_stack_trace); |
| 2787 PushArgument(for_stack_trace.value()); | 2837 PushArgument(for_stack_trace.value()); |
| 2788 instr = new ReThrowInstr(node->token_pos()); | 2838 instr = new ReThrowInstr(node->token_pos()); |
| 2789 } | 2839 } |
| 2790 AddInstruction(instr); | 2840 AddInstruction(instr); |
| 2791 } | 2841 } |
| 2792 | 2842 |
| 2793 | 2843 |
| 2794 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { | 2844 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2811 const intptr_t try_index = owner()->try_index(); | 2861 const intptr_t try_index = owner()->try_index(); |
| 2812 if (try_index >= 0) { | 2862 if (try_index >= 0) { |
| 2813 // We are about to generate code for an inlined finally block. Exceptions | 2863 // We are about to generate code for an inlined finally block. Exceptions |
| 2814 // thrown in this block of code should be treated as though they are | 2864 // thrown in this block of code should be treated as though they are |
| 2815 // thrown not from the current try block but the outer try block if any. | 2865 // thrown not from the current try block but the outer try block if any. |
| 2816 owner()->set_try_index((try_index - 1)); | 2866 owner()->set_try_index((try_index - 1)); |
| 2817 } | 2867 } |
| 2818 BuildLoadContext(node->context_var()); | 2868 BuildLoadContext(node->context_var()); |
| 2819 | 2869 |
| 2820 JoinEntryInstr* finally_entry = | 2870 JoinEntryInstr* finally_entry = |
| 2821 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 2871 new JoinEntryInstr(owner()->AllocateBlockId(), |
| 2822 EffectGraphVisitor for_finally_block(owner(), temp_index()); | 2872 owner()->try_index(), |
| 2873 loop_depth()); |
| 2874 EffectGraphVisitor for_finally_block(owner(), temp_index(), loop_depth()); |
| 2823 node->finally_block()->Visit(&for_finally_block); | 2875 node->finally_block()->Visit(&for_finally_block); |
| 2824 | 2876 |
| 2825 if (try_index >= 0) { | 2877 if (try_index >= 0) { |
| 2826 owner()->set_try_index(try_index); | 2878 owner()->set_try_index(try_index); |
| 2827 } | 2879 } |
| 2828 | 2880 |
| 2829 if (for_finally_block.is_open()) { | 2881 if (for_finally_block.is_open()) { |
| 2830 JoinEntryInstr* after_finally = | 2882 JoinEntryInstr* after_finally = |
| 2831 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 2883 new JoinEntryInstr(owner()->AllocateBlockId(), |
| 2884 owner()->try_index(), |
| 2885 loop_depth()); |
| 2832 for_finally_block.Goto(after_finally); | 2886 for_finally_block.Goto(after_finally); |
| 2833 for_finally_block.exit_ = after_finally; | 2887 for_finally_block.exit_ = after_finally; |
| 2834 } | 2888 } |
| 2835 | 2889 |
| 2836 Goto(finally_entry); | 2890 Goto(finally_entry); |
| 2837 AppendFragment(finally_entry, for_finally_block); | 2891 AppendFragment(finally_entry, for_finally_block); |
| 2838 exit_ = for_finally_block.exit_; | 2892 exit_ = for_finally_block.exit_; |
| 2839 } | 2893 } |
| 2840 | 2894 |
| 2841 | 2895 |
| 2842 FlowGraph* FlowGraphBuilder::BuildGraph(InliningContext context) { | 2896 FlowGraph* FlowGraphBuilder::BuildGraph(InliningContext context, |
| 2897 intptr_t initial_loop_depth) { |
| 2843 if (FLAG_print_ast) { | 2898 if (FLAG_print_ast) { |
| 2844 // Print the function ast before IL generation. | 2899 // Print the function ast before IL generation. |
| 2845 AstPrinter::PrintFunctionNodes(parsed_function()); | 2900 AstPrinter::PrintFunctionNodes(parsed_function()); |
| 2846 } | 2901 } |
| 2847 // Set the inlining context. | 2902 // Set the inlining context. |
| 2848 ASSERT(inlining_context_ == kNotInlining); | 2903 ASSERT(inlining_context_ == kNotInlining); |
| 2849 inlining_context_ = context; | 2904 inlining_context_ = context; |
| 2850 if (InInliningContext()) exits_ = new ZoneGrowableArray<ReturnInstr*>(); | 2905 if (InInliningContext()) exits_ = new ZoneGrowableArray<ReturnInstr*>(); |
| 2851 // Compilation can be nested, preserve the computation-id. | 2906 // Compilation can be nested, preserve the computation-id. |
| 2852 const Function& function = parsed_function().function(); | 2907 const Function& function = parsed_function().function(); |
| 2853 TargetEntryInstr* normal_entry = | 2908 TargetEntryInstr* normal_entry = |
| 2854 new TargetEntryInstr(AllocateBlockId(), | 2909 new TargetEntryInstr(AllocateBlockId(), |
| 2855 CatchClauseNode::kInvalidTryIndex); | 2910 CatchClauseNode::kInvalidTryIndex, |
| 2911 initial_loop_depth); |
| 2856 graph_entry_ = new GraphEntryInstr(normal_entry); | 2912 graph_entry_ = new GraphEntryInstr(normal_entry); |
| 2857 EffectGraphVisitor for_effect(this, 0); | 2913 EffectGraphVisitor for_effect(this, 0, initial_loop_depth); |
| 2858 if (InInliningContext()) { | 2914 if (InInliningContext()) { |
| 2859 exits_ = new ZoneGrowableArray<ReturnInstr*>(); | 2915 exits_ = new ZoneGrowableArray<ReturnInstr*>(); |
| 2860 } | 2916 } |
| 2861 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the | 2917 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the |
| 2862 // stack check on entry for leaf routines). | 2918 // stack check on entry for leaf routines). |
| 2863 Instruction* check = new CheckStackOverflowInstr(function.token_pos()); | 2919 Instruction* check = new CheckStackOverflowInstr(function.token_pos()); |
| 2864 // If we are inlining don't actually attach the stack check. We must still | 2920 // If we are inlining don't actually attach the stack check. We must still |
| 2865 // create the stack check inorder to allocate a deopt id. | 2921 // create the stack check inorder to allocate a deopt id. |
| 2866 if (!InInliningContext()) for_effect.AddInstruction(check); | 2922 if (!InInliningContext()) for_effect.AddInstruction(check); |
| 2867 parsed_function().node_sequence()->Visit(&for_effect); | 2923 parsed_function().node_sequence()->Visit(&for_effect); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2880 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 2936 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 2881 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 2937 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 2882 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2938 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2883 const Error& error = Error::Handle( | 2939 const Error& error = Error::Handle( |
| 2884 LanguageError::New(String::Handle(String::New(chars)))); | 2940 LanguageError::New(String::Handle(String::New(chars)))); |
| 2885 Isolate::Current()->long_jump_base()->Jump(1, error); | 2941 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2886 } | 2942 } |
| 2887 | 2943 |
| 2888 | 2944 |
| 2889 } // namespace dart | 2945 } // namespace dart |
| OLD | NEW |