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

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

Powered by Google App Engine
This is Rietveld 408576698