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

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

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

Powered by Google App Engine
This is Rietveld 408576698