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

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

Issue 11975061: Removed loop depth info tracking at graph build time. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_builder.h" 5 #include "vm/flow_graph_builder.h"
6 6
7 #include "vm/ast_printer.h" 7 #include "vm/ast_printer.h"
8 #include "vm/code_descriptors.h" 8 #include "vm/code_descriptors.h"
9 #include "vm/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flags.h" 10 #include "vm/flags.h"
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 197
198 // 3. Add a join or select one (or neither) of the arms as exit. 198 // 3. Add a join or select one (or neither) of the arms as exit.
199 if (true_exit == NULL) { 199 if (true_exit == NULL) {
200 exit_ = false_exit; // May be NULL. 200 exit_ = false_exit; // May be NULL.
201 if (false_exit != NULL) temp_index_ = false_fragment.temp_index(); 201 if (false_exit != NULL) temp_index_ = false_fragment.temp_index();
202 } else if (false_exit == NULL) { 202 } else if (false_exit == NULL) {
203 exit_ = true_exit; 203 exit_ = true_exit;
204 temp_index_ = true_fragment.temp_index(); 204 temp_index_ = true_fragment.temp_index();
205 } else { 205 } else {
206 JoinEntryInstr* join = 206 JoinEntryInstr* join =
207 new JoinEntryInstr(owner()->AllocateBlockId(), 207 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
208 owner()->try_index(),
209 loop_depth());
210 true_exit->Goto(join); 208 true_exit->Goto(join);
211 false_exit->Goto(join); 209 false_exit->Goto(join);
212 exit_ = join; 210 exit_ = join;
213 ASSERT(true_fragment.temp_index() == false_fragment.temp_index()); 211 ASSERT(true_fragment.temp_index() == false_fragment.temp_index());
214 temp_index_ = true_fragment.temp_index(); 212 temp_index_ = true_fragment.temp_index();
215 } 213 }
216 } 214 }
217 215
218 216
219 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment, 217 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment,
220 const EffectGraphVisitor& body_fragment) { 218 const EffectGraphVisitor& body_fragment) {
221 // We have: a test graph fragment with zero, one, or two available exits; 219 // We have: a test graph fragment with zero, one, or two available exits;
222 // and an effect graph fragment with zero or one available exits. We want 220 // and an effect graph fragment with zero or one available exits. We want
223 // to append the 'while loop' consisting of the test graph fragment as 221 // to append the 'while loop' consisting of the test graph fragment as
224 // condition and the effect graph fragment as body. 222 // condition and the effect graph fragment as body.
225 ASSERT(is_open()); 223 ASSERT(is_open());
226 224
227 // 1. Connect the body to the test if it is reachable, and if so record 225 // 1. Connect the body to the test if it is reachable, and if so record
228 // its exit (if any). 226 // its exit (if any).
229 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor(); 227 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor();
230 Instruction* body_exit = AppendFragment(body_entry, body_fragment); 228 Instruction* body_exit = AppendFragment(body_entry, body_fragment);
231 229
232 // 2. Connect the test to this graph, including the body if reachable and 230 // 2. Connect the test to this graph, including the body if reachable and
233 // using a fresh join node if the body is reachable and has an open exit. 231 // using a fresh join node if the body is reachable and has an open exit.
234 if (body_exit == NULL) { 232 if (body_exit == NULL) {
235 Append(test_fragment); 233 Append(test_fragment);
236 } else { 234 } else {
237 JoinEntryInstr* join = 235 JoinEntryInstr* join =
238 new JoinEntryInstr(owner()->AllocateBlockId(), 236 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
239 owner()->try_index(),
240 loop_depth() + 1);
241 join->LinkTo(test_fragment.entry()); 237 join->LinkTo(test_fragment.entry());
242 Goto(join); 238 Goto(join);
243 body_exit->Goto(join); 239 body_exit->Goto(join);
244 } 240 }
245 241
246 // 3. Set the exit to the graph to be the false successor of the test, a 242 // 3. Set the exit to the graph to be the false successor of the test, a
247 // fresh target node 243 // fresh target node
248 244
249 exit_ = test_fragment.CreateFalseSuccessor(); 245 exit_ = test_fragment.CreateFalseSuccessor();
250 } 246 }
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 AddInstruction(new StoreContextInstr(load_saved_context)); 338 AddInstruction(new StoreContextInstr(load_saved_context));
343 } 339 }
344 340
345 341
346 void TestGraphVisitor::ConnectBranchesTo( 342 void TestGraphVisitor::ConnectBranchesTo(
347 const GrowableArray<TargetEntryInstr**>& branches, 343 const GrowableArray<TargetEntryInstr**>& branches,
348 JoinEntryInstr* join) const { 344 JoinEntryInstr* join) const {
349 ASSERT(!branches.is_empty()); 345 ASSERT(!branches.is_empty());
350 for (intptr_t i = 0; i < branches.length(); i++) { 346 for (intptr_t i = 0; i < branches.length(); i++) {
351 TargetEntryInstr* target = 347 TargetEntryInstr* target =
352 new TargetEntryInstr(owner()->AllocateBlockId(), 348 new TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
353 owner()->try_index(),
354 loop_depth());
355 *(branches[i]) = target; 349 *(branches[i]) = target;
356 target->Goto(join); 350 target->Goto(join);
357 } 351 }
358 } 352 }
359 353
360 354
361 void TestGraphVisitor::IfTrueGoto(JoinEntryInstr* join) const { 355 void TestGraphVisitor::IfTrueGoto(JoinEntryInstr* join) const {
362 ConnectBranchesTo(true_successor_addresses_, join); 356 ConnectBranchesTo(true_successor_addresses_, join);
363 } 357 }
364 358
365 359
366 void TestGraphVisitor::IfFalseGoto(JoinEntryInstr* join) const { 360 void TestGraphVisitor::IfFalseGoto(JoinEntryInstr* join) const {
367 ConnectBranchesTo(false_successor_addresses_, join); 361 ConnectBranchesTo(false_successor_addresses_, join);
368 } 362 }
369 363
370 364
371 BlockEntryInstr* TestGraphVisitor::CreateSuccessorFor( 365 BlockEntryInstr* TestGraphVisitor::CreateSuccessorFor(
372 const GrowableArray<TargetEntryInstr**>& branches) const { 366 const GrowableArray<TargetEntryInstr**>& branches) const {
373 ASSERT(!branches.is_empty()); 367 ASSERT(!branches.is_empty());
374 368
375 if (branches.length() == 1) { 369 if (branches.length() == 1) {
376 TargetEntryInstr* target = 370 TargetEntryInstr* target =
377 new TargetEntryInstr(owner()->AllocateBlockId(), 371 new TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
378 owner()->try_index(),
379 loop_depth());
380 *(branches[0]) = target; 372 *(branches[0]) = target;
381 return target; 373 return target;
382 } 374 }
383 375
384 JoinEntryInstr* join = 376 JoinEntryInstr* join =
385 new JoinEntryInstr(owner()->AllocateBlockId(), 377 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
386 owner()->try_index(),
387 loop_depth());
388 ConnectBranchesTo(branches, join); 378 ConnectBranchesTo(branches, join);
389 return join; 379 return join;
390 } 380 }
391 381
392 382
393 BlockEntryInstr* TestGraphVisitor::CreateTrueSuccessor() const { 383 BlockEntryInstr* TestGraphVisitor::CreateTrueSuccessor() const {
394 return CreateSuccessorFor(true_successor_addresses_); 384 return CreateSuccessorFor(true_successor_addresses_);
395 } 385 }
396 386
397 387
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 } 458 }
469 459
470 460
471 // Special handling for AND/OR. 461 // Special handling for AND/OR.
472 void TestGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { 462 void TestGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
473 // Operators "&&" and "||" cannot be overloaded therefore do not call 463 // Operators "&&" and "||" cannot be overloaded therefore do not call
474 // operator. 464 // operator.
475 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { 465 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
476 TestGraphVisitor for_left(owner(), 466 TestGraphVisitor for_left(owner(),
477 temp_index(), 467 temp_index(),
478 loop_depth(),
479 node->left()->token_pos()); 468 node->left()->token_pos());
480 node->left()->Visit(&for_left); 469 node->left()->Visit(&for_left);
481 470
482 TestGraphVisitor for_right(owner(), 471 TestGraphVisitor for_right(owner(),
483 temp_index(), 472 temp_index(),
484 loop_depth(),
485 node->right()->token_pos()); 473 node->right()->token_pos());
486 node->right()->Visit(&for_right); 474 node->right()->Visit(&for_right);
487 475
488 Append(for_left); 476 Append(for_left);
489 477
490 if (node->kind() == Token::kAND) { 478 if (node->kind() == Token::kAND) {
491 AppendFragment(for_left.CreateTrueSuccessor(), for_right); 479 AppendFragment(for_left.CreateTrueSuccessor(), for_right);
492 true_successor_addresses_.AddArray(for_right.true_successor_addresses_); 480 true_successor_addresses_.AddArray(for_right.true_successor_addresses_);
493 false_successor_addresses_.AddArray(for_left.false_successor_addresses_); 481 false_successor_addresses_.AddArray(for_left.false_successor_addresses_);
494 false_successor_addresses_.AddArray(for_right.false_successor_addresses_); 482 false_successor_addresses_.AddArray(for_right.false_successor_addresses_);
(...skipping 18 matching lines...) Expand all
513 501
514 void EffectGraphVisitor::InlineBailout(const char* reason) { 502 void EffectGraphVisitor::InlineBailout(const char* reason) {
515 owner()->parsed_function().function().set_is_inlinable(false); 503 owner()->parsed_function().function().set_is_inlinable(false);
516 if (owner()->InInliningContext()) owner()->Bailout(reason); 504 if (owner()->InInliningContext()) owner()->Bailout(reason);
517 } 505 }
518 506
519 507
520 // <Statement> ::= Return { value: <Expression> 508 // <Statement> ::= Return { value: <Expression>
521 // inlined_finally_list: <InlinedFinally>* } 509 // inlined_finally_list: <InlinedFinally>* }
522 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { 510 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) {
523 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); 511 ValueGraphVisitor for_value(owner(), temp_index());
524 node->value()->Visit(&for_value); 512 node->value()->Visit(&for_value);
525 Append(for_value); 513 Append(for_value);
526 514
527 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { 515 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) {
528 InlineBailout("EffectGraphVisitor::VisitReturnNode (exception)"); 516 InlineBailout("EffectGraphVisitor::VisitReturnNode (exception)");
529 EffectGraphVisitor for_effect(owner(), temp_index(), loop_depth()); 517 EffectGraphVisitor for_effect(owner(), temp_index());
530 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); 518 node->InlinedFinallyNodeAt(i)->Visit(&for_effect);
531 Append(for_effect); 519 Append(for_effect);
532 if (!is_open()) return; 520 if (!is_open()) return;
533 } 521 }
534 522
535 Value* return_value = for_value.value(); 523 Value* return_value = for_value.value();
536 if (FLAG_enable_type_checks) { 524 if (FLAG_enable_type_checks) {
537 const Function& function = owner()->parsed_function().function(); 525 const Function& function = owner()->parsed_function().function();
538 const bool is_implicit_dynamic_getter = 526 const bool is_implicit_dynamic_getter =
539 (!function.is_static() && 527 (!function.is_static() &&
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 eliminated); 630 eliminated);
643 } 631 }
644 return eliminated; 632 return eliminated;
645 } 633 }
646 634
647 635
648 // <Expression> :: Assignable { expr: <Expression> 636 // <Expression> :: Assignable { expr: <Expression>
649 // type: AbstractType 637 // type: AbstractType
650 // dst_name: String } 638 // dst_name: String }
651 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { 639 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) {
652 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); 640 ValueGraphVisitor for_value(owner(), temp_index());
653 node->expr()->Visit(&for_value); 641 node->expr()->Visit(&for_value);
654 Append(for_value); 642 Append(for_value);
655 Definition* checked_value; 643 Definition* checked_value;
656 if (CanSkipTypeCheck(node->expr()->token_pos(), 644 if (CanSkipTypeCheck(node->expr()->token_pos(),
657 for_value.value(), 645 for_value.value(),
658 node->type(), 646 node->type(),
659 node->dst_name())) { 647 node->dst_name())) {
660 checked_value = for_value.value()->definition(); // No check needed. 648 checked_value = for_value.value()->definition(); // No check needed.
661 } else { 649 } else {
662 checked_value = BuildAssertAssignable(node->expr()->token_pos(), 650 checked_value = BuildAssertAssignable(node->expr()->token_pos(),
663 for_value.value(), 651 for_value.value(),
664 node->type(), 652 node->type(),
665 node->dst_name()); 653 node->dst_name());
666 } 654 }
667 ReturnDefinition(checked_value); 655 ReturnDefinition(checked_value);
668 } 656 }
669 657
670 658
671 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { 659 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) {
672 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); 660 ValueGraphVisitor for_value(owner(), temp_index());
673 node->expr()->Visit(&for_value); 661 node->expr()->Visit(&for_value);
674 Append(for_value); 662 Append(for_value);
675 ReturnValue(BuildAssignableValue(node->expr()->token_pos(), 663 ReturnValue(BuildAssignableValue(node->expr()->token_pos(),
676 for_value.value(), 664 for_value.value(),
677 node->type(), 665 node->type(),
678 node->dst_name())); 666 node->dst_name()));
679 } 667 }
680 668
681 669
682 // <Expression> :: BinaryOp { kind: Token::Kind 670 // <Expression> :: BinaryOp { kind: Token::Kind
683 // left: <Expression> 671 // left: <Expression>
684 // right: <Expression> } 672 // right: <Expression> }
685 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { 673 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
686 // Operators "&&" and "||" cannot be overloaded therefore do not call 674 // Operators "&&" and "||" cannot be overloaded therefore do not call
687 // operator. 675 // operator.
688 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { 676 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
689 // See ValueGraphVisitor::VisitBinaryOpNode. 677 // See ValueGraphVisitor::VisitBinaryOpNode.
690 TestGraphVisitor for_left(owner(), 678 TestGraphVisitor for_left(owner(),
691 temp_index(), 679 temp_index(),
692 loop_depth(),
693 node->left()->token_pos()); 680 node->left()->token_pos());
694 node->left()->Visit(&for_left); 681 node->left()->Visit(&for_left);
695 EffectGraphVisitor for_right(owner(), temp_index(), loop_depth()); 682 EffectGraphVisitor for_right(owner(), temp_index());
696 node->right()->Visit(&for_right); 683 node->right()->Visit(&for_right);
697 EffectGraphVisitor empty(owner(), temp_index(), loop_depth()); 684 EffectGraphVisitor empty(owner(), temp_index());
698 if (node->kind() == Token::kAND) { 685 if (node->kind() == Token::kAND) {
699 Join(for_left, for_right, empty); 686 Join(for_left, for_right, empty);
700 } else { 687 } else {
701 Join(for_left, empty, for_right); 688 Join(for_left, empty, for_right);
702 } 689 }
703 return; 690 return;
704 } 691 }
705 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); 692 ValueGraphVisitor for_left_value(owner(), temp_index());
706 node->left()->Visit(&for_left_value); 693 node->left()->Visit(&for_left_value);
707 Append(for_left_value); 694 Append(for_left_value);
708 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 695 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
709 696
710 ValueGraphVisitor for_right_value(owner(), temp_index(), loop_depth()); 697 ValueGraphVisitor for_right_value(owner(), temp_index());
711 node->right()->Visit(&for_right_value); 698 node->right()->Visit(&for_right_value);
712 Append(for_right_value); 699 Append(for_right_value);
713 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); 700 PushArgumentInstr* push_right = PushArgument(for_right_value.value());
714 701
715 ZoneGrowableArray<PushArgumentInstr*>* arguments = 702 ZoneGrowableArray<PushArgumentInstr*>* arguments =
716 new ZoneGrowableArray<PushArgumentInstr*>(2); 703 new ZoneGrowableArray<PushArgumentInstr*>(2);
717 arguments->Add(push_left); 704 arguments->Add(push_left);
718 arguments->Add(push_right); 705 arguments->Add(push_right);
719 const String& name = String::ZoneHandle(Symbols::New(node->Name())); 706 const String& name = String::ZoneHandle(Symbols::New(node->Name()));
720 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), 707 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(),
(...skipping 11 matching lines...) Expand all
732 // Operators "&&" and "||" cannot be overloaded therefore do not call 719 // Operators "&&" and "||" cannot be overloaded therefore do not call
733 // operator. 720 // operator.
734 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { 721 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
735 // Implement short-circuit logic: do not evaluate right if evaluation 722 // Implement short-circuit logic: do not evaluate right if evaluation
736 // of left is sufficient. 723 // of left is sufficient.
737 // AND: left ? right === true : false; 724 // AND: left ? right === true : false;
738 // OR: left ? true : right === true; 725 // OR: left ? true : right === true;
739 726
740 TestGraphVisitor for_test(owner(), 727 TestGraphVisitor for_test(owner(),
741 temp_index(), 728 temp_index(),
742 loop_depth(),
743 node->left()->token_pos()); 729 node->left()->token_pos());
744 node->left()->Visit(&for_test); 730 node->left()->Visit(&for_test);
745 731
746 ValueGraphVisitor for_right(owner(), temp_index(), loop_depth()); 732 ValueGraphVisitor for_right(owner(), temp_index());
747 node->right()->Visit(&for_right); 733 node->right()->Visit(&for_right);
748 Value* right_value = for_right.value(); 734 Value* right_value = for_right.value();
749 if (FLAG_enable_type_checks) { 735 if (FLAG_enable_type_checks) {
750 right_value = 736 right_value =
751 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(), 737 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(),
752 right_value)); 738 right_value));
753 } 739 }
754 Value* constant_true = for_right.Bind(new ConstantInstr(Bool::True())); 740 Value* constant_true = for_right.Bind(new ConstantInstr(Bool::True()));
755 Value* compare = 741 Value* compare =
756 for_right.Bind(new StrictCompareInstr(Token::kEQ_STRICT, 742 for_right.Bind(new StrictCompareInstr(Token::kEQ_STRICT,
757 right_value, 743 right_value,
758 constant_true)); 744 constant_true));
759 for_right.Do(BuildStoreExprTemp(compare)); 745 for_right.Do(BuildStoreExprTemp(compare));
760 746
761 if (node->kind() == Token::kAND) { 747 if (node->kind() == Token::kAND) {
762 ValueGraphVisitor for_false(owner(), temp_index(), loop_depth()); 748 ValueGraphVisitor for_false(owner(), temp_index());
763 Value* constant_false = for_false.Bind(new ConstantInstr(Bool::False())); 749 Value* constant_false = for_false.Bind(new ConstantInstr(Bool::False()));
764 for_false.Do(BuildStoreExprTemp(constant_false)); 750 for_false.Do(BuildStoreExprTemp(constant_false));
765 Join(for_test, for_right, for_false); 751 Join(for_test, for_right, for_false);
766 } else { 752 } else {
767 ASSERT(node->kind() == Token::kOR); 753 ASSERT(node->kind() == Token::kOR);
768 ValueGraphVisitor for_true(owner(), temp_index(), loop_depth()); 754 ValueGraphVisitor for_true(owner(), temp_index());
769 Value* constant_true = for_true.Bind(new ConstantInstr(Bool::True())); 755 Value* constant_true = for_true.Bind(new ConstantInstr(Bool::True()));
770 for_true.Do(BuildStoreExprTemp(constant_true)); 756 for_true.Do(BuildStoreExprTemp(constant_true));
771 Join(for_test, for_true, for_right); 757 Join(for_test, for_true, for_right);
772 } 758 }
773 ReturnDefinition(BuildLoadExprTemp()); 759 ReturnDefinition(BuildLoadExprTemp());
774 return; 760 return;
775 } 761 }
776 EffectGraphVisitor::VisitBinaryOpNode(node); 762 EffectGraphVisitor::VisitBinaryOpNode(node);
777 } 763 }
778 764
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 const String& dst_name) { 857 const String& dst_name) {
872 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { 858 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) {
873 return value; 859 return value;
874 } 860 }
875 return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name)); 861 return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name));
876 } 862 }
877 863
878 864
879 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { 865 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) {
880 ASSERT(Token::IsTypeTestOperator(node->kind())); 866 ASSERT(Token::IsTypeTestOperator(node->kind()));
881 EffectGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); 867 EffectGraphVisitor for_left_value(owner(), temp_index());
882 node->left()->Visit(&for_left_value); 868 node->left()->Visit(&for_left_value);
883 Append(for_left_value); 869 Append(for_left_value);
884 } 870 }
885 871
886 872
887 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { 873 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) {
888 ASSERT(Token::IsTypeCastOperator(node->kind())); 874 ASSERT(Token::IsTypeCastOperator(node->kind()));
889 const AbstractType& type = node->right()->AsTypeNode()->type(); 875 const AbstractType& type = node->right()->AsTypeNode()->type();
890 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. 876 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed.
891 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); 877 ValueGraphVisitor for_value(owner(), temp_index());
892 node->left()->Visit(&for_value); 878 node->left()->Visit(&for_value);
893 const String& dst_name = String::ZoneHandle( 879 const String& dst_name = String::ZoneHandle(
894 Symbols::New(Exceptions::kCastErrorDstName)); 880 Symbols::New(Exceptions::kCastErrorDstName));
895 if (!CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) { 881 if (!CanSkipTypeCheck(node->token_pos(), for_value.value(), type, dst_name)) {
896 Append(for_value); 882 Append(for_value);
897 Do(BuildAssertAssignable( 883 Do(BuildAssertAssignable(
898 node->token_pos(), for_value.value(), type, dst_name)); 884 node->token_pos(), for_value.value(), type, dst_name));
899 } 885 }
900 } 886 }
901 887
902 888
903 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) { 889 void ValueGraphVisitor::BuildTypeTest(ComparisonNode* node) {
904 ASSERT(Token::IsTypeTestOperator(node->kind())); 890 ASSERT(Token::IsTypeTestOperator(node->kind()));
905 const AbstractType& type = node->right()->AsTypeNode()->type(); 891 const AbstractType& type = node->right()->AsTypeNode()->type();
906 ASSERT(type.IsFinalized() && !type.IsMalformed()); 892 ASSERT(type.IsFinalized() && !type.IsMalformed());
907 const bool negate_result = (node->kind() == Token::kISNOT); 893 const bool negate_result = (node->kind() == Token::kISNOT);
908 // All objects are instances of type T if Object type is a subtype of type T. 894 // All objects are instances of type T if Object type is a subtype of type T.
909 const Type& object_type = Type::Handle(Type::ObjectType()); 895 const Type& object_type = Type::Handle(Type::ObjectType());
910 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { 896 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) {
911 // Must evaluate left side. 897 // Must evaluate left side.
912 EffectGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); 898 EffectGraphVisitor for_left_value(owner(), temp_index());
913 node->left()->Visit(&for_left_value); 899 node->left()->Visit(&for_left_value);
914 Append(for_left_value); 900 Append(for_left_value);
915 ReturnDefinition(new ConstantInstr(negate_result ? 901 ReturnDefinition(new ConstantInstr(negate_result ?
916 Bool::False() : Bool::True())); 902 Bool::False() : Bool::True()));
917 return; 903 return;
918 } 904 }
919 905
920 // Eliminate the test if it can be performed successfully at compile time. 906 // Eliminate the test if it can be performed successfully at compile time.
921 if ((node->left() != NULL) && 907 if ((node->left() != NULL) &&
922 node->left()->IsLiteralNode() && 908 node->left()->IsLiteralNode() &&
(...skipping 13 matching lines...) Expand all
936 Bool::False() : Bool::True()); 922 Bool::False() : Bool::True());
937 } else { 923 } else {
938 result = new ConstantInstr(negate_result ? 924 result = new ConstantInstr(negate_result ?
939 Bool::True() : Bool::False()); 925 Bool::True() : Bool::False());
940 } 926 }
941 } 927 }
942 ReturnDefinition(result); 928 ReturnDefinition(result);
943 return; 929 return;
944 } 930 }
945 931
946 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); 932 ValueGraphVisitor for_left_value(owner(), temp_index());
947 node->left()->Visit(&for_left_value); 933 node->left()->Visit(&for_left_value);
948 Append(for_left_value); 934 Append(for_left_value);
949 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 935 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
950 PushArgumentInstr* push_instantiator = NULL; 936 PushArgumentInstr* push_instantiator = NULL;
951 PushArgumentInstr* push_type_args = NULL; 937 PushArgumentInstr* push_type_args = NULL;
952 if (type.IsInstantiated()) { 938 if (type.IsInstantiated()) {
953 push_instantiator = PushArgument(BuildNullValue()); 939 push_instantiator = PushArgument(BuildNullValue());
954 push_type_args = PushArgument(BuildNullValue()); 940 push_type_args = PushArgument(BuildNullValue());
955 } else { 941 } else {
956 BuildTypecheckPushArguments(node->token_pos(), 942 BuildTypecheckPushArguments(node->token_pos(),
(...skipping 22 matching lines...) Expand all
979 Array::ZoneHandle(), 965 Array::ZoneHandle(),
980 kNumArgsChecked); 966 kNumArgsChecked);
981 ReturnDefinition(call); 967 ReturnDefinition(call);
982 } 968 }
983 969
984 970
985 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) { 971 void ValueGraphVisitor::BuildTypeCast(ComparisonNode* node) {
986 ASSERT(Token::IsTypeCastOperator(node->kind())); 972 ASSERT(Token::IsTypeCastOperator(node->kind()));
987 const AbstractType& type = node->right()->AsTypeNode()->type(); 973 const AbstractType& type = node->right()->AsTypeNode()->type();
988 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed. 974 ASSERT(type.IsFinalized()); // The type in a type cast may be malformed.
989 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); 975 ValueGraphVisitor for_value(owner(), temp_index());
990 node->left()->Visit(&for_value); 976 node->left()->Visit(&for_value);
991 Append(for_value); 977 Append(for_value);
992 const String& dst_name = String::ZoneHandle( 978 const String& dst_name = String::ZoneHandle(
993 Symbols::New(Exceptions::kCastErrorDstName)); 979 Symbols::New(Exceptions::kCastErrorDstName));
994 ReturnValue(BuildAssignableValue(node->token_pos(), 980 ReturnValue(BuildAssignableValue(node->token_pos(),
995 for_value.value(), 981 for_value.value(),
996 type, 982 type,
997 dst_name)); 983 dst_name));
998 } 984 }
999 985
1000 986
1001 // <Expression> :: Comparison { kind: Token::Kind 987 // <Expression> :: Comparison { kind: Token::Kind
1002 // left: <Expression> 988 // left: <Expression>
1003 // right: <Expression> } 989 // right: <Expression> }
1004 // TODO(srdjan): Implement new equality. 990 // TODO(srdjan): Implement new equality.
1005 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { 991 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) {
1006 if (Token::IsTypeTestOperator(node->kind())) { 992 if (Token::IsTypeTestOperator(node->kind())) {
1007 BuildTypeTest(node); 993 BuildTypeTest(node);
1008 return; 994 return;
1009 } 995 }
1010 if (Token::IsTypeCastOperator(node->kind())) { 996 if (Token::IsTypeCastOperator(node->kind())) {
1011 BuildTypeCast(node); 997 BuildTypeCast(node);
1012 return; 998 return;
1013 } 999 }
1014 if ((node->kind() == Token::kEQ_STRICT) || 1000 if ((node->kind() == Token::kEQ_STRICT) ||
1015 (node->kind() == Token::kNE_STRICT)) { 1001 (node->kind() == Token::kNE_STRICT)) {
1016 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); 1002 ValueGraphVisitor for_left_value(owner(), temp_index());
1017 node->left()->Visit(&for_left_value); 1003 node->left()->Visit(&for_left_value);
1018 Append(for_left_value); 1004 Append(for_left_value);
1019 ValueGraphVisitor for_right_value(owner(), temp_index(), loop_depth()); 1005 ValueGraphVisitor for_right_value(owner(), temp_index());
1020 node->right()->Visit(&for_right_value); 1006 node->right()->Visit(&for_right_value);
1021 Append(for_right_value); 1007 Append(for_right_value);
1022 StrictCompareInstr* comp = new StrictCompareInstr( 1008 StrictCompareInstr* comp = new StrictCompareInstr(
1023 node->kind(), for_left_value.value(), for_right_value.value()); 1009 node->kind(), for_left_value.value(), for_right_value.value());
1024 ReturnDefinition(comp); 1010 ReturnDefinition(comp);
1025 return; 1011 return;
1026 } 1012 }
1027 1013
1028 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { 1014 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) {
1029 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); 1015 ValueGraphVisitor for_left_value(owner(), temp_index());
1030 node->left()->Visit(&for_left_value); 1016 node->left()->Visit(&for_left_value);
1031 Append(for_left_value); 1017 Append(for_left_value);
1032 ValueGraphVisitor for_right_value(owner(), temp_index(), loop_depth()); 1018 ValueGraphVisitor for_right_value(owner(), temp_index());
1033 node->right()->Visit(&for_right_value); 1019 node->right()->Visit(&for_right_value);
1034 Append(for_right_value); 1020 Append(for_right_value);
1035 if (FLAG_enable_type_checks) { 1021 if (FLAG_enable_type_checks) {
1036 EqualityCompareInstr* comp = new EqualityCompareInstr( 1022 EqualityCompareInstr* comp = new EqualityCompareInstr(
1037 node->token_pos(), 1023 node->token_pos(),
1038 Token::kEQ, 1024 Token::kEQ,
1039 for_left_value.value(), 1025 for_left_value.value(),
1040 for_right_value.value()); 1026 for_right_value.value());
1041 if (node->kind() == Token::kEQ) { 1027 if (node->kind() == Token::kEQ) {
1042 ReturnDefinition(comp); 1028 ReturnDefinition(comp);
1043 } else { 1029 } else {
1044 Value* eq_result = Bind(comp); 1030 Value* eq_result = Bind(comp);
1045 eq_result = Bind(new AssertBooleanInstr(node->token_pos(), eq_result)); 1031 eq_result = Bind(new AssertBooleanInstr(node->token_pos(), eq_result));
1046 ReturnDefinition(new BooleanNegateInstr(eq_result)); 1032 ReturnDefinition(new BooleanNegateInstr(eq_result));
1047 } 1033 }
1048 } else { 1034 } else {
1049 EqualityCompareInstr* comp = new EqualityCompareInstr( 1035 EqualityCompareInstr* comp = new EqualityCompareInstr(
1050 node->token_pos(), 1036 node->token_pos(),
1051 node->kind(), 1037 node->kind(),
1052 for_left_value.value(), 1038 for_left_value.value(),
1053 for_right_value.value()); 1039 for_right_value.value());
1054 ReturnDefinition(comp); 1040 ReturnDefinition(comp);
1055 } 1041 }
1056 return; 1042 return;
1057 } 1043 }
1058 1044
1059 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); 1045 ValueGraphVisitor for_left_value(owner(), temp_index());
1060 node->left()->Visit(&for_left_value); 1046 node->left()->Visit(&for_left_value);
1061 Append(for_left_value); 1047 Append(for_left_value);
1062 ValueGraphVisitor for_right_value(owner(), temp_index(), loop_depth()); 1048 ValueGraphVisitor for_right_value(owner(), temp_index());
1063 node->right()->Visit(&for_right_value); 1049 node->right()->Visit(&for_right_value);
1064 Append(for_right_value); 1050 Append(for_right_value);
1065 RelationalOpInstr* comp = new RelationalOpInstr(node->token_pos(), 1051 RelationalOpInstr* comp = new RelationalOpInstr(node->token_pos(),
1066 node->kind(), 1052 node->kind(),
1067 for_left_value.value(), 1053 for_left_value.value(),
1068 for_right_value.value()); 1054 for_right_value.value());
1069 ReturnDefinition(comp); 1055 ReturnDefinition(comp);
1070 } 1056 }
1071 1057
1072 1058
1073 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { 1059 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
1074 // "!" cannot be overloaded, therefore do not call operator. 1060 // "!" cannot be overloaded, therefore do not call operator.
1075 if (node->kind() == Token::kNOT) { 1061 if (node->kind() == Token::kNOT) {
1076 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); 1062 ValueGraphVisitor for_value(owner(), temp_index());
1077 node->operand()->Visit(&for_value); 1063 node->operand()->Visit(&for_value);
1078 Append(for_value); 1064 Append(for_value);
1079 Value* value = for_value.value(); 1065 Value* value = for_value.value();
1080 if (FLAG_enable_type_checks) { 1066 if (FLAG_enable_type_checks) {
1081 value = 1067 value =
1082 Bind(new AssertBooleanInstr(node->operand()->token_pos(), value)); 1068 Bind(new AssertBooleanInstr(node->operand()->token_pos(), value));
1083 } 1069 }
1084 BooleanNegateInstr* negate = new BooleanNegateInstr(value); 1070 BooleanNegateInstr* negate = new BooleanNegateInstr(value);
1085 ReturnDefinition(negate); 1071 ReturnDefinition(negate);
1086 return; 1072 return;
1087 } 1073 }
1088 1074
1089 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); 1075 ValueGraphVisitor for_value(owner(), temp_index());
1090 node->operand()->Visit(&for_value); 1076 node->operand()->Visit(&for_value);
1091 Append(for_value); 1077 Append(for_value);
1092 PushArgumentInstr* push_value = PushArgument(for_value.value()); 1078 PushArgumentInstr* push_value = PushArgument(for_value.value());
1093 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1079 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1094 new ZoneGrowableArray<PushArgumentInstr*>(1); 1080 new ZoneGrowableArray<PushArgumentInstr*>(1);
1095 arguments->Add(push_value); 1081 arguments->Add(push_value);
1096 InstanceCallInstr* call = 1082 InstanceCallInstr* call =
1097 new InstanceCallInstr(node->token_pos(), 1083 new InstanceCallInstr(node->token_pos(),
1098 String::ZoneHandle( 1084 String::ZoneHandle(
1099 Symbols::New(Token::Str(node->kind()))), 1085 Symbols::New(Token::Str(node->kind()))),
1100 node->kind(), 1086 node->kind(),
1101 arguments, 1087 arguments,
1102 Array::ZoneHandle(), 1088 Array::ZoneHandle(),
1103 1); 1089 1);
1104 ReturnDefinition(call); 1090 ReturnDefinition(call);
1105 } 1091 }
1106 1092
1107 1093
1108 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { 1094 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
1109 TestGraphVisitor for_test(owner(), 1095 TestGraphVisitor for_test(owner(),
1110 temp_index(), 1096 temp_index(),
1111 loop_depth(),
1112 node->condition()->token_pos()); 1097 node->condition()->token_pos());
1113 node->condition()->Visit(&for_test); 1098 node->condition()->Visit(&for_test);
1114 1099
1115 // Translate the subexpressions for their effects. 1100 // Translate the subexpressions for their effects.
1116 EffectGraphVisitor for_true(owner(), temp_index(), loop_depth()); 1101 EffectGraphVisitor for_true(owner(), temp_index());
1117 node->true_expr()->Visit(&for_true); 1102 node->true_expr()->Visit(&for_true);
1118 EffectGraphVisitor for_false(owner(), temp_index(), loop_depth()); 1103 EffectGraphVisitor for_false(owner(), temp_index());
1119 node->false_expr()->Visit(&for_false); 1104 node->false_expr()->Visit(&for_false);
1120 1105
1121 Join(for_test, for_true, for_false); 1106 Join(for_test, for_true, for_false);
1122 } 1107 }
1123 1108
1124 1109
1125 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { 1110 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
1126 TestGraphVisitor for_test(owner(), 1111 TestGraphVisitor for_test(owner(),
1127 temp_index(), 1112 temp_index(),
1128 loop_depth(),
1129 node->condition()->token_pos()); 1113 node->condition()->token_pos());
1130 node->condition()->Visit(&for_test); 1114 node->condition()->Visit(&for_test);
1131 1115
1132 ValueGraphVisitor for_true(owner(), temp_index(), loop_depth()); 1116 ValueGraphVisitor for_true(owner(), temp_index());
1133 node->true_expr()->Visit(&for_true); 1117 node->true_expr()->Visit(&for_true);
1134 ASSERT(for_true.is_open()); 1118 ASSERT(for_true.is_open());
1135 for_true.Do(BuildStoreExprTemp(for_true.value())); 1119 for_true.Do(BuildStoreExprTemp(for_true.value()));
1136 1120
1137 ValueGraphVisitor for_false(owner(), temp_index(), loop_depth()); 1121 ValueGraphVisitor for_false(owner(), temp_index());
1138 node->false_expr()->Visit(&for_false); 1122 node->false_expr()->Visit(&for_false);
1139 ASSERT(for_false.is_open()); 1123 ASSERT(for_false.is_open());
1140 for_false.Do(BuildStoreExprTemp(for_false.value())); 1124 for_false.Do(BuildStoreExprTemp(for_false.value()));
1141 1125
1142 Join(for_test, for_true, for_false); 1126 Join(for_test, for_true, for_false);
1143 ReturnDefinition(BuildLoadExprTemp()); 1127 ReturnDefinition(BuildLoadExprTemp());
1144 } 1128 }
1145 1129
1146 1130
1147 // <Statement> ::= If { condition: <Expression> 1131 // <Statement> ::= If { condition: <Expression>
1148 // true_branch: <Sequence> 1132 // true_branch: <Sequence>
1149 // false_branch: <Sequence> } 1133 // false_branch: <Sequence> }
1150 void EffectGraphVisitor::VisitIfNode(IfNode* node) { 1134 void EffectGraphVisitor::VisitIfNode(IfNode* node) {
1151 TestGraphVisitor for_test(owner(), 1135 TestGraphVisitor for_test(owner(),
1152 temp_index(), 1136 temp_index(),
1153 loop_depth(),
1154 node->condition()->token_pos()); 1137 node->condition()->token_pos());
1155 node->condition()->Visit(&for_test); 1138 node->condition()->Visit(&for_test);
1156 1139
1157 EffectGraphVisitor for_true(owner(), temp_index(), loop_depth()); 1140 EffectGraphVisitor for_true(owner(), temp_index());
1158 EffectGraphVisitor for_false(owner(), temp_index(), loop_depth()); 1141 EffectGraphVisitor for_false(owner(), temp_index());
1159 1142
1160 node->true_branch()->Visit(&for_true); 1143 node->true_branch()->Visit(&for_true);
1161 // The for_false graph fragment will be empty (default graph fragment) if 1144 // The for_false graph fragment will be empty (default graph fragment) if
1162 // we do not call Visit. 1145 // we do not call Visit.
1163 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false); 1146 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false);
1164 Join(for_test, for_true, for_false); 1147 Join(for_test, for_true, for_false);
1165 } 1148 }
1166 1149
1167 1150
1168 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) { 1151 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) {
1169 EffectGraphVisitor switch_body(owner(), temp_index(), loop_depth()); 1152 EffectGraphVisitor switch_body(owner(), temp_index());
1170 node->body()->Visit(&switch_body); 1153 node->body()->Visit(&switch_body);
1171 Append(switch_body); 1154 Append(switch_body);
1172 if ((node->label() != NULL) && (node->label()->join_for_break() != NULL)) { 1155 if ((node->label() != NULL) && (node->label()->join_for_break() != NULL)) {
1173 node->label()->join_for_break()->set_loop_depth(loop_depth());
1174 if (is_open()) Goto(node->label()->join_for_break()); 1156 if (is_open()) Goto(node->label()->join_for_break());
1175 exit_ = node->label()->join_for_break(); 1157 exit_ = node->label()->join_for_break();
1176 } 1158 }
1177 // No continue label allowed. 1159 // No continue label allowed.
1178 ASSERT((node->label() == NULL) || 1160 ASSERT((node->label() == NULL) ||
1179 (node->label()->join_for_continue() == NULL)); 1161 (node->label()->join_for_continue() == NULL));
1180 } 1162 }
1181 1163
1182 1164
1183 // A case node contains zero or more case expressions, can contain default 1165 // A case node contains zero or more case expressions, can contain default
(...skipping 13 matching lines...) Expand all
1197 // g) case-statements-join 1179 // g) case-statements-join
1198 // h) [ case-statements ] -> exit-join 1180 // h) [ case-statements ] -> exit-join
1199 // i) exit-target -> exit-join 1181 // i) exit-target -> exit-join
1200 // j) exit-join 1182 // j) exit-join
1201 // 1183 //
1202 // Note: The specification of switch/case is under discussion and may change 1184 // Note: The specification of switch/case is under discussion and may change
1203 // drastically. 1185 // drastically.
1204 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { 1186 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) {
1205 const intptr_t len = node->case_expressions()->length(); 1187 const intptr_t len = node->case_expressions()->length();
1206 // Create case statements instructions. 1188 // Create case statements instructions.
1207 EffectGraphVisitor for_case_statements(owner(), temp_index(), loop_depth()); 1189 EffectGraphVisitor for_case_statements(owner(), temp_index());
1208 // Compute start of statements fragment. 1190 // Compute start of statements fragment.
1209 JoinEntryInstr* statement_start = NULL; 1191 JoinEntryInstr* statement_start = NULL;
1210 if ((node->label() != NULL) && node->label()->is_continue_target()) { 1192 if ((node->label() != NULL) && node->label()->is_continue_target()) {
1211 // Since a labeled jump continue statement occur in a different case node, 1193 // Since a labeled jump continue statement occur in a different case node,
1212 // allocate JoinNode here and use it as statement start. 1194 // allocate JoinNode here and use it as statement start.
1213 statement_start = node->label()->join_for_continue(); 1195 statement_start = node->label()->join_for_continue();
1214 if (statement_start == NULL) { 1196 if (statement_start == NULL) {
1215 statement_start = new JoinEntryInstr(owner()->AllocateBlockId(), 1197 statement_start = new JoinEntryInstr(owner()->AllocateBlockId(),
1216 owner()->try_index(), 1198 owner()->try_index());
1217 loop_depth());
1218 node->label()->set_join_for_continue(statement_start); 1199 node->label()->set_join_for_continue(statement_start);
1219 } 1200 }
1220 } else { 1201 } else {
1221 statement_start = new JoinEntryInstr(owner()->AllocateBlockId(), 1202 statement_start = new JoinEntryInstr(owner()->AllocateBlockId(),
1222 owner()->try_index(), 1203 owner()->try_index());
1223 loop_depth());
1224 } 1204 }
1225 node->statements()->Visit(&for_case_statements); 1205 node->statements()->Visit(&for_case_statements);
1226 Instruction* statement_exit = 1206 Instruction* statement_exit =
1227 AppendFragment(statement_start, for_case_statements); 1207 AppendFragment(statement_start, for_case_statements);
1228 if (is_open() && (len == 0)) { 1208 if (is_open() && (len == 0)) {
1229 ASSERT(node->contains_default()); 1209 ASSERT(node->contains_default());
1230 // Default only case node. 1210 // Default only case node.
1231 Goto(statement_start); 1211 Goto(statement_start);
1232 exit_ = statement_exit; 1212 exit_ = statement_exit;
1233 return; 1213 return;
1234 } 1214 }
1235 1215
1236 // Generate instructions for all case expressions. 1216 // Generate instructions for all case expressions.
1237 TargetEntryInstr* next_target = NULL; 1217 TargetEntryInstr* next_target = NULL;
1238 for (intptr_t i = 0; i < len; i++) { 1218 for (intptr_t i = 0; i < len; i++) {
1239 AstNode* case_expr = node->case_expressions()->NodeAt(i); 1219 AstNode* case_expr = node->case_expressions()->NodeAt(i);
1240 TestGraphVisitor for_case_expression(owner(), 1220 TestGraphVisitor for_case_expression(owner(),
1241 temp_index(), 1221 temp_index(),
1242 loop_depth(),
1243 case_expr->token_pos()); 1222 case_expr->token_pos());
1244 case_expr->Visit(&for_case_expression); 1223 case_expr->Visit(&for_case_expression);
1245 if (i == 0) { 1224 if (i == 0) {
1246 // Append only the first one, everything else is connected from it. 1225 // Append only the first one, everything else is connected from it.
1247 Append(for_case_expression); 1226 Append(for_case_expression);
1248 } else { 1227 } else {
1249 ASSERT(next_target != NULL); 1228 ASSERT(next_target != NULL);
1250 AppendFragment(next_target, for_case_expression); 1229 AppendFragment(next_target, for_case_expression);
1251 } 1230 }
1252 for_case_expression.IfTrueGoto(statement_start); 1231 for_case_expression.IfTrueGoto(statement_start);
1253 next_target = for_case_expression.CreateFalseSuccessor()->AsTargetEntry(); 1232 next_target = for_case_expression.CreateFalseSuccessor()->AsTargetEntry();
1254 } 1233 }
1255 1234
1256 // Once a test fragment has been added, this fragment is closed. 1235 // Once a test fragment has been added, this fragment is closed.
1257 ASSERT(!is_open()); 1236 ASSERT(!is_open());
1258 1237
1259 Instruction* exit_instruction = NULL; 1238 Instruction* exit_instruction = NULL;
1260 // Handle last (or only) case: false goes to exit or to statement if this 1239 // Handle last (or only) case: false goes to exit or to statement if this
1261 // node contains default. 1240 // node contains default.
1262 if (len > 0) { 1241 if (len > 0) {
1263 ASSERT(next_target != NULL); 1242 ASSERT(next_target != NULL);
1264 if (node->contains_default()) { 1243 if (node->contains_default()) {
1265 // True and false go to statement start. 1244 // True and false go to statement start.
1266 next_target->Goto(statement_start); 1245 next_target->Goto(statement_start);
1267 exit_instruction = statement_exit; 1246 exit_instruction = statement_exit;
1268 } else { 1247 } else {
1269 if (statement_exit != NULL) { 1248 if (statement_exit != NULL) {
1270 JoinEntryInstr* join = new JoinEntryInstr(owner()->AllocateBlockId(), 1249 JoinEntryInstr* join = new JoinEntryInstr(owner()->AllocateBlockId(),
1271 owner()->try_index(), 1250 owner()->try_index());
1272 loop_depth());
1273 statement_exit->Goto(join); 1251 statement_exit->Goto(join);
1274 next_target->Goto(join); 1252 next_target->Goto(join);
1275 exit_instruction = join; 1253 exit_instruction = join;
1276 } else { 1254 } else {
1277 exit_instruction = next_target; 1255 exit_instruction = next_target;
1278 } 1256 }
1279 } 1257 }
1280 } else { 1258 } else {
1281 // A CaseNode without case expressions must contain default. 1259 // A CaseNode without case expressions must contain default.
1282 ASSERT(node->contains_default()); 1260 ASSERT(node->contains_default());
(...skipping 13 matching lines...) Expand all
1296 // a) loop-join 1274 // a) loop-join
1297 // b) [ test ] -> (body-entry-target, loop-exit-target) 1275 // b) [ test ] -> (body-entry-target, loop-exit-target)
1298 // c) body-entry-target 1276 // c) body-entry-target
1299 // d) [ body ] -> (continue-join) 1277 // d) [ body ] -> (continue-join)
1300 // e) continue-join -> (loop-join) 1278 // e) continue-join -> (loop-join)
1301 // f) loop-exit-target 1279 // f) loop-exit-target
1302 // g) break-join (optional) 1280 // g) break-join (optional)
1303 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { 1281 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) {
1304 TestGraphVisitor for_test(owner(), 1282 TestGraphVisitor for_test(owner(),
1305 temp_index(), 1283 temp_index(),
1306 loop_depth() + 1,
1307 node->condition()->token_pos()); 1284 node->condition()->token_pos());
1308 node->condition()->Visit(&for_test); 1285 node->condition()->Visit(&for_test);
1309 ASSERT(!for_test.is_empty()); // Language spec. 1286 ASSERT(!for_test.is_empty()); // Language spec.
1310 1287
1311 EffectGraphVisitor for_body(owner(), temp_index(), loop_depth() + 1); 1288 EffectGraphVisitor for_body(owner(), temp_index());
1312 for_body.AddInstruction( 1289 for_body.AddInstruction(
1313 new CheckStackOverflowInstr(node->token_pos())); 1290 new CheckStackOverflowInstr(node->token_pos()));
1314 node->body()->Visit(&for_body); 1291 node->body()->Visit(&for_body);
1315 1292
1316 // Labels are set after body traversal. 1293 // Labels are set after body traversal.
1317 SourceLabel* lbl = node->label(); 1294 SourceLabel* lbl = node->label();
1318 ASSERT(lbl != NULL); 1295 ASSERT(lbl != NULL);
1319 JoinEntryInstr* join = lbl->join_for_continue(); 1296 JoinEntryInstr* join = lbl->join_for_continue();
1320 if (join != NULL) { 1297 if (join != NULL) {
1321 join->set_loop_depth(loop_depth() + 1);
1322 if (for_body.is_open()) for_body.Goto(join); 1298 if (for_body.is_open()) for_body.Goto(join);
1323 for_body.exit_ = join; 1299 for_body.exit_ = join;
1324 } 1300 }
1325 TieLoop(for_test, for_body); 1301 TieLoop(for_test, for_body);
1326 join = lbl->join_for_break(); 1302 join = lbl->join_for_break();
1327 if (join != NULL) { 1303 if (join != NULL) {
1328 join->set_loop_depth(loop_depth());
1329 Goto(join); 1304 Goto(join);
1330 exit_ = join; 1305 exit_ = join;
1331 } 1306 }
1332 } 1307 }
1333 1308
1334 1309
1335 // The fragment is composed as follows: 1310 // The fragment is composed as follows:
1336 // a) body-entry-join 1311 // a) body-entry-join
1337 // b) [ body ] 1312 // b) [ body ]
1338 // c) test-entry (continue-join or body-exit-target) 1313 // c) test-entry (continue-join or body-exit-target)
1339 // d) [ test-entry ] -> (back-target, loop-exit-target) 1314 // d) [ test-entry ] -> (back-target, loop-exit-target)
1340 // e) back-target -> (body-entry-join) 1315 // e) back-target -> (body-entry-join)
1341 // f) loop-exit-target 1316 // f) loop-exit-target
1342 // g) break-join 1317 // g) break-join
1343 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { 1318 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) {
1344 // Traverse body first in order to generate continue and break labels. 1319 // Traverse body first in order to generate continue and break labels.
1345 EffectGraphVisitor for_body(owner(), temp_index(), loop_depth() + 1); 1320 EffectGraphVisitor for_body(owner(), temp_index());
1346 for_body.AddInstruction( 1321 for_body.AddInstruction(
1347 new CheckStackOverflowInstr(node->token_pos())); 1322 new CheckStackOverflowInstr(node->token_pos()));
1348 node->body()->Visit(&for_body); 1323 node->body()->Visit(&for_body);
1349 1324
1350 TestGraphVisitor for_test(owner(), 1325 TestGraphVisitor for_test(owner(),
1351 temp_index(), 1326 temp_index(),
1352 loop_depth() + 1,
1353 node->condition()->token_pos()); 1327 node->condition()->token_pos());
1354 node->condition()->Visit(&for_test); 1328 node->condition()->Visit(&for_test);
1355 ASSERT(is_open()); 1329 ASSERT(is_open());
1356 1330
1357 // Tie do-while loop (test is after the body). 1331 // Tie do-while loop (test is after the body).
1358 JoinEntryInstr* body_entry_join = 1332 JoinEntryInstr* body_entry_join =
1359 new JoinEntryInstr(owner()->AllocateBlockId(), 1333 new JoinEntryInstr(owner()->AllocateBlockId(),
1360 owner()->try_index(), 1334 owner()->try_index());
1361 loop_depth() + 1);
1362 Goto(body_entry_join); 1335 Goto(body_entry_join);
1363 Instruction* body_exit = AppendFragment(body_entry_join, for_body); 1336 Instruction* body_exit = AppendFragment(body_entry_join, for_body);
1364 1337
1365 JoinEntryInstr* join = node->label()->join_for_continue(); 1338 JoinEntryInstr* join = node->label()->join_for_continue();
1366 if ((body_exit != NULL) || (join != NULL)) { 1339 if ((body_exit != NULL) || (join != NULL)) {
1367 if (join == NULL) { 1340 if (join == NULL) {
1368 join = new JoinEntryInstr(owner()->AllocateBlockId(), 1341 join = new JoinEntryInstr(owner()->AllocateBlockId(),
1369 owner()->try_index(), 1342 owner()->try_index());
1370 loop_depth() + 1);
1371 } else {
1372 join->set_loop_depth(loop_depth() + 1);
1373 } 1343 }
1374 join->LinkTo(for_test.entry()); 1344 join->LinkTo(for_test.entry());
1375 if (body_exit != NULL) { 1345 if (body_exit != NULL) {
1376 body_exit->Goto(join); 1346 body_exit->Goto(join);
1377 } 1347 }
1378 } 1348 }
1379 1349
1380 for_test.IfTrueGoto(body_entry_join); 1350 for_test.IfTrueGoto(body_entry_join);
1381 join = node->label()->join_for_break(); 1351 join = node->label()->join_for_break();
1382 if (join == NULL) { 1352 if (join == NULL) {
1383 exit_ = for_test.CreateFalseSuccessor(); 1353 exit_ = for_test.CreateFalseSuccessor();
1384 } else { 1354 } else {
1385 join->set_loop_depth(loop_depth());
1386 for_test.IfFalseGoto(join); 1355 for_test.IfFalseGoto(join);
1387 exit_ = join; 1356 exit_ = join;
1388 } 1357 }
1389 } 1358 }
1390 1359
1391 1360
1392 // A ForNode can contain break and continue jumps. 'break' joins to 1361 // A ForNode can contain break and continue jumps. 'break' joins to
1393 // ForNode exit, 'continue' joins at increment entry. The fragment is composed 1362 // ForNode exit, 'continue' joins at increment entry. The fragment is composed
1394 // as follows: 1363 // as follows:
1395 // a) [ initializer ] 1364 // a) [ initializer ]
1396 // b) loop-join 1365 // b) loop-join
1397 // c) [ test ] -> (body-entry-target, loop-exit-target) 1366 // c) [ test ] -> (body-entry-target, loop-exit-target)
1398 // d) body-entry-target 1367 // d) body-entry-target
1399 // e) [ body ] 1368 // e) [ body ]
1400 // f) continue-join (optional) 1369 // f) continue-join (optional)
1401 // g) [ increment ] -> (loop-join) 1370 // g) [ increment ] -> (loop-join)
1402 // h) loop-exit-target 1371 // h) loop-exit-target
1403 // i) break-join 1372 // i) break-join
1404 void EffectGraphVisitor::VisitForNode(ForNode* node) { 1373 void EffectGraphVisitor::VisitForNode(ForNode* node) {
1405 EffectGraphVisitor for_initializer(owner(), temp_index(), loop_depth()); 1374 EffectGraphVisitor for_initializer(owner(), temp_index());
1406 node->initializer()->Visit(&for_initializer); 1375 node->initializer()->Visit(&for_initializer);
1407 Append(for_initializer); 1376 Append(for_initializer);
1408 ASSERT(is_open()); 1377 ASSERT(is_open());
1409 1378
1410 // Compose body to set any jump labels. 1379 // Compose body to set any jump labels.
1411 EffectGraphVisitor for_body(owner(), temp_index(), loop_depth() + 1); 1380 EffectGraphVisitor for_body(owner(), temp_index());
1412 for_body.AddInstruction( 1381 for_body.AddInstruction(
1413 new CheckStackOverflowInstr(node->token_pos())); 1382 new CheckStackOverflowInstr(node->token_pos()));
1414 node->body()->Visit(&for_body); 1383 node->body()->Visit(&for_body);
1415 1384
1416 // Join loop body, increment and compute their end instruction. 1385 // Join loop body, increment and compute their end instruction.
1417 ASSERT(!for_body.is_empty()); 1386 ASSERT(!for_body.is_empty());
1418 Instruction* loop_increment_end = NULL; 1387 Instruction* loop_increment_end = NULL;
1419 EffectGraphVisitor for_increment(owner(), temp_index(), loop_depth() + 1); 1388 EffectGraphVisitor for_increment(owner(), temp_index());
1420 node->increment()->Visit(&for_increment); 1389 node->increment()->Visit(&for_increment);
1421 JoinEntryInstr* join = node->label()->join_for_continue(); 1390 JoinEntryInstr* join = node->label()->join_for_continue();
1422 if (join != NULL) { 1391 if (join != NULL) {
1423 join->set_loop_depth(loop_depth() + 1);
1424 // Insert the join between the body and increment. 1392 // Insert the join between the body and increment.
1425 if (for_body.is_open()) for_body.Goto(join); 1393 if (for_body.is_open()) for_body.Goto(join);
1426 loop_increment_end = AppendFragment(join, for_increment); 1394 loop_increment_end = AppendFragment(join, for_increment);
1427 ASSERT(loop_increment_end != NULL); 1395 ASSERT(loop_increment_end != NULL);
1428 } else if (for_body.is_open()) { 1396 } else if (for_body.is_open()) {
1429 // Do not insert an extra basic block. 1397 // Do not insert an extra basic block.
1430 for_body.Append(for_increment); 1398 for_body.Append(for_increment);
1431 loop_increment_end = for_body.exit(); 1399 loop_increment_end = for_body.exit();
1432 // 'for_body' contains at least the stack check. 1400 // 'for_body' contains at least the stack check.
1433 ASSERT(loop_increment_end != NULL); 1401 ASSERT(loop_increment_end != NULL);
1434 } else { 1402 } else {
1435 loop_increment_end = NULL; 1403 loop_increment_end = NULL;
1436 } 1404 }
1437 1405
1438 // 'loop_increment_end' is NULL only if there is no join for continue and the 1406 // 'loop_increment_end' is NULL only if there is no join for continue and the
1439 // body is not open, i.e., no backward branch exists. 1407 // body is not open, i.e., no backward branch exists.
1440 if (loop_increment_end != NULL) { 1408 if (loop_increment_end != NULL) {
1441 JoinEntryInstr* loop_start = 1409 JoinEntryInstr* loop_start =
1442 new JoinEntryInstr(owner()->AllocateBlockId(), 1410 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
1443 owner()->try_index(),
1444 loop_depth() + 1);
1445 Goto(loop_start); 1411 Goto(loop_start);
1446 loop_increment_end->Goto(loop_start); 1412 loop_increment_end->Goto(loop_start);
1447 exit_ = loop_start; 1413 exit_ = loop_start;
1448 } 1414 }
1449 1415
1450 if (node->condition() == NULL) { 1416 if (node->condition() == NULL) {
1451 // Endless loop, no test. 1417 // Endless loop, no test.
1452 JoinEntryInstr* body_entry = 1418 JoinEntryInstr* body_entry =
1453 new JoinEntryInstr(owner()->AllocateBlockId(), 1419 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
1454 owner()->try_index(),
1455 loop_depth() + 1);
1456 AppendFragment(body_entry, for_body); 1420 AppendFragment(body_entry, for_body);
1457 Goto(body_entry); 1421 Goto(body_entry);
1458 if (node->label()->join_for_break() != NULL) { 1422 if (node->label()->join_for_break() != NULL) {
1459 node->label()->join_for_break()->set_loop_depth(loop_depth());
1460 // Control flow of ForLoop continues into join_for_break. 1423 // Control flow of ForLoop continues into join_for_break.
1461 exit_ = node->label()->join_for_break(); 1424 exit_ = node->label()->join_for_break();
1462 } 1425 }
1463 } else { 1426 } else {
1464 TestGraphVisitor for_test(owner(), 1427 TestGraphVisitor for_test(owner(),
1465 temp_index(), 1428 temp_index(),
1466 loop_depth() + 1,
1467 node->condition()->token_pos()); 1429 node->condition()->token_pos());
1468 node->condition()->Visit(&for_test); 1430 node->condition()->Visit(&for_test);
1469 Append(for_test); 1431 Append(for_test);
1470 1432
1471 BlockEntryInstr* body_entry = for_test.CreateTrueSuccessor(); 1433 BlockEntryInstr* body_entry = for_test.CreateTrueSuccessor();
1472 AppendFragment(body_entry, for_body); 1434 AppendFragment(body_entry, for_body);
1473 1435
1474 if (node->label()->join_for_break() == NULL) { 1436 if (node->label()->join_for_break() == NULL) {
1475 exit_ = for_test.CreateFalseSuccessor(); 1437 exit_ = for_test.CreateFalseSuccessor();
1476 } else { 1438 } else {
1477 node->label()->join_for_break()->set_loop_depth(loop_depth());
1478 for_test.IfFalseGoto(node->label()->join_for_break()); 1439 for_test.IfFalseGoto(node->label()->join_for_break());
1479 exit_ = node->label()->join_for_break(); 1440 exit_ = node->label()->join_for_break();
1480 } 1441 }
1481 } 1442 }
1482 } 1443 }
1483 1444
1484 1445
1485 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { 1446 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) {
1486 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { 1447 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) {
1487 EffectGraphVisitor for_effect(owner(), temp_index(), loop_depth()); 1448 EffectGraphVisitor for_effect(owner(), temp_index());
1488 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); 1449 node->InlinedFinallyNodeAt(i)->Visit(&for_effect);
1489 Append(for_effect); 1450 Append(for_effect);
1490 if (!is_open()) return; 1451 if (!is_open()) return;
1491 } 1452 }
1492 1453
1493 // Unchain the context(s) up to the outer context level of the scope which 1454 // Unchain the context(s) up to the outer context level of the scope which
1494 // contains the destination label. 1455 // contains the destination label.
1495 SourceLabel* label = node->label(); 1456 SourceLabel* label = node->label();
1496 ASSERT(label->owner() != NULL); 1457 ASSERT(label->owner() != NULL);
1497 int target_context_level = 0; 1458 int target_context_level = 0;
(...skipping 17 matching lines...) Expand all
1515 intptr_t current_context_level = owner()->context_level(); 1476 intptr_t current_context_level = owner()->context_level();
1516 ASSERT(current_context_level >= target_context_level); 1477 ASSERT(current_context_level >= target_context_level);
1517 while (current_context_level-- > target_context_level) { 1478 while (current_context_level-- > target_context_level) {
1518 UnchainContext(); 1479 UnchainContext();
1519 } 1480 }
1520 1481
1521 JoinEntryInstr* jump_target = NULL; 1482 JoinEntryInstr* jump_target = NULL;
1522 if (node->kind() == Token::kBREAK) { 1483 if (node->kind() == Token::kBREAK) {
1523 if (node->label()->join_for_break() == NULL) { 1484 if (node->label()->join_for_break() == NULL) {
1524 node->label()->set_join_for_break( 1485 node->label()->set_join_for_break(
1525 new JoinEntryInstr(owner()->AllocateBlockId(), 1486 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()));
1526 owner()->try_index(),
1527 BlockEntryInstr::kInvalidLoopDepth));
1528 } 1487 }
1529 jump_target = node->label()->join_for_break(); 1488 jump_target = node->label()->join_for_break();
1530 } else { 1489 } else {
1531 if (node->label()->join_for_continue() == NULL) { 1490 if (node->label()->join_for_continue() == NULL) {
1532 node->label()->set_join_for_continue( 1491 node->label()->set_join_for_continue(
1533 new JoinEntryInstr(owner()->AllocateBlockId(), 1492 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()));
1534 owner()->try_index(),
1535 BlockEntryInstr::kInvalidLoopDepth));
1536 } 1493 }
1537 jump_target = node->label()->join_for_continue(); 1494 jump_target = node->label()->join_for_continue();
1538 } 1495 }
1539 Goto(jump_target); 1496 Goto(jump_target);
1540 } 1497 }
1541 1498
1542 1499
1543 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { 1500 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) {
1544 UNREACHABLE(); 1501 UNREACHABLE();
1545 } 1502 }
1546 1503
1547 1504
1548 void EffectGraphVisitor::VisitArgumentDefinitionTestNode( 1505 void EffectGraphVisitor::VisitArgumentDefinitionTestNode(
1549 ArgumentDefinitionTestNode* node) { 1506 ArgumentDefinitionTestNode* node) {
1550 InlineBailout("EffectGraphVisitor::VisitArgumentDefinitionTestNode"); 1507 InlineBailout("EffectGraphVisitor::VisitArgumentDefinitionTestNode");
1551 Definition* load = BuildLoadLocal(node->saved_arguments_descriptor()); 1508 Definition* load = BuildLoadLocal(node->saved_arguments_descriptor());
1552 Value* arguments_descriptor = Bind(load); 1509 Value* arguments_descriptor = Bind(load);
1553 ArgumentDefinitionTestInstr* arg_def_test = 1510 ArgumentDefinitionTestInstr* arg_def_test =
1554 new ArgumentDefinitionTestInstr(node, arguments_descriptor); 1511 new ArgumentDefinitionTestInstr(node, arguments_descriptor);
1555 ReturnDefinition(arg_def_test); 1512 ReturnDefinition(arg_def_test);
1556 } 1513 }
1557 1514
1558 1515
1559 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { 1516 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) {
1560 // Translate the array elements and collect their values. 1517 // Translate the array elements and collect their values.
1561 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1518 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1562 new ZoneGrowableArray<PushArgumentInstr*>(node->length()); 1519 new ZoneGrowableArray<PushArgumentInstr*>(node->length());
1563 for (int i = 0; i < node->length(); ++i) { 1520 for (int i = 0; i < node->length(); ++i) {
1564 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); 1521 ValueGraphVisitor for_value(owner(), temp_index());
1565 node->ElementAt(i)->Visit(&for_value); 1522 node->ElementAt(i)->Visit(&for_value);
1566 Append(for_value); 1523 Append(for_value);
1567 arguments->Add(PushArgument(for_value.value())); 1524 arguments->Add(PushArgument(for_value.value()));
1568 } 1525 }
1569 const AbstractTypeArguments& type_args = 1526 const AbstractTypeArguments& type_args =
1570 AbstractTypeArguments::ZoneHandle(node->type().arguments()); 1527 AbstractTypeArguments::ZoneHandle(node->type().arguments());
1571 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), 1528 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(),
1572 type_args); 1529 type_args);
1573 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), 1530 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(),
1574 arguments, 1531 arguments,
(...skipping 26 matching lines...) Expand all
1601 // TODO(regis): Why are we not doing this in the parser? 1558 // TODO(regis): Why are we not doing this in the parser?
1602 const ContextScope& context_scope = ContextScope::ZoneHandle( 1559 const ContextScope& context_scope = ContextScope::ZoneHandle(
1603 node->scope()->PreserveOuterScope(owner()->context_level())); 1560 node->scope()->PreserveOuterScope(owner()->context_level()));
1604 ASSERT(!function.HasCode()); 1561 ASSERT(!function.HasCode());
1605 ASSERT(function.context_scope() == ContextScope::null()); 1562 ASSERT(function.context_scope() == ContextScope::null());
1606 function.set_context_scope(context_scope); 1563 function.set_context_scope(context_scope);
1607 } 1564 }
1608 receiver = BuildNullValue(); 1565 receiver = BuildNullValue();
1609 } else { 1566 } else {
1610 ASSERT(function.IsImplicitInstanceClosureFunction()); 1567 ASSERT(function.IsImplicitInstanceClosureFunction());
1611 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); 1568 ValueGraphVisitor for_receiver(owner(), temp_index());
1612 node->receiver()->Visit(&for_receiver); 1569 node->receiver()->Visit(&for_receiver);
1613 Append(for_receiver); 1570 Append(for_receiver);
1614 receiver = for_receiver.value(); 1571 receiver = for_receiver.value();
1615 } 1572 }
1616 PushArgumentInstr* push_receiver = PushArgument(receiver); 1573 PushArgumentInstr* push_receiver = PushArgument(receiver);
1617 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1574 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1618 new ZoneGrowableArray<PushArgumentInstr*>(2); 1575 new ZoneGrowableArray<PushArgumentInstr*>(2);
1619 arguments->Add(push_receiver); 1576 arguments->Add(push_receiver);
1620 ASSERT(function.context_scope() != ContextScope::null()); 1577 ASSERT(function.context_scope() != ContextScope::null());
1621 1578
(...skipping 13 matching lines...) Expand all
1635 arguments->Add(push_type_arguments); 1592 arguments->Add(push_type_arguments);
1636 ReturnDefinition( 1593 ReturnDefinition(
1637 new CreateClosureInstr(node->function(), arguments, node->token_pos())); 1594 new CreateClosureInstr(node->function(), arguments, node->token_pos()));
1638 } 1595 }
1639 1596
1640 1597
1641 void EffectGraphVisitor::TranslateArgumentList( 1598 void EffectGraphVisitor::TranslateArgumentList(
1642 const ArgumentListNode& node, 1599 const ArgumentListNode& node,
1643 ZoneGrowableArray<Value*>* values) { 1600 ZoneGrowableArray<Value*>* values) {
1644 for (intptr_t i = 0; i < node.length(); ++i) { 1601 for (intptr_t i = 0; i < node.length(); ++i) {
1645 ValueGraphVisitor for_argument(owner(), temp_index(), loop_depth()); 1602 ValueGraphVisitor for_argument(owner(), temp_index());
1646 node.NodeAt(i)->Visit(&for_argument); 1603 node.NodeAt(i)->Visit(&for_argument);
1647 Append(for_argument); 1604 Append(for_argument);
1648 values->Add(for_argument.value()); 1605 values->Add(for_argument.value());
1649 } 1606 }
1650 } 1607 }
1651 1608
1652 1609
1653 void EffectGraphVisitor::BuildPushArguments( 1610 void EffectGraphVisitor::BuildPushArguments(
1654 const ArgumentListNode& node, 1611 const ArgumentListNode& node,
1655 ZoneGrowableArray<PushArgumentInstr*>* values) { 1612 ZoneGrowableArray<PushArgumentInstr*>* values) {
1656 for (intptr_t i = 0; i < node.length(); ++i) { 1613 for (intptr_t i = 0; i < node.length(); ++i) {
1657 ValueGraphVisitor for_argument(owner(), temp_index(), loop_depth()); 1614 ValueGraphVisitor for_argument(owner(), temp_index());
1658 node.NodeAt(i)->Visit(&for_argument); 1615 node.NodeAt(i)->Visit(&for_argument);
1659 Append(for_argument); 1616 Append(for_argument);
1660 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); 1617 PushArgumentInstr* push_arg = PushArgument(for_argument.value());
1661 values->Add(push_arg); 1618 values->Add(push_arg);
1662 } 1619 }
1663 } 1620 }
1664 1621
1665 1622
1666 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { 1623 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
1667 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); 1624 ValueGraphVisitor for_receiver(owner(), temp_index());
1668 node->receiver()->Visit(&for_receiver); 1625 node->receiver()->Visit(&for_receiver);
1669 Append(for_receiver); 1626 Append(for_receiver);
1670 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); 1627 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
1671 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1628 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1672 new ZoneGrowableArray<PushArgumentInstr*>( 1629 new ZoneGrowableArray<PushArgumentInstr*>(
1673 node->arguments()->length() + 1); 1630 node->arguments()->length() + 1);
1674 arguments->Add(push_receiver); 1631 arguments->Add(push_receiver);
1675 1632
1676 BuildPushArguments(*node->arguments(), arguments); 1633 BuildPushArguments(*node->arguments(), arguments);
1677 InstanceCallInstr* call = new InstanceCallInstr( 1634 InstanceCallInstr* call = new InstanceCallInstr(
1678 node->token_pos(), 1635 node->token_pos(),
1679 node->function_name(), Token::kILLEGAL, arguments, 1636 node->function_name(), Token::kILLEGAL, arguments,
1680 node->arguments()->names(), 1); 1637 node->arguments()->names(), 1);
1681 ReturnDefinition(call); 1638 ReturnDefinition(call);
1682 } 1639 }
1683 1640
1684 1641
1685 // <Expression> ::= StaticCall { function: Function 1642 // <Expression> ::= StaticCall { function: Function
1686 // arguments: <ArgumentList> } 1643 // arguments: <ArgumentList> }
1687 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { 1644 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
1688 if (node->function().name() == Symbols::Identical().raw()) { 1645 if (node->function().name() == Symbols::Identical().raw()) {
1689 // Attempt to replace top level defined 'identical' from the core 1646 // Attempt to replace top level defined 'identical' from the core
1690 // library with strict equal early on. 1647 // library with strict equal early on.
1691 // TODO(hausner): Evaluate if this can happen at AST building time. 1648 // TODO(hausner): Evaluate if this can happen at AST building time.
1692 const Class& cls = Class::Handle(node->function().Owner()); 1649 const Class& cls = Class::Handle(node->function().Owner());
1693 if (cls.IsTopLevel()) { 1650 if (cls.IsTopLevel()) {
1694 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 1651 const Library& core_lib = Library::Handle(Library::CoreLibrary());
1695 if (cls.library() == core_lib.raw()) { 1652 if (cls.library() == core_lib.raw()) {
1696 ASSERT(node->arguments()->length() == 2); 1653 ASSERT(node->arguments()->length() == 2);
1697 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth()); 1654 ValueGraphVisitor for_left_value(owner(), temp_index());
1698 node->arguments()->NodeAt(0)->Visit(&for_left_value); 1655 node->arguments()->NodeAt(0)->Visit(&for_left_value);
1699 Append(for_left_value); 1656 Append(for_left_value);
1700 ValueGraphVisitor for_right_value(owner(), temp_index(), loop_depth()); 1657 ValueGraphVisitor for_right_value(owner(), temp_index());
1701 node->arguments()->NodeAt(1)->Visit(&for_right_value); 1658 node->arguments()->NodeAt(1)->Visit(&for_right_value);
1702 Append(for_right_value); 1659 Append(for_right_value);
1703 StrictCompareInstr* comp = new StrictCompareInstr( 1660 StrictCompareInstr* comp = new StrictCompareInstr(
1704 Token::kEQ_STRICT, 1661 Token::kEQ_STRICT,
1705 for_left_value.value(), 1662 for_left_value.value(),
1706 for_right_value.value()); 1663 for_right_value.value());
1707 ReturnDefinition(comp); 1664 ReturnDefinition(comp);
1708 return; 1665 return;
1709 } 1666 }
1710 } 1667 }
1711 } 1668 }
1712 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1669 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1713 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); 1670 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length());
1714 BuildPushArguments(*node->arguments(), arguments); 1671 BuildPushArguments(*node->arguments(), arguments);
1715 StaticCallInstr* call = 1672 StaticCallInstr* call =
1716 new StaticCallInstr(node->token_pos(), 1673 new StaticCallInstr(node->token_pos(),
1717 node->function(), 1674 node->function(),
1718 node->arguments()->names(), 1675 node->arguments()->names(),
1719 arguments); 1676 arguments);
1720 ReturnDefinition(call); 1677 ReturnDefinition(call);
1721 } 1678 }
1722 1679
1723 1680
1724 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall( 1681 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall(
1725 ClosureCallNode* node) { 1682 ClosureCallNode* node) {
1726 ValueGraphVisitor for_closure(owner(), temp_index(), loop_depth()); 1683 ValueGraphVisitor for_closure(owner(), temp_index());
1727 node->closure()->Visit(&for_closure); 1684 node->closure()->Visit(&for_closure);
1728 Append(for_closure); 1685 Append(for_closure);
1729 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); 1686 PushArgumentInstr* push_closure = PushArgument(for_closure.value());
1730 1687
1731 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1688 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1732 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); 1689 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length());
1733 arguments->Add(push_closure); 1690 arguments->Add(push_closure);
1734 BuildPushArguments(*node->arguments(), arguments); 1691 BuildPushArguments(*node->arguments(), arguments);
1735 1692
1736 // Save context around the call. 1693 // Save context around the call.
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1915 Function& outer_function = 1872 Function& outer_function =
1916 Function::Handle(owner()->parsed_function().function().raw()); 1873 Function::Handle(owner()->parsed_function().function().raw());
1917 while (outer_function.IsLocalFunction()) { 1874 while (outer_function.IsLocalFunction()) {
1918 outer_function = outer_function.parent_function(); 1875 outer_function = outer_function.parent_function();
1919 } 1876 }
1920 if (outer_function.IsFactory()) { 1877 if (outer_function.IsFactory()) {
1921 return NULL; 1878 return NULL;
1922 } 1879 }
1923 1880
1924 ASSERT(owner()->parsed_function().instantiator() != NULL); 1881 ASSERT(owner()->parsed_function().instantiator() != NULL);
1925 ValueGraphVisitor for_instantiator(owner(), temp_index(), loop_depth()); 1882 ValueGraphVisitor for_instantiator(owner(), temp_index());
1926 owner()->parsed_function().instantiator()->Visit(&for_instantiator); 1883 owner()->parsed_function().instantiator()->Visit(&for_instantiator);
1927 Append(for_instantiator); 1884 Append(for_instantiator);
1928 return for_instantiator.value(); 1885 return for_instantiator.value();
1929 } 1886 }
1930 1887
1931 1888
1932 // 'expression_temp_var' may not be used inside this method if 'instantiator' 1889 // 'expression_temp_var' may not be used inside this method if 'instantiator'
1933 // is not NULL. 1890 // is not NULL.
1934 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( 1891 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments(
1935 intptr_t token_pos, Value* instantiator) { 1892 intptr_t token_pos, Value* instantiator) {
(...skipping 14 matching lines...) Expand all
1950 } 1907 }
1951 Function& outer_function = 1908 Function& outer_function =
1952 Function::Handle(owner()->parsed_function().function().raw()); 1909 Function::Handle(owner()->parsed_function().function().raw());
1953 while (outer_function.IsLocalFunction()) { 1910 while (outer_function.IsLocalFunction()) {
1954 outer_function = outer_function.parent_function(); 1911 outer_function = outer_function.parent_function();
1955 } 1912 }
1956 if (outer_function.IsFactory()) { 1913 if (outer_function.IsFactory()) {
1957 // No instantiator for factories. 1914 // No instantiator for factories.
1958 ASSERT(instantiator == NULL); 1915 ASSERT(instantiator == NULL);
1959 ASSERT(owner()->parsed_function().instantiator() != NULL); 1916 ASSERT(owner()->parsed_function().instantiator() != NULL);
1960 ValueGraphVisitor for_instantiator(owner(), temp_index(), loop_depth()); 1917 ValueGraphVisitor for_instantiator(owner(), temp_index());
1961 owner()->parsed_function().instantiator()->Visit(&for_instantiator); 1918 owner()->parsed_function().instantiator()->Visit(&for_instantiator);
1962 Append(for_instantiator); 1919 Append(for_instantiator);
1963 return for_instantiator.value(); 1920 return for_instantiator.value();
1964 } 1921 }
1965 if (instantiator == NULL) { 1922 if (instantiator == NULL) {
1966 instantiator = BuildInstantiator(); 1923 instantiator = BuildInstantiator();
1967 } 1924 }
1968 // The instantiator is the receiver of the caller, which is not a factory. 1925 // The instantiator is the receiver of the caller, which is not a factory.
1969 // The receiver cannot be null; extract its AbstractTypeArguments object. 1926 // The receiver cannot be null; extract its AbstractTypeArguments object.
1970 // Note that in the factory case, the instantiator is the first parameter 1927 // Note that in the factory case, the instantiator is the first parameter
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
2098 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); 2055 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value);
2099 BuildConstructorCall(node, push_allocated_value); 2056 BuildConstructorCall(node, push_allocated_value);
2100 Definition* load_allocated = BuildLoadLocal( 2057 Definition* load_allocated = BuildLoadLocal(
2101 node->allocated_object_var()); 2058 node->allocated_object_var());
2102 allocated_value = Bind(load_allocated); 2059 allocated_value = Bind(load_allocated);
2103 ReturnValue(allocated_value); 2060 ReturnValue(allocated_value);
2104 } 2061 }
2105 2062
2106 2063
2107 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { 2064 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
2108 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); 2065 ValueGraphVisitor for_receiver(owner(), temp_index());
2109 node->receiver()->Visit(&for_receiver); 2066 node->receiver()->Visit(&for_receiver);
2110 Append(for_receiver); 2067 Append(for_receiver);
2111 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); 2068 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
2112 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2069 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2113 new ZoneGrowableArray<PushArgumentInstr*>(1); 2070 new ZoneGrowableArray<PushArgumentInstr*>(1);
2114 arguments->Add(push_receiver); 2071 arguments->Add(push_receiver);
2115 const String& name = 2072 const String& name =
2116 String::ZoneHandle(Field::GetterSymbol(node->field_name())); 2073 String::ZoneHandle(Field::GetterSymbol(node->field_name()));
2117 InstanceCallInstr* call = new InstanceCallInstr( 2074 InstanceCallInstr* call = new InstanceCallInstr(
2118 node->token_pos(), name, Token::kGET, 2075 node->token_pos(), name, Token::kGET,
2119 arguments, Array::ZoneHandle(), 1); 2076 arguments, Array::ZoneHandle(), 1);
2120 ReturnDefinition(call); 2077 ReturnDefinition(call);
2121 } 2078 }
2122 2079
2123 2080
2124 void EffectGraphVisitor::BuildInstanceSetterArguments( 2081 void EffectGraphVisitor::BuildInstanceSetterArguments(
2125 InstanceSetterNode* node, 2082 InstanceSetterNode* node,
2126 ZoneGrowableArray<PushArgumentInstr*>* arguments, 2083 ZoneGrowableArray<PushArgumentInstr*>* arguments,
2127 bool result_is_needed) { 2084 bool result_is_needed) {
2128 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); 2085 ValueGraphVisitor for_receiver(owner(), temp_index());
2129 node->receiver()->Visit(&for_receiver); 2086 node->receiver()->Visit(&for_receiver);
2130 Append(for_receiver); 2087 Append(for_receiver);
2131 arguments->Add(PushArgument(for_receiver.value())); 2088 arguments->Add(PushArgument(for_receiver.value()));
2132 2089
2133 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); 2090 ValueGraphVisitor for_value(owner(), temp_index());
2134 node->value()->Visit(&for_value); 2091 node->value()->Visit(&for_value);
2135 Append(for_value); 2092 Append(for_value);
2136 2093
2137 Value* value = NULL; 2094 Value* value = NULL;
2138 if (result_is_needed) { 2095 if (result_is_needed) {
2139 value = Bind(BuildStoreExprTemp(for_value.value())); 2096 value = Bind(BuildStoreExprTemp(for_value.value()));
2140 } else { 2097 } else {
2141 value = for_value.value(); 2098 value = for_value.value();
2142 } 2099 }
2143 arguments->Add(PushArgument(value)); 2100 arguments->Add(PushArgument(value));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2190 // Resolve and call noSuchMethod. 2147 // Resolve and call noSuchMethod.
2191 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); 2148 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos());
2192 arguments->Add(node->receiver()); 2149 arguments->Add(node->receiver());
2193 StaticCallInstr* call = BuildStaticNoSuchMethodCall(node->cls(), 2150 StaticCallInstr* call = BuildStaticNoSuchMethodCall(node->cls(),
2194 node->receiver(), 2151 node->receiver(),
2195 getter_name, 2152 getter_name,
2196 arguments); 2153 arguments);
2197 ReturnDefinition(call); 2154 ReturnDefinition(call);
2198 return; 2155 return;
2199 } else { 2156 } else {
2200 ValueGraphVisitor receiver_value(owner(), temp_index(), loop_depth()); 2157 ValueGraphVisitor receiver_value(owner(), temp_index());
2201 node->receiver()->Visit(&receiver_value); 2158 node->receiver()->Visit(&receiver_value);
2202 Append(receiver_value); 2159 Append(receiver_value);
2203 arguments->Add(PushArgument(receiver_value.value())); 2160 arguments->Add(PushArgument(receiver_value.value()));
2204 } 2161 }
2205 } else { 2162 } else {
2206 getter_function = node->cls().LookupStaticFunction(getter_name); 2163 getter_function = node->cls().LookupStaticFunction(getter_name);
2207 if (getter_function.IsNull()) { 2164 if (getter_function.IsNull()) {
2208 // When the parser encounters a reference to a static field materialized 2165 // When the parser encounters a reference to a static field materialized
2209 // only by a static setter, but no corresponding static getter, it creates 2166 // only by a static setter, but no corresponding static getter, it creates
2210 // a StaticGetterNode ast node referring to the non-existing static getter 2167 // a StaticGetterNode ast node referring to the non-existing static getter
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2264 arguments); 2221 arguments);
2265 } else { 2222 } else {
2266 // Throw a NoSuchMethodError. 2223 // Throw a NoSuchMethodError.
2267 call = BuildThrowNoSuchMethodError(node->token_pos(), 2224 call = BuildThrowNoSuchMethodError(node->token_pos(),
2268 node->cls(), 2225 node->cls(),
2269 setter_name); 2226 setter_name);
2270 } 2227 }
2271 } else { 2228 } else {
2272 if (is_super_setter) { 2229 if (is_super_setter) {
2273 // Add receiver of instance getter. 2230 // Add receiver of instance getter.
2274 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); 2231 ValueGraphVisitor for_receiver(owner(), temp_index());
2275 node->receiver()->Visit(&for_receiver); 2232 node->receiver()->Visit(&for_receiver);
2276 Append(for_receiver); 2233 Append(for_receiver);
2277 arguments->Add(PushArgument(for_receiver.value())); 2234 arguments->Add(PushArgument(for_receiver.value()));
2278 } 2235 }
2279 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); 2236 ValueGraphVisitor for_value(owner(), temp_index());
2280 node->value()->Visit(&for_value); 2237 node->value()->Visit(&for_value);
2281 Append(for_value); 2238 Append(for_value);
2282 Value* value = NULL; 2239 Value* value = NULL;
2283 if (result_is_needed) { 2240 if (result_is_needed) {
2284 value = Bind(BuildStoreExprTemp(for_value.value())); 2241 value = Bind(BuildStoreExprTemp(for_value.value()));
2285 } else { 2242 } else {
2286 value = for_value.value(); 2243 value = for_value.value();
2287 } 2244 }
2288 arguments->Add(PushArgument(value)); 2245 arguments->Add(PushArgument(value));
2289 2246
(...skipping 30 matching lines...) Expand all
2320 2277
2321 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { 2278 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) {
2322 // PrimaryNodes are temporary during parsing. 2279 // PrimaryNodes are temporary during parsing.
2323 UNREACHABLE(); 2280 UNREACHABLE();
2324 } 2281 }
2325 2282
2326 2283
2327 // <Expression> ::= LoadLocal { local: LocalVariable } 2284 // <Expression> ::= LoadLocal { local: LocalVariable }
2328 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { 2285 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) {
2329 if (node->HasPseudo()) { 2286 if (node->HasPseudo()) {
2330 EffectGraphVisitor for_pseudo(owner(), temp_index(), loop_depth()); 2287 EffectGraphVisitor for_pseudo(owner(), temp_index());
2331 node->pseudo()->Visit(&for_pseudo); 2288 node->pseudo()->Visit(&for_pseudo);
2332 Append(for_pseudo); 2289 Append(for_pseudo);
2333 } 2290 }
2334 } 2291 }
2335 2292
2336 2293
2337 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { 2294 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) {
2338 EffectGraphVisitor::VisitLoadLocalNode(node); 2295 EffectGraphVisitor::VisitLoadLocalNode(node);
2339 Definition* load = BuildLoadLocal(node->local()); 2296 Definition* load = BuildLoadLocal(node->local());
2340 ReturnDefinition(load); 2297 ReturnDefinition(load);
2341 } 2298 }
2342 2299
2343 2300
2344 // <Expression> ::= StoreLocal { local: LocalVariable 2301 // <Expression> ::= StoreLocal { local: LocalVariable
2345 // value: <Expression> } 2302 // value: <Expression> }
2346 void EffectGraphVisitor::HandleStoreLocal(StoreLocalNode* node, 2303 void EffectGraphVisitor::HandleStoreLocal(StoreLocalNode* node,
2347 bool result_is_needed) { 2304 bool result_is_needed) {
2348 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); 2305 ValueGraphVisitor for_value(owner(), temp_index());
2349 node->value()->Visit(&for_value); 2306 node->value()->Visit(&for_value);
2350 Append(for_value); 2307 Append(for_value);
2351 Value* store_value = for_value.value(); 2308 Value* store_value = for_value.value();
2352 if (FLAG_enable_type_checks) { 2309 if (FLAG_enable_type_checks) {
2353 store_value = BuildAssignableValue(node->value()->token_pos(), 2310 store_value = BuildAssignableValue(node->value()->token_pos(),
2354 store_value, 2311 store_value,
2355 node->local().type(), 2312 node->local().type(),
2356 node->local().name()); 2313 node->local().name());
2357 } 2314 }
2358 Definition* store = BuildStoreLocal(node->local(), 2315 Definition* store = BuildStoreLocal(node->local(),
2359 store_value, 2316 store_value,
2360 result_is_needed); 2317 result_is_needed);
2361 ReturnDefinition(store); 2318 ReturnDefinition(store);
2362 } 2319 }
2363 2320
2364 2321
2365 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { 2322 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
2366 HandleStoreLocal(node, kResultNotNeeded); 2323 HandleStoreLocal(node, kResultNotNeeded);
2367 } 2324 }
2368 2325
2369 2326
2370 void ValueGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { 2327 void ValueGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
2371 HandleStoreLocal(node, kResultNeeded); 2328 HandleStoreLocal(node, kResultNeeded);
2372 } 2329 }
2373 2330
2374 2331
2375 void EffectGraphVisitor::VisitLoadInstanceFieldNode( 2332 void EffectGraphVisitor::VisitLoadInstanceFieldNode(
2376 LoadInstanceFieldNode* node) { 2333 LoadInstanceFieldNode* node) {
2377 ValueGraphVisitor for_instance(owner(), temp_index(), loop_depth()); 2334 ValueGraphVisitor for_instance(owner(), temp_index());
2378 node->instance()->Visit(&for_instance); 2335 node->instance()->Visit(&for_instance);
2379 Append(for_instance); 2336 Append(for_instance);
2380 LoadFieldInstr* load = new LoadFieldInstr( 2337 LoadFieldInstr* load = new LoadFieldInstr(
2381 for_instance.value(), 2338 for_instance.value(),
2382 node->field().Offset(), 2339 node->field().Offset(),
2383 AbstractType::ZoneHandle(node->field().type())); 2340 AbstractType::ZoneHandle(node->field().type()));
2384 ReturnDefinition(load); 2341 ReturnDefinition(load);
2385 } 2342 }
2386 2343
2387 2344
2388 void EffectGraphVisitor::VisitStoreInstanceFieldNode( 2345 void EffectGraphVisitor::VisitStoreInstanceFieldNode(
2389 StoreInstanceFieldNode* node) { 2346 StoreInstanceFieldNode* node) {
2390 ValueGraphVisitor for_instance(owner(), temp_index(), loop_depth()); 2347 ValueGraphVisitor for_instance(owner(), temp_index());
2391 node->instance()->Visit(&for_instance); 2348 node->instance()->Visit(&for_instance);
2392 Append(for_instance); 2349 Append(for_instance);
2393 ValueGraphVisitor for_value(owner(), for_instance.temp_index(), loop_depth()); 2350 ValueGraphVisitor for_value(owner(), for_instance.temp_index());
2394 node->value()->Visit(&for_value); 2351 node->value()->Visit(&for_value);
2395 Append(for_value); 2352 Append(for_value);
2396 Value* store_value = for_value.value(); 2353 Value* store_value = for_value.value();
2397 if (FLAG_enable_type_checks) { 2354 if (FLAG_enable_type_checks) {
2398 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); 2355 const AbstractType& type = AbstractType::ZoneHandle(node->field().type());
2399 const String& dst_name = String::ZoneHandle(node->field().name()); 2356 const String& dst_name = String::ZoneHandle(node->field().name());
2400 store_value = BuildAssignableValue(node->value()->token_pos(), 2357 store_value = BuildAssignableValue(node->value()->token_pos(),
2401 store_value, 2358 store_value,
2402 type, 2359 type,
2403 dst_name); 2360 dst_name);
(...skipping 13 matching lines...) Expand all
2417 2374
2418 2375
2419 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { 2376 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) {
2420 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(node->field()); 2377 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(node->field());
2421 ReturnDefinition(load); 2378 ReturnDefinition(load);
2422 } 2379 }
2423 2380
2424 2381
2425 Definition* EffectGraphVisitor::BuildStoreStaticField( 2382 Definition* EffectGraphVisitor::BuildStoreStaticField(
2426 StoreStaticFieldNode* node, bool result_is_needed) { 2383 StoreStaticFieldNode* node, bool result_is_needed) {
2427 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); 2384 ValueGraphVisitor for_value(owner(), temp_index());
2428 node->value()->Visit(&for_value); 2385 node->value()->Visit(&for_value);
2429 Append(for_value); 2386 Append(for_value);
2430 Value* store_value = NULL; 2387 Value* store_value = NULL;
2431 if (result_is_needed) { 2388 if (result_is_needed) {
2432 store_value = Bind(BuildStoreExprTemp(for_value.value())); 2389 store_value = Bind(BuildStoreExprTemp(for_value.value()));
2433 } else { 2390 } else {
2434 store_value = for_value.value(); 2391 store_value = for_value.value();
2435 } 2392 }
2436 if (FLAG_enable_type_checks) { 2393 if (FLAG_enable_type_checks) {
2437 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); 2394 const AbstractType& type = AbstractType::ZoneHandle(node->field().type());
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2480 BuildStaticNoSuchMethodCall(node->super_class(), 2437 BuildStaticNoSuchMethodCall(node->super_class(),
2481 node->array(), 2438 node->array(),
2482 Symbols::IndexToken(), 2439 Symbols::IndexToken(),
2483 arguments); 2440 arguments);
2484 ReturnDefinition(call); 2441 ReturnDefinition(call);
2485 return; 2442 return;
2486 } 2443 }
2487 } 2444 }
2488 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2445 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2489 new ZoneGrowableArray<PushArgumentInstr*>(2); 2446 new ZoneGrowableArray<PushArgumentInstr*>(2);
2490 ValueGraphVisitor for_array(owner(), temp_index(), loop_depth()); 2447 ValueGraphVisitor for_array(owner(), temp_index());
2491 node->array()->Visit(&for_array); 2448 node->array()->Visit(&for_array);
2492 Append(for_array); 2449 Append(for_array);
2493 arguments->Add(PushArgument(for_array.value())); 2450 arguments->Add(PushArgument(for_array.value()));
2494 2451
2495 ValueGraphVisitor for_index(owner(), temp_index(), loop_depth()); 2452 ValueGraphVisitor for_index(owner(), temp_index());
2496 node->index_expr()->Visit(&for_index); 2453 node->index_expr()->Visit(&for_index);
2497 Append(for_index); 2454 Append(for_index);
2498 arguments->Add(PushArgument(for_index.value())); 2455 arguments->Add(PushArgument(for_index.value()));
2499 2456
2500 if (super_function != NULL) { 2457 if (super_function != NULL) {
2501 // Generate static call to super operator. 2458 // Generate static call to super operator.
2502 StaticCallInstr* load = new StaticCallInstr(node->token_pos(), 2459 StaticCallInstr* load = new StaticCallInstr(node->token_pos(),
2503 *super_function, 2460 *super_function,
2504 Array::ZoneHandle(), 2461 Array::ZoneHandle(),
2505 arguments); 2462 arguments);
(...skipping 20 matching lines...) Expand all
2526 // Resolve the store indexed operator in the super class. 2483 // Resolve the store indexed operator in the super class.
2527 super_function = &Function::ZoneHandle( 2484 super_function = &Function::ZoneHandle(
2528 Resolver::ResolveDynamicAnyArgs(node->super_class(), 2485 Resolver::ResolveDynamicAnyArgs(node->super_class(),
2529 Symbols::AssignIndexToken())); 2486 Symbols::AssignIndexToken()));
2530 if (super_function->IsNull()) { 2487 if (super_function->IsNull()) {
2531 // Could not resolve super operator. Generate call noSuchMethod() of the 2488 // Could not resolve super operator. Generate call noSuchMethod() of the
2532 // super class instead. 2489 // super class instead.
2533 if (result_is_needed) { 2490 if (result_is_needed) {
2534 // Even though noSuchMethod most likely does not return, 2491 // Even though noSuchMethod most likely does not return,
2535 // we save the stored value if the result is needed. 2492 // we save the stored value if the result is needed.
2536 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); 2493 ValueGraphVisitor for_value(owner(), temp_index());
2537 node->value()->Visit(&for_value); 2494 node->value()->Visit(&for_value);
2538 Append(for_value); 2495 Append(for_value);
2539 Bind(BuildStoreExprTemp(for_value.value())); 2496 Bind(BuildStoreExprTemp(for_value.value()));
2540 } 2497 }
2541 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); 2498 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos());
2542 arguments->Add(node->array()); 2499 arguments->Add(node->array());
2543 arguments->Add(node->index_expr()); 2500 arguments->Add(node->index_expr());
2544 arguments->Add(node->value()); 2501 arguments->Add(node->value());
2545 StaticCallInstr* call = 2502 StaticCallInstr* call =
2546 BuildStaticNoSuchMethodCall(node->super_class(), 2503 BuildStaticNoSuchMethodCall(node->super_class(),
2547 node->array(), 2504 node->array(),
2548 Symbols::AssignIndexToken(), 2505 Symbols::AssignIndexToken(),
2549 arguments); 2506 arguments);
2550 if (result_is_needed) { 2507 if (result_is_needed) {
2551 Do(call); 2508 Do(call);
2552 return BuildLoadExprTemp(); 2509 return BuildLoadExprTemp();
2553 } else { 2510 } else {
2554 return call; 2511 return call;
2555 } 2512 }
2556 } 2513 }
2557 } 2514 }
2558 2515
2559 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2516 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2560 new ZoneGrowableArray<PushArgumentInstr*>(3); 2517 new ZoneGrowableArray<PushArgumentInstr*>(3);
2561 ValueGraphVisitor for_array(owner(), temp_index(), loop_depth()); 2518 ValueGraphVisitor for_array(owner(), temp_index());
2562 node->array()->Visit(&for_array); 2519 node->array()->Visit(&for_array);
2563 Append(for_array); 2520 Append(for_array);
2564 arguments->Add(PushArgument(for_array.value())); 2521 arguments->Add(PushArgument(for_array.value()));
2565 2522
2566 ValueGraphVisitor for_index(owner(), temp_index(), loop_depth()); 2523 ValueGraphVisitor for_index(owner(), temp_index());
2567 node->index_expr()->Visit(&for_index); 2524 node->index_expr()->Visit(&for_index);
2568 Append(for_index); 2525 Append(for_index);
2569 arguments->Add(PushArgument(for_index.value())); 2526 arguments->Add(PushArgument(for_index.value()));
2570 2527
2571 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth()); 2528 ValueGraphVisitor for_value(owner(), temp_index());
2572 node->value()->Visit(&for_value); 2529 node->value()->Visit(&for_value);
2573 Append(for_value); 2530 Append(for_value);
2574 Value* value = NULL; 2531 Value* value = NULL;
2575 if (result_is_needed) { 2532 if (result_is_needed) {
2576 value = Bind(BuildStoreExprTemp(for_value.value())); 2533 value = Bind(BuildStoreExprTemp(for_value.value()));
2577 } else { 2534 } else {
2578 value = for_value.value(); 2535 value = for_value.value();
2579 } 2536 }
2580 arguments->Add(PushArgument(value)); 2537 arguments->Add(PushArgument(value));
2581 2538
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
2747 // variable so that ssa renaming detects the dependency and makes use 2704 // variable so that ssa renaming detects the dependency and makes use
2748 // of the checked type in type propagation. 2705 // of the checked type in type propagation.
2749 Do(BuildStoreLocal(parameter, parameter_value, kResultNotNeeded)); 2706 Do(BuildStoreLocal(parameter, parameter_value, kResultNotNeeded));
2750 } 2707 }
2751 pos++; 2708 pos++;
2752 } 2709 }
2753 } 2710 }
2754 2711
2755 intptr_t i = 0; 2712 intptr_t i = 0;
2756 while (is_open() && (i < node->length())) { 2713 while (is_open() && (i < node->length())) {
2757 EffectGraphVisitor for_effect(owner(), temp_index(), loop_depth()); 2714 EffectGraphVisitor for_effect(owner(), temp_index());
2758 node->NodeAt(i++)->Visit(&for_effect); 2715 node->NodeAt(i++)->Visit(&for_effect);
2759 Append(for_effect); 2716 Append(for_effect);
2760 if (!is_open()) { 2717 if (!is_open()) {
2761 // E.g., because of a JumpNode. 2718 // E.g., because of a JumpNode.
2762 break; 2719 break;
2763 } 2720 }
2764 } 2721 }
2765 2722
2766 if (is_open()) { 2723 if (is_open()) {
2767 if (MustSaveRestoreContext(node)) { 2724 if (MustSaveRestoreContext(node)) {
2768 ASSERT(num_context_variables > 0); 2725 ASSERT(num_context_variables > 0);
2769 BuildLoadContext(*owner()->parsed_function().saved_context_var()); 2726 BuildLoadContext(*owner()->parsed_function().saved_context_var());
2770 } else if (num_context_variables > 0) { 2727 } else if (num_context_variables > 0) {
2771 UnchainContext(); 2728 UnchainContext();
2772 } 2729 }
2773 } 2730 }
2774 2731
2775 // No continue on sequence allowed. 2732 // No continue on sequence allowed.
2776 ASSERT((node->label() == NULL) || 2733 ASSERT((node->label() == NULL) ||
2777 (node->label()->join_for_continue() == NULL)); 2734 (node->label()->join_for_continue() == NULL));
2778 // If this node sequence is labeled, a break out of the sequence will have 2735 // If this node sequence is labeled, a break out of the sequence will have
2779 // taken care of unchaining the context. 2736 // taken care of unchaining the context.
2780 if ((node->label() != NULL) && 2737 if ((node->label() != NULL) &&
2781 (node->label()->join_for_break() != NULL)) { 2738 (node->label()->join_for_break() != NULL)) {
2782 node->label()->join_for_break()->set_loop_depth(loop_depth());
2783 if (is_open()) Goto(node->label()->join_for_break()); 2739 if (is_open()) Goto(node->label()->join_for_break());
2784 exit_ = node->label()->join_for_break(); 2740 exit_ = node->label()->join_for_break();
2785 } 2741 }
2786 2742
2787 // The outermost function sequence cannot contain a label. 2743 // The outermost function sequence cannot contain a label.
2788 ASSERT((node->label() == NULL) || 2744 ASSERT((node->label() == NULL) ||
2789 (node != owner()->parsed_function().node_sequence())); 2745 (node != owner()->parsed_function().node_sequence()));
2790 owner()->set_context_level(previous_context_level); 2746 owner()->set_context_level(previous_context_level);
2791 } 2747 }
2792 2748
2793 2749
2794 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { 2750 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) {
2795 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)"); 2751 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)");
2796 // NOTE: The implicit variables ':saved_context', ':exception_var' 2752 // NOTE: The implicit variables ':saved_context', ':exception_var'
2797 // and ':stacktrace_var' can never be captured variables. 2753 // and ':stacktrace_var' can never be captured variables.
2798 // Restores CTX from local variable ':saved_context'. 2754 // Restores CTX from local variable ':saved_context'.
2799 AddInstruction( 2755 AddInstruction(
2800 new CatchEntryInstr(node->exception_var(), node->stacktrace_var())); 2756 new CatchEntryInstr(node->exception_var(), node->stacktrace_var()));
2801 BuildLoadContext(node->context_var()); 2757 BuildLoadContext(node->context_var());
2802 2758
2803 EffectGraphVisitor for_catch(owner(), temp_index(), loop_depth()); 2759 EffectGraphVisitor for_catch(owner(), temp_index());
2804 node->VisitChildren(&for_catch); 2760 node->VisitChildren(&for_catch);
2805 Append(for_catch); 2761 Append(for_catch);
2806 } 2762 }
2807 2763
2808 2764
2809 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { 2765 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) {
2810 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); 2766 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)");
2811 intptr_t old_try_index = owner()->try_index(); 2767 intptr_t old_try_index = owner()->try_index();
2812 intptr_t try_index = owner()->AllocateTryIndex(); 2768 intptr_t try_index = owner()->AllocateTryIndex();
2813 owner()->set_try_index(try_index); 2769 owner()->set_try_index(try_index);
2814 2770
2815 // Preserve CTX into local variable '%saved_context'. 2771 // Preserve CTX into local variable '%saved_context'.
2816 BuildStoreContext(node->context_var()); 2772 BuildStoreContext(node->context_var());
2817 2773
2818 EffectGraphVisitor for_try_block(owner(), temp_index(), loop_depth()); 2774 EffectGraphVisitor for_try_block(owner(), temp_index());
2819 node->try_block()->Visit(&for_try_block); 2775 node->try_block()->Visit(&for_try_block);
2820 2776
2821 if (for_try_block.is_open()) { 2777 if (for_try_block.is_open()) {
2822 JoinEntryInstr* after_try = 2778 JoinEntryInstr* after_try =
2823 new JoinEntryInstr(owner()->AllocateBlockId(), 2779 new JoinEntryInstr(owner()->AllocateBlockId(), old_try_index);
2824 old_try_index,
2825 loop_depth());
2826 for_try_block.Goto(after_try); 2780 for_try_block.Goto(after_try);
2827 for_try_block.exit_ = after_try; 2781 for_try_block.exit_ = after_try;
2828 } 2782 }
2829 2783
2830 JoinEntryInstr* try_entry = 2784 JoinEntryInstr* try_entry =
2831 new JoinEntryInstr(owner()->AllocateBlockId(), try_index, loop_depth()); 2785 new JoinEntryInstr(owner()->AllocateBlockId(), try_index);
2832 2786
2833 Goto(try_entry); 2787 Goto(try_entry);
2834 AppendFragment(try_entry, for_try_block); 2788 AppendFragment(try_entry, for_try_block);
2835 exit_ = for_try_block.exit_; 2789 exit_ = for_try_block.exit_;
2836 2790
2837 // We are done generating code for the try block. 2791 // We are done generating code for the try block.
2838 owner()->set_try_index(old_try_index); 2792 owner()->set_try_index(old_try_index);
2839 2793
2840 CatchClauseNode* catch_block = node->catch_block(); 2794 CatchClauseNode* catch_block = node->catch_block();
2841 if (catch_block != NULL) { 2795 if (catch_block != NULL) {
2842 // Set the corresponding try index for this catch block so 2796 // Set the corresponding try index for this catch block so
2843 // that we can set the appropriate handler pc when we generate 2797 // that we can set the appropriate handler pc when we generate
2844 // code for this catch block. 2798 // code for this catch block.
2845 catch_block->set_try_index(try_index); 2799 catch_block->set_try_index(try_index);
2846 EffectGraphVisitor for_catch_block(owner(), temp_index(), loop_depth()); 2800 EffectGraphVisitor for_catch_block(owner(), temp_index());
2847 catch_block->Visit(&for_catch_block); 2801 catch_block->Visit(&for_catch_block);
2848 TargetEntryInstr* catch_entry = 2802 TargetEntryInstr* catch_entry =
2849 new TargetEntryInstr(owner()->AllocateBlockId(), 2803 new TargetEntryInstr(owner()->AllocateBlockId(), old_try_index);
2850 old_try_index,
2851 loop_depth());
2852 catch_entry->set_catch_try_index(try_index); 2804 catch_entry->set_catch_try_index(try_index);
2853 catch_entry->set_catch_handler_types(catch_block->handler_types()); 2805 catch_entry->set_catch_handler_types(catch_block->handler_types());
2854 owner()->AddCatchEntry(catch_entry); 2806 owner()->AddCatchEntry(catch_entry);
2855 ASSERT(!for_catch_block.is_open()); 2807 ASSERT(!for_catch_block.is_open());
2856 AppendFragment(catch_entry, for_catch_block); 2808 AppendFragment(catch_entry, for_catch_block);
2857 if (node->end_catch_label() != NULL) { 2809 if (node->end_catch_label() != NULL) {
2858 JoinEntryInstr* join = node->end_catch_label()->join_for_continue(); 2810 JoinEntryInstr* join = node->end_catch_label()->join_for_continue();
2859 if (join != NULL) { 2811 if (join != NULL) {
2860 join->set_loop_depth(loop_depth());
2861 if (is_open()) Goto(join); 2812 if (is_open()) Goto(join);
2862 exit_ = join; 2813 exit_ = join;
2863 } 2814 }
2864 } 2815 }
2865 } 2816 }
2866 2817
2867 // Generate code for the finally block if one exists. 2818 // Generate code for the finally block if one exists.
2868 if ((node->finally_block() != NULL) && is_open()) { 2819 if ((node->finally_block() != NULL) && is_open()) {
2869 EffectGraphVisitor for_finally_block(owner(), temp_index(), loop_depth()); 2820 EffectGraphVisitor for_finally_block(owner(), temp_index());
2870 node->finally_block()->Visit(&for_finally_block); 2821 node->finally_block()->Visit(&for_finally_block);
2871 Append(for_finally_block); 2822 Append(for_finally_block);
2872 } 2823 }
2873 } 2824 }
2874 2825
2875 2826
2876 // Looks up dynamic method noSuchMethod in target_class 2827 // Looks up dynamic method noSuchMethod in target_class
2877 // (including its super class chain) and builds a static call to it. 2828 // (including its super class chain) and builds a static call to it.
2878 StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall( 2829 StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall(
2879 const Class& target_class, 2830 const Class& target_class,
2880 AstNode* receiver, 2831 AstNode* receiver,
2881 const String& method_name, 2832 const String& method_name,
2882 ArgumentListNode* method_arguments) { 2833 ArgumentListNode* method_arguments) {
2883 // Build the graph to allocate an InvocationMirror object by calling 2834 // Build the graph to allocate an InvocationMirror object by calling
2884 // the static allocation method. 2835 // the static allocation method.
2885 const Library& corelib = Library::Handle(Library::CoreLibrary()); 2836 const Library& corelib = Library::Handle(Library::CoreLibrary());
2886 const Class& mirror_class = Class::Handle( 2837 const Class& mirror_class = Class::Handle(
2887 corelib.LookupClassAllowPrivate(Symbols::InvocationMirror())); 2838 corelib.LookupClassAllowPrivate(Symbols::InvocationMirror()));
2888 ASSERT(!mirror_class.IsNull()); 2839 ASSERT(!mirror_class.IsNull());
2889 const Function& allocation_function = Function::ZoneHandle( 2840 const Function& allocation_function = Function::ZoneHandle(
2890 Resolver::ResolveStaticByName( 2841 Resolver::ResolveStaticByName(
2891 mirror_class, 2842 mirror_class,
2892 PrivateCoreLibName(Symbols::AllocateInvocationMirror()), 2843 PrivateCoreLibName(Symbols::AllocateInvocationMirror()),
2893 Resolver::kIsQualified)); 2844 Resolver::kIsQualified));
2894 ASSERT(!allocation_function.IsNull()); 2845 ASSERT(!allocation_function.IsNull());
2895 2846
2896 // Evaluate the receiver before the arguments. This will be used 2847 // Evaluate the receiver before the arguments. This will be used
2897 // as an argument to the noSuchMethod call. 2848 // as an argument to the noSuchMethod call.
2898 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth()); 2849 ValueGraphVisitor for_receiver(owner(), temp_index());
2899 receiver->Visit(&for_receiver); 2850 receiver->Visit(&for_receiver);
2900 Append(for_receiver); 2851 Append(for_receiver);
2901 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); 2852 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
2902 2853
2903 // Allocate the arguments and pass them into the construction 2854 // Allocate the arguments and pass them into the construction
2904 // of the InvocationMirror. 2855 // of the InvocationMirror.
2905 const intptr_t args_pos = method_arguments->token_pos(); 2856 const intptr_t args_pos = method_arguments->token_pos();
2906 ArgumentListNode* arguments = new ArgumentListNode(args_pos); 2857 ArgumentListNode* arguments = new ArgumentListNode(args_pos);
2907 // The first argument is the original method name. 2858 // The first argument is the original method name.
2908 arguments->Add(new LiteralNode(args_pos, method_name)); 2859 arguments->Add(new LiteralNode(args_pos, method_name));
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
2993 func, 2944 func,
2994 Array::ZoneHandle(), // No names. 2945 Array::ZoneHandle(), // No names.
2995 arguments); 2946 arguments);
2996 } 2947 }
2997 2948
2998 2949
2999 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { 2950 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) {
3000 // TODO(kmillikin) non-local control flow is not handled correctly 2951 // TODO(kmillikin) non-local control flow is not handled correctly
3001 // by the inliner. 2952 // by the inliner.
3002 InlineBailout("EffectGraphVisitor::BuildThrowNode (exception)"); 2953 InlineBailout("EffectGraphVisitor::BuildThrowNode (exception)");
3003 ValueGraphVisitor for_exception(owner(), temp_index(), loop_depth()); 2954 ValueGraphVisitor for_exception(owner(), temp_index());
3004 node->exception()->Visit(&for_exception); 2955 node->exception()->Visit(&for_exception);
3005 Append(for_exception); 2956 Append(for_exception);
3006 PushArgument(for_exception.value()); 2957 PushArgument(for_exception.value());
3007 Instruction* instr = NULL; 2958 Instruction* instr = NULL;
3008 if (node->stacktrace() == NULL) { 2959 if (node->stacktrace() == NULL) {
3009 instr = new ThrowInstr(node->token_pos()); 2960 instr = new ThrowInstr(node->token_pos());
3010 } else { 2961 } else {
3011 ValueGraphVisitor for_stack_trace(owner(), temp_index(), loop_depth()); 2962 ValueGraphVisitor for_stack_trace(owner(), temp_index());
3012 node->stacktrace()->Visit(&for_stack_trace); 2963 node->stacktrace()->Visit(&for_stack_trace);
3013 Append(for_stack_trace); 2964 Append(for_stack_trace);
3014 PushArgument(for_stack_trace.value()); 2965 PushArgument(for_stack_trace.value());
3015 instr = new ReThrowInstr(node->token_pos()); 2966 instr = new ReThrowInstr(node->token_pos());
3016 } 2967 }
3017 AddInstruction(instr); 2968 AddInstruction(instr);
3018 } 2969 }
3019 2970
3020 2971
3021 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { 2972 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) {
(...skipping 16 matching lines...) Expand all
3038 const intptr_t try_index = owner()->try_index(); 2989 const intptr_t try_index = owner()->try_index();
3039 if (try_index >= 0) { 2990 if (try_index >= 0) {
3040 // We are about to generate code for an inlined finally block. Exceptions 2991 // We are about to generate code for an inlined finally block. Exceptions
3041 // thrown in this block of code should be treated as though they are 2992 // thrown in this block of code should be treated as though they are
3042 // thrown not from the current try block but the outer try block if any. 2993 // thrown not from the current try block but the outer try block if any.
3043 owner()->set_try_index((try_index - 1)); 2994 owner()->set_try_index((try_index - 1));
3044 } 2995 }
3045 BuildLoadContext(node->context_var()); 2996 BuildLoadContext(node->context_var());
3046 2997
3047 JoinEntryInstr* finally_entry = 2998 JoinEntryInstr* finally_entry =
3048 new JoinEntryInstr(owner()->AllocateBlockId(), 2999 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
3049 owner()->try_index(), 3000 EffectGraphVisitor for_finally_block(owner(), temp_index());
3050 loop_depth());
3051 EffectGraphVisitor for_finally_block(owner(), temp_index(), loop_depth());
3052 node->finally_block()->Visit(&for_finally_block); 3001 node->finally_block()->Visit(&for_finally_block);
3053 3002
3054 if (try_index >= 0) { 3003 if (try_index >= 0) {
3055 owner()->set_try_index(try_index); 3004 owner()->set_try_index(try_index);
3056 } 3005 }
3057 3006
3058 if (for_finally_block.is_open()) { 3007 if (for_finally_block.is_open()) {
3059 JoinEntryInstr* after_finally = 3008 JoinEntryInstr* after_finally =
3060 new JoinEntryInstr(owner()->AllocateBlockId(), 3009 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
3061 owner()->try_index(),
3062 loop_depth());
3063 for_finally_block.Goto(after_finally); 3010 for_finally_block.Goto(after_finally);
3064 for_finally_block.exit_ = after_finally; 3011 for_finally_block.exit_ = after_finally;
3065 } 3012 }
3066 3013
3067 Goto(finally_entry); 3014 Goto(finally_entry);
3068 AppendFragment(finally_entry, for_finally_block); 3015 AppendFragment(finally_entry, for_finally_block);
3069 exit_ = for_finally_block.exit_; 3016 exit_ = for_finally_block.exit_;
3070 } 3017 }
3071 3018
3072 3019
3073 FlowGraph* FlowGraphBuilder::BuildGraph(intptr_t initial_loop_depth) { 3020 FlowGraph* FlowGraphBuilder::BuildGraph() {
3074 if (FLAG_print_ast) { 3021 if (FLAG_print_ast) {
3075 // Print the function ast before IL generation. 3022 // Print the function ast before IL generation.
3076 AstPrinter::PrintFunctionNodes(parsed_function()); 3023 AstPrinter::PrintFunctionNodes(parsed_function());
3077 } 3024 }
3078 // Compilation can be nested, preserve the computation-id. 3025 // Compilation can be nested, preserve the computation-id.
3079 const Function& function = parsed_function().function(); 3026 const Function& function = parsed_function().function();
3080 TargetEntryInstr* normal_entry = 3027 TargetEntryInstr* normal_entry =
3081 new TargetEntryInstr(AllocateBlockId(), 3028 new TargetEntryInstr(AllocateBlockId(),
3082 CatchClauseNode::kInvalidTryIndex, 3029 CatchClauseNode::kInvalidTryIndex);
3083 initial_loop_depth);
3084 graph_entry_ = new GraphEntryInstr(normal_entry); 3030 graph_entry_ = new GraphEntryInstr(normal_entry);
3085 EffectGraphVisitor for_effect(this, 0, initial_loop_depth); 3031 EffectGraphVisitor for_effect(this, 0);
3086 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the 3032 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the
3087 // stack check on entry for leaf routines). 3033 // stack check on entry for leaf routines).
3088 Instruction* check = new CheckStackOverflowInstr(function.token_pos()); 3034 Instruction* check = new CheckStackOverflowInstr(function.token_pos());
3089 // If we are inlining don't actually attach the stack check. We must still 3035 // If we are inlining don't actually attach the stack check. We must still
3090 // create the stack check inorder to allocate a deopt id. 3036 // create the stack check inorder to allocate a deopt id.
3091 if (!InInliningContext()) for_effect.AddInstruction(check); 3037 if (!InInliningContext()) for_effect.AddInstruction(check);
3092 parsed_function().node_sequence()->Visit(&for_effect); 3038 parsed_function().node_sequence()->Visit(&for_effect);
3093 AppendFragment(normal_entry, for_effect); 3039 AppendFragment(normal_entry, for_effect);
3094 // Check that the graph is properly terminated. 3040 // Check that the graph is properly terminated.
3095 ASSERT(!for_effect.is_open()); 3041 ASSERT(!for_effect.is_open());
3096 FlowGraph* graph = new FlowGraph(*this, graph_entry_, last_used_block_id_); 3042 FlowGraph* graph = new FlowGraph(*this, graph_entry_, last_used_block_id_);
3097 return graph; 3043 return graph;
3098 } 3044 }
3099 3045
3100 3046
3101 void FlowGraphBuilder::Bailout(const char* reason) { 3047 void FlowGraphBuilder::Bailout(const char* reason) {
3102 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; 3048 const char* kFormat = "FlowGraphBuilder Bailout: %s %s";
3103 const char* function_name = parsed_function_.function().ToCString(); 3049 const char* function_name = parsed_function_.function().ToCString();
3104 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 3050 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
3105 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 3051 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
3106 OS::SNPrint(chars, len, kFormat, function_name, reason); 3052 OS::SNPrint(chars, len, kFormat, function_name, reason);
3107 const Error& error = Error::Handle( 3053 const Error& error = Error::Handle(
3108 LanguageError::New(String::Handle(String::New(chars)))); 3054 LanguageError::New(String::Handle(String::New(chars))));
3109 Isolate::Current()->long_jump_base()->Jump(1, error); 3055 Isolate::Current()->long_jump_base()->Jump(1, error);
3110 } 3056 }
3111 3057
3112 3058
3113 } // namespace dart 3059 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698