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

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: Style and phrasing. 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
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());
Kevin Millikin (Google) 2012/10/26 12:07:22 This join is the entry to the test. It should be
zerny-google 2012/10/29 16:44:25 Done.
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());
srdjan 2012/10/25 20:38:50 It looks weird that an instruction changes its loo
Kevin Millikin (Google) 2012/10/26 12:07:22 The loop depth was invalid before. We do not know
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 BlockEntryInstr::kInvalidLoopDepth);
srdjan 2012/10/25 20:38:50 Why not set it to loop_depth() + 1 ?
zerny-google 2012/10/29 16:44:25 I set it to invalid so it is correctly set just on
1244 } 1273 }
1274 join->set_loop_depth(loop_depth() + 1);
1245 join->LinkTo(for_test.entry()); 1275 join->LinkTo(for_test.entry());
1246 if (body_exit != NULL) { 1276 if (body_exit != NULL) {
1247 body_exit->Goto(join); 1277 body_exit->Goto(join);
1248 } 1278 }
1249 } 1279 }
1250 1280
1251
1252 for_test.IfTrueGoto(body_entry_join); 1281 for_test.IfTrueGoto(body_entry_join);
1253 if (node->label()->join_for_break() == NULL) { 1282 join = node->label()->join_for_break();
1283 if (join == NULL) {
1254 exit_ = for_test.CreateFalseSuccessor(); 1284 exit_ = for_test.CreateFalseSuccessor();
1255 } else { 1285 } else {
1256 for_test.IfFalseGoto(node->label()->join_for_break()); 1286 join->set_loop_depth(loop_depth());
1257 exit_ = node->label()->join_for_break(); 1287 for_test.IfFalseGoto(join);
1288 exit_ = join;
1258 } 1289 }
1259 } 1290 }
1260 1291
1261 1292
1262 // A ForNode can contain break and continue jumps. 'break' joins to 1293 // A ForNode can contain break and continue jumps. 'break' joins to
1263 // ForNode exit, 'continue' joins at increment entry. The fragment is composed 1294 // ForNode exit, 'continue' joins at increment entry. The fragment is composed
1264 // as follows: 1295 // as follows:
1265 // a) [ initializer ] 1296 // a) [ initializer ]
1266 // b) loop-join 1297 // b) loop-join
1267 // c) [ test ] -> (body-entry-target, loop-exit-target) 1298 // c) [ test ] -> (body-entry-target, loop-exit-target)
1268 // d) body-entry-target 1299 // d) body-entry-target
1269 // e) [ body ] 1300 // e) [ body ]
1270 // f) continue-join (optional) 1301 // f) continue-join (optional)
1271 // g) [ increment ] -> (loop-join) 1302 // g) [ increment ] -> (loop-join)
1272 // h) loop-exit-target 1303 // h) loop-exit-target
1273 // i) break-join 1304 // i) break-join
1274 void EffectGraphVisitor::VisitForNode(ForNode* node) { 1305 void EffectGraphVisitor::VisitForNode(ForNode* node) {
1275 EffectGraphVisitor for_initializer(owner(), temp_index()); 1306 EffectGraphVisitor for_initializer(owner(), temp_index(), loop_depth());
1276 node->initializer()->Visit(&for_initializer); 1307 node->initializer()->Visit(&for_initializer);
1277 Append(for_initializer); 1308 Append(for_initializer);
1278 ASSERT(is_open()); 1309 ASSERT(is_open());
1279 1310
1280 // Compose body to set any jump labels. 1311 // Compose body to set any jump labels.
1281 EffectGraphVisitor for_body(owner(), temp_index()); 1312 EffectGraphVisitor for_body(owner(), temp_index(), loop_depth() + 1);
1282 for_body.AddInstruction( 1313 for_body.AddInstruction(
1283 new CheckStackOverflowInstr(node->token_pos())); 1314 new CheckStackOverflowInstr(node->token_pos()));
1284 node->body()->Visit(&for_body); 1315 node->body()->Visit(&for_body);
1285 1316
1286 // Join loop body, increment and compute their end instruction. 1317 // Join loop body, increment and compute their end instruction.
1287 ASSERT(!for_body.is_empty()); 1318 ASSERT(!for_body.is_empty());
1288 Instruction* loop_increment_end = NULL; 1319 Instruction* loop_increment_end = NULL;
1289 EffectGraphVisitor for_increment(owner(), temp_index()); 1320 EffectGraphVisitor for_increment(owner(), temp_index(), loop_depth() + 1);
1290 node->increment()->Visit(&for_increment); 1321 node->increment()->Visit(&for_increment);
1291 JoinEntryInstr* join = node->label()->join_for_continue(); 1322 JoinEntryInstr* join = node->label()->join_for_continue();
1292 if (join != NULL) { 1323 if (join != NULL) {
1324 join->set_loop_depth(loop_depth() + 1);
1293 // Insert the join between the body and increment. 1325 // Insert the join between the body and increment.
1294 if (for_body.is_open()) for_body.Goto(join); 1326 if (for_body.is_open()) for_body.Goto(join);
1295 loop_increment_end = AppendFragment(join, for_increment); 1327 loop_increment_end = AppendFragment(join, for_increment);
1296 ASSERT(loop_increment_end != NULL); 1328 ASSERT(loop_increment_end != NULL);
1297 } else if (for_body.is_open()) { 1329 } else if (for_body.is_open()) {
1298 // Do not insert an extra basic block. 1330 // Do not insert an extra basic block.
1299 for_body.Append(for_increment); 1331 for_body.Append(for_increment);
1300 loop_increment_end = for_body.exit(); 1332 loop_increment_end = for_body.exit();
1301 // 'for_body' contains at least the stack check. 1333 // 'for_body' contains at least the stack check.
1302 ASSERT(loop_increment_end != NULL); 1334 ASSERT(loop_increment_end != NULL);
1303 } else { 1335 } else {
1304 loop_increment_end = NULL; 1336 loop_increment_end = NULL;
1305 } 1337 }
1306 1338
1307 // 'loop_increment_end' is NULL only if there is no join for continue and the 1339 // '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. 1340 // body is not open, i.e., no backward branch exists.
1309 if (loop_increment_end != NULL) { 1341 if (loop_increment_end != NULL) {
1310 JoinEntryInstr* loop_start = 1342 JoinEntryInstr* loop_start =
1311 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 1343 new JoinEntryInstr(owner()->AllocateBlockId(),
1344 owner()->try_index(),
1345 loop_depth() + 1);
1312 Goto(loop_start); 1346 Goto(loop_start);
1313 loop_increment_end->Goto(loop_start); 1347 loop_increment_end->Goto(loop_start);
1314 exit_ = loop_start; 1348 exit_ = loop_start;
1315 } 1349 }
1316 1350
1317 if (node->condition() == NULL) { 1351 if (node->condition() == NULL) {
1318 // Endless loop, no test. 1352 // Endless loop, no test.
1319 JoinEntryInstr* body_entry = 1353 JoinEntryInstr* body_entry =
1320 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 1354 new JoinEntryInstr(owner()->AllocateBlockId(),
1355 owner()->try_index(),
1356 loop_depth() + 1);
1321 AppendFragment(body_entry, for_body); 1357 AppendFragment(body_entry, for_body);
1322 Goto(body_entry); 1358 Goto(body_entry);
1323 if (node->label()->join_for_break() != NULL) { 1359 if (node->label()->join_for_break() != NULL) {
1360 node->label()->join_for_break()->set_loop_depth(loop_depth());
1324 // Control flow of ForLoop continues into join_for_break. 1361 // Control flow of ForLoop continues into join_for_break.
1325 exit_ = node->label()->join_for_break(); 1362 exit_ = node->label()->join_for_break();
1326 } 1363 }
1327 } else { 1364 } else {
1328 TestGraphVisitor for_test(owner(), 1365 TestGraphVisitor for_test(owner(),
1329 temp_index(), 1366 temp_index(),
1367 loop_depth() + 1,
1330 node->condition()->token_pos()); 1368 node->condition()->token_pos());
1331 node->condition()->Visit(&for_test); 1369 node->condition()->Visit(&for_test);
1332 Append(for_test); 1370 Append(for_test);
1333 1371
1334 BlockEntryInstr* body_entry = for_test.CreateTrueSuccessor(); 1372 BlockEntryInstr* body_entry = for_test.CreateTrueSuccessor();
1335 AppendFragment(body_entry, for_body); 1373 AppendFragment(body_entry, for_body);
1336 1374
1337 if (node->label()->join_for_break() == NULL) { 1375 if (node->label()->join_for_break() == NULL) {
1338 exit_ = for_test.CreateFalseSuccessor(); 1376 exit_ = for_test.CreateFalseSuccessor();
1339 } else { 1377 } else {
1378 node->label()->join_for_break()->set_loop_depth(loop_depth());
1340 for_test.IfFalseGoto(node->label()->join_for_break()); 1379 for_test.IfFalseGoto(node->label()->join_for_break());
1341 exit_ = node->label()->join_for_break(); 1380 exit_ = node->label()->join_for_break();
1342 } 1381 }
1343 } 1382 }
1344 } 1383 }
1345 1384
1346 1385
1347 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { 1386 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) {
1348 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { 1387 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) {
1349 EffectGraphVisitor for_effect(owner(), temp_index()); 1388 EffectGraphVisitor for_effect(owner(), temp_index(), loop_depth());
1350 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); 1389 node->InlinedFinallyNodeAt(i)->Visit(&for_effect);
1351 Append(for_effect); 1390 Append(for_effect);
1352 if (!is_open()) return; 1391 if (!is_open()) return;
1353 } 1392 }
1354 1393
1355 // Unchain the context(s) up to the outer context level of the scope which 1394 // Unchain the context(s) up to the outer context level of the scope which
1356 // contains the destination label. 1395 // contains the destination label.
1357 SourceLabel* label = node->label(); 1396 SourceLabel* label = node->label();
1358 ASSERT(label->owner() != NULL); 1397 ASSERT(label->owner() != NULL);
1359 int target_context_level = 0; 1398 int target_context_level = 0;
(...skipping 17 matching lines...) Expand all
1377 intptr_t current_context_level = owner()->context_level(); 1416 intptr_t current_context_level = owner()->context_level();
1378 ASSERT(current_context_level >= target_context_level); 1417 ASSERT(current_context_level >= target_context_level);
1379 while (current_context_level-- > target_context_level) { 1418 while (current_context_level-- > target_context_level) {
1380 UnchainContext(); 1419 UnchainContext();
1381 } 1420 }
1382 1421
1383 JoinEntryInstr* jump_target = NULL; 1422 JoinEntryInstr* jump_target = NULL;
1384 if (node->kind() == Token::kBREAK) { 1423 if (node->kind() == Token::kBREAK) {
1385 if (node->label()->join_for_break() == NULL) { 1424 if (node->label()->join_for_break() == NULL) {
1386 node->label()->set_join_for_break( 1425 node->label()->set_join_for_break(
1387 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index())); 1426 new JoinEntryInstr(owner()->AllocateBlockId(),
1427 owner()->try_index(),
1428 BlockEntryInstr::kInvalidLoopDepth));
1388 } 1429 }
1389 jump_target = node->label()->join_for_break(); 1430 jump_target = node->label()->join_for_break();
1390 } else { 1431 } else {
1391 if (node->label()->join_for_continue() == NULL) { 1432 if (node->label()->join_for_continue() == NULL) {
1392 node->label()->set_join_for_continue( 1433 node->label()->set_join_for_continue(
1393 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index())); 1434 new JoinEntryInstr(owner()->AllocateBlockId(),
1435 owner()->try_index(),
1436 BlockEntryInstr::kInvalidLoopDepth));
1394 } 1437 }
1395 jump_target = node->label()->join_for_continue(); 1438 jump_target = node->label()->join_for_continue();
1396 } 1439 }
1397 Goto(jump_target); 1440 Goto(jump_target);
1398 } 1441 }
1399 1442
1400 1443
1401 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { 1444 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) {
1402 UNREACHABLE(); 1445 UNREACHABLE();
1403 } 1446 }
1404 1447
1405 1448
1406 void EffectGraphVisitor::VisitArgumentDefinitionTestNode( 1449 void EffectGraphVisitor::VisitArgumentDefinitionTestNode(
1407 ArgumentDefinitionTestNode* node) { 1450 ArgumentDefinitionTestNode* node) {
1408 InlineBailout("EffectGraphVisitor::VisitArgumentDefinitionTestNode"); 1451 InlineBailout("EffectGraphVisitor::VisitArgumentDefinitionTestNode");
1409 Definition* load = BuildLoadLocal(node->saved_arguments_descriptor()); 1452 Definition* load = BuildLoadLocal(node->saved_arguments_descriptor());
1410 Value* arguments_descriptor = Bind(load); 1453 Value* arguments_descriptor = Bind(load);
1411 ArgumentDefinitionTestInstr* arg_def_test = 1454 ArgumentDefinitionTestInstr* arg_def_test =
1412 new ArgumentDefinitionTestInstr(node, arguments_descriptor); 1455 new ArgumentDefinitionTestInstr(node, arguments_descriptor);
1413 ReturnDefinition(arg_def_test); 1456 ReturnDefinition(arg_def_test);
1414 } 1457 }
1415 1458
1416 1459
1417 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { 1460 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) {
1418 // Translate the array elements and collect their values. 1461 // Translate the array elements and collect their values.
1419 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1462 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1420 new ZoneGrowableArray<PushArgumentInstr*>(node->length()); 1463 new ZoneGrowableArray<PushArgumentInstr*>(node->length());
1421 for (int i = 0; i < node->length(); ++i) { 1464 for (int i = 0; i < node->length(); ++i) {
1422 ValueGraphVisitor for_value(owner(), temp_index()); 1465 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth());
1423 node->ElementAt(i)->Visit(&for_value); 1466 node->ElementAt(i)->Visit(&for_value);
1424 Append(for_value); 1467 Append(for_value);
1425 arguments->Add(PushArgument(for_value.value())); 1468 arguments->Add(PushArgument(for_value.value()));
1426 } 1469 }
1427 const AbstractTypeArguments& type_args = 1470 const AbstractTypeArguments& type_args =
1428 AbstractTypeArguments::ZoneHandle(node->type().arguments()); 1471 AbstractTypeArguments::ZoneHandle(node->type().arguments());
1429 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), 1472 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(),
1430 type_args); 1473 type_args);
1431 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), 1474 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(),
1432 arguments, 1475 arguments,
(...skipping 13 matching lines...) Expand all
1446 if (function.context_scope() == ContextScope::null()) { 1489 if (function.context_scope() == ContextScope::null()) {
1447 // TODO(regis): Why are we not doing this in the parser? 1490 // TODO(regis): Why are we not doing this in the parser?
1448 const ContextScope& context_scope = ContextScope::ZoneHandle( 1491 const ContextScope& context_scope = ContextScope::ZoneHandle(
1449 node->scope()->PreserveOuterScope(owner()->context_level())); 1492 node->scope()->PreserveOuterScope(owner()->context_level()));
1450 ASSERT(!function.HasCode()); 1493 ASSERT(!function.HasCode());
1451 ASSERT(function.context_scope() == ContextScope::null()); 1494 ASSERT(function.context_scope() == ContextScope::null());
1452 function.set_context_scope(context_scope); 1495 function.set_context_scope(context_scope);
1453 } 1496 }
1454 receiver = BuildNullValue(); 1497 receiver = BuildNullValue();
1455 } else if (function.IsImplicitInstanceClosureFunction()) { 1498 } else if (function.IsImplicitInstanceClosureFunction()) {
1456 ValueGraphVisitor for_receiver(owner(), temp_index()); 1499 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth());
1457 node->receiver()->Visit(&for_receiver); 1500 node->receiver()->Visit(&for_receiver);
1458 Append(for_receiver); 1501 Append(for_receiver);
1459 receiver = for_receiver.value(); 1502 receiver = for_receiver.value();
1460 } else { 1503 } else {
1461 receiver = BuildNullValue(); 1504 receiver = BuildNullValue();
1462 } 1505 }
1463 PushArgumentInstr* push_receiver = PushArgument(receiver); 1506 PushArgumentInstr* push_receiver = PushArgument(receiver);
1464 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1507 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1465 new ZoneGrowableArray<PushArgumentInstr*>(2); 1508 new ZoneGrowableArray<PushArgumentInstr*>(2);
1466 arguments->Add(push_receiver); 1509 arguments->Add(push_receiver);
(...skipping 14 matching lines...) Expand all
1481 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments); 1524 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments);
1482 arguments->Add(push_type_arguments); 1525 arguments->Add(push_type_arguments);
1483 ReturnDefinition(new CreateClosureInstr(node, arguments)); 1526 ReturnDefinition(new CreateClosureInstr(node, arguments));
1484 } 1527 }
1485 1528
1486 1529
1487 void EffectGraphVisitor::TranslateArgumentList( 1530 void EffectGraphVisitor::TranslateArgumentList(
1488 const ArgumentListNode& node, 1531 const ArgumentListNode& node,
1489 ZoneGrowableArray<Value*>* values) { 1532 ZoneGrowableArray<Value*>* values) {
1490 for (intptr_t i = 0; i < node.length(); ++i) { 1533 for (intptr_t i = 0; i < node.length(); ++i) {
1491 ValueGraphVisitor for_argument(owner(), temp_index()); 1534 ValueGraphVisitor for_argument(owner(), temp_index(), loop_depth());
1492 node.NodeAt(i)->Visit(&for_argument); 1535 node.NodeAt(i)->Visit(&for_argument);
1493 Append(for_argument); 1536 Append(for_argument);
1494 values->Add(for_argument.value()); 1537 values->Add(for_argument.value());
1495 } 1538 }
1496 } 1539 }
1497 1540
1498 1541
1499 void EffectGraphVisitor::BuildPushArguments( 1542 void EffectGraphVisitor::BuildPushArguments(
1500 const ArgumentListNode& node, 1543 const ArgumentListNode& node,
1501 ZoneGrowableArray<PushArgumentInstr*>* values) { 1544 ZoneGrowableArray<PushArgumentInstr*>* values) {
1502 for (intptr_t i = 0; i < node.length(); ++i) { 1545 for (intptr_t i = 0; i < node.length(); ++i) {
1503 ValueGraphVisitor for_argument(owner(), temp_index()); 1546 ValueGraphVisitor for_argument(owner(), temp_index(), loop_depth());
1504 node.NodeAt(i)->Visit(&for_argument); 1547 node.NodeAt(i)->Visit(&for_argument);
1505 Append(for_argument); 1548 Append(for_argument);
1506 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); 1549 PushArgumentInstr* push_arg = PushArgument(for_argument.value());
1507 values->Add(push_arg); 1550 values->Add(push_arg);
1508 } 1551 }
1509 } 1552 }
1510 1553
1511 1554
1512 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { 1555 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
1513 ValueGraphVisitor for_receiver(owner(), temp_index()); 1556 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth());
1514 node->receiver()->Visit(&for_receiver); 1557 node->receiver()->Visit(&for_receiver);
1515 Append(for_receiver); 1558 Append(for_receiver);
1516 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); 1559 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
1517 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1560 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1518 new ZoneGrowableArray<PushArgumentInstr*>( 1561 new ZoneGrowableArray<PushArgumentInstr*>(
1519 node->arguments()->length() + 1); 1562 node->arguments()->length() + 1);
1520 arguments->Add(push_receiver); 1563 arguments->Add(push_receiver);
1521 1564
1522 BuildPushArguments(*node->arguments(), arguments); 1565 BuildPushArguments(*node->arguments(), arguments);
1523 InstanceCallInstr* call = new InstanceCallInstr( 1566 InstanceCallInstr* call = new InstanceCallInstr(
1524 node->token_pos(), 1567 node->token_pos(),
1525 node->function_name(), Token::kILLEGAL, arguments, 1568 node->function_name(), Token::kILLEGAL, arguments,
1526 node->arguments()->names(), 1); 1569 node->arguments()->names(), 1);
1527 ReturnDefinition(call); 1570 ReturnDefinition(call);
1528 } 1571 }
1529 1572
1530 1573
1531 // <Expression> ::= StaticCall { function: Function 1574 // <Expression> ::= StaticCall { function: Function
1532 // arguments: <ArgumentList> } 1575 // arguments: <ArgumentList> }
1533 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { 1576 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
1534 if (node->function().name() == Symbols::Identical()) { 1577 if (node->function().name() == Symbols::Identical()) {
1535 // Attempt to replace identical with strcit equal early on. 1578 // Attempt to replace identical with strcit equal early on.
1536 // TODO(hausner): Evaluate if this can happen at AST building time. 1579 // TODO(hausner): Evaluate if this can happen at AST building time.
1537 const Class& cls = Class::Handle(node->function().Owner()); 1580 const Class& cls = Class::Handle(node->function().Owner());
1538 if (cls.IsTopLevel()) { 1581 if (cls.IsTopLevel()) {
1539 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 1582 const Library& core_lib = Library::Handle(Library::CoreLibrary());
1540 if (cls.library() == core_lib.raw()) { 1583 if (cls.library() == core_lib.raw()) {
1541 ASSERT(node->arguments()->length() == 2); 1584 ASSERT(node->arguments()->length() == 2);
1542 ValueGraphVisitor for_left_value(owner(), temp_index()); 1585 ValueGraphVisitor for_left_value(owner(), temp_index(), loop_depth());
1543 node->arguments()->NodeAt(0)->Visit(&for_left_value); 1586 node->arguments()->NodeAt(0)->Visit(&for_left_value);
1544 Append(for_left_value); 1587 Append(for_left_value);
1545 ValueGraphVisitor for_right_value(owner(), temp_index()); 1588 ValueGraphVisitor for_right_value(owner(), temp_index(), loop_depth());
1546 node->arguments()->NodeAt(1)->Visit(&for_right_value); 1589 node->arguments()->NodeAt(1)->Visit(&for_right_value);
1547 Append(for_right_value); 1590 Append(for_right_value);
1548 StrictCompareInstr* comp = new StrictCompareInstr( 1591 StrictCompareInstr* comp = new StrictCompareInstr(
1549 Token::kEQ_STRICT, 1592 Token::kEQ_STRICT,
1550 for_left_value.value(), 1593 for_left_value.value(),
1551 for_right_value.value()); 1594 for_right_value.value());
1552 ReturnDefinition(comp); 1595 ReturnDefinition(comp);
1553 return; 1596 return;
1554 } 1597 }
1555 } 1598 }
1556 } 1599 }
1557 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1600 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1558 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); 1601 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length());
1559 BuildPushArguments(*node->arguments(), arguments); 1602 BuildPushArguments(*node->arguments(), arguments);
1560 StaticCallInstr* call = 1603 StaticCallInstr* call =
1561 new StaticCallInstr(node->token_pos(), 1604 new StaticCallInstr(node->token_pos(),
1562 node->function(), 1605 node->function(),
1563 node->arguments()->names(), 1606 node->arguments()->names(),
1564 arguments); 1607 arguments);
1565 ReturnDefinition(call); 1608 ReturnDefinition(call);
1566 } 1609 }
1567 1610
1568 1611
1569 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall( 1612 ClosureCallInstr* EffectGraphVisitor::BuildClosureCall(
1570 ClosureCallNode* node) { 1613 ClosureCallNode* node) {
1571 ValueGraphVisitor for_closure(owner(), temp_index()); 1614 ValueGraphVisitor for_closure(owner(), temp_index(), loop_depth());
1572 node->closure()->Visit(&for_closure); 1615 node->closure()->Visit(&for_closure);
1573 Append(for_closure); 1616 Append(for_closure);
1574 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); 1617 PushArgumentInstr* push_closure = PushArgument(for_closure.value());
1575 1618
1576 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1619 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1577 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); 1620 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length());
1578 arguments->Add(push_closure); 1621 arguments->Add(push_closure);
1579 BuildPushArguments(*node->arguments(), arguments); 1622 BuildPushArguments(*node->arguments(), arguments);
1580 1623
1581 // Save context around the call. 1624 // Save context around the call.
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
1732 Function& outer_function = 1775 Function& outer_function =
1733 Function::Handle(owner()->parsed_function().function().raw()); 1776 Function::Handle(owner()->parsed_function().function().raw());
1734 while (outer_function.IsLocalFunction()) { 1777 while (outer_function.IsLocalFunction()) {
1735 outer_function = outer_function.parent_function(); 1778 outer_function = outer_function.parent_function();
1736 } 1779 }
1737 if (outer_function.IsFactory()) { 1780 if (outer_function.IsFactory()) {
1738 return NULL; 1781 return NULL;
1739 } 1782 }
1740 1783
1741 ASSERT(owner()->parsed_function().instantiator() != NULL); 1784 ASSERT(owner()->parsed_function().instantiator() != NULL);
1742 ValueGraphVisitor for_instantiator(owner(), temp_index()); 1785 ValueGraphVisitor for_instantiator(owner(), temp_index(), loop_depth());
1743 owner()->parsed_function().instantiator()->Visit(&for_instantiator); 1786 owner()->parsed_function().instantiator()->Visit(&for_instantiator);
1744 Append(for_instantiator); 1787 Append(for_instantiator);
1745 return for_instantiator.value(); 1788 return for_instantiator.value();
1746 } 1789 }
1747 1790
1748 1791
1749 // 'expression_temp_var' may not be used inside this method if 'instantiator' 1792 // 'expression_temp_var' may not be used inside this method if 'instantiator'
1750 // is not NULL. 1793 // is not NULL.
1751 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( 1794 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments(
1752 intptr_t token_pos, Value* instantiator) { 1795 intptr_t token_pos, Value* instantiator) {
(...skipping 14 matching lines...) Expand all
1767 } 1810 }
1768 Function& outer_function = 1811 Function& outer_function =
1769 Function::Handle(owner()->parsed_function().function().raw()); 1812 Function::Handle(owner()->parsed_function().function().raw());
1770 while (outer_function.IsLocalFunction()) { 1813 while (outer_function.IsLocalFunction()) {
1771 outer_function = outer_function.parent_function(); 1814 outer_function = outer_function.parent_function();
1772 } 1815 }
1773 if (outer_function.IsFactory()) { 1816 if (outer_function.IsFactory()) {
1774 // No instantiator for factories. 1817 // No instantiator for factories.
1775 ASSERT(instantiator == NULL); 1818 ASSERT(instantiator == NULL);
1776 ASSERT(owner()->parsed_function().instantiator() != NULL); 1819 ASSERT(owner()->parsed_function().instantiator() != NULL);
1777 ValueGraphVisitor for_instantiator(owner(), temp_index()); 1820 ValueGraphVisitor for_instantiator(owner(), temp_index(), loop_depth());
1778 owner()->parsed_function().instantiator()->Visit(&for_instantiator); 1821 owner()->parsed_function().instantiator()->Visit(&for_instantiator);
1779 Append(for_instantiator); 1822 Append(for_instantiator);
1780 return for_instantiator.value(); 1823 return for_instantiator.value();
1781 } 1824 }
1782 if (instantiator == NULL) { 1825 if (instantiator == NULL) {
1783 instantiator = BuildInstantiator(); 1826 instantiator = BuildInstantiator();
1784 } 1827 }
1785 // The instantiator is the receiver of the caller, which is not a factory. 1828 // The instantiator is the receiver of the caller, which is not a factory.
1786 // The receiver cannot be null; extract its AbstractTypeArguments object. 1829 // The receiver cannot be null; extract its AbstractTypeArguments object.
1787 // Note that in the factory case, the instantiator is the first parameter 1830 // Note that in the factory case, the instantiator is the first parameter
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1915 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); 1958 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value);
1916 BuildConstructorCall(node, push_allocated_value); 1959 BuildConstructorCall(node, push_allocated_value);
1917 Definition* load_allocated = BuildLoadLocal( 1960 Definition* load_allocated = BuildLoadLocal(
1918 node->allocated_object_var()); 1961 node->allocated_object_var());
1919 allocated_value = Bind(load_allocated); 1962 allocated_value = Bind(load_allocated);
1920 ReturnValue(allocated_value); 1963 ReturnValue(allocated_value);
1921 } 1964 }
1922 1965
1923 1966
1924 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { 1967 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
1925 ValueGraphVisitor for_receiver(owner(), temp_index()); 1968 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth());
1926 node->receiver()->Visit(&for_receiver); 1969 node->receiver()->Visit(&for_receiver);
1927 Append(for_receiver); 1970 Append(for_receiver);
1928 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); 1971 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
1929 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1972 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1930 new ZoneGrowableArray<PushArgumentInstr*>(1); 1973 new ZoneGrowableArray<PushArgumentInstr*>(1);
1931 arguments->Add(push_receiver); 1974 arguments->Add(push_receiver);
1932 const String& name = 1975 const String& name =
1933 String::ZoneHandle(Field::GetterSymbol(node->field_name())); 1976 String::ZoneHandle(Field::GetterSymbol(node->field_name()));
1934 InstanceCallInstr* call = new InstanceCallInstr( 1977 InstanceCallInstr* call = new InstanceCallInstr(
1935 node->token_pos(), name, Token::kGET, 1978 node->token_pos(), name, Token::kGET,
1936 arguments, Array::ZoneHandle(), 1); 1979 arguments, Array::ZoneHandle(), 1);
1937 ReturnDefinition(call); 1980 ReturnDefinition(call);
1938 } 1981 }
1939 1982
1940 1983
1941 void EffectGraphVisitor::BuildInstanceSetterArguments( 1984 void EffectGraphVisitor::BuildInstanceSetterArguments(
1942 InstanceSetterNode* node, 1985 InstanceSetterNode* node,
1943 ZoneGrowableArray<PushArgumentInstr*>* arguments, 1986 ZoneGrowableArray<PushArgumentInstr*>* arguments,
1944 bool result_is_needed) { 1987 bool result_is_needed) {
1945 ValueGraphVisitor for_receiver(owner(), temp_index()); 1988 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth());
1946 node->receiver()->Visit(&for_receiver); 1989 node->receiver()->Visit(&for_receiver);
1947 Append(for_receiver); 1990 Append(for_receiver);
1948 arguments->Add(PushArgument(for_receiver.value())); 1991 arguments->Add(PushArgument(for_receiver.value()));
1949 1992
1950 ValueGraphVisitor for_value(owner(), temp_index()); 1993 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth());
1951 node->value()->Visit(&for_value); 1994 node->value()->Visit(&for_value);
1952 Append(for_value); 1995 Append(for_value);
1953 1996
1954 Value* value = NULL; 1997 Value* value = NULL;
1955 if (result_is_needed) { 1998 if (result_is_needed) {
1956 value = Bind(BuildStoreExprTemp(for_value.value())); 1999 value = Bind(BuildStoreExprTemp(for_value.value()));
1957 } else { 2000 } else {
1958 value = for_value.value(); 2001 value = for_value.value();
1959 } 2002 }
1960 arguments->Add(PushArgument(value)); 2003 arguments->Add(PushArgument(value));
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1998 String::Handle(Field::GetterName(node->field_name())); 2041 String::Handle(Field::GetterName(node->field_name()));
1999 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2042 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2000 new ZoneGrowableArray<PushArgumentInstr*>(); 2043 new ZoneGrowableArray<PushArgumentInstr*>();
2001 Function& getter_function = Function::ZoneHandle(); 2044 Function& getter_function = Function::ZoneHandle();
2002 if (node->is_super_getter()) { 2045 if (node->is_super_getter()) {
2003 // Statically resolved instance getter, i.e. "super getter". 2046 // Statically resolved instance getter, i.e. "super getter".
2004 getter_function = 2047 getter_function =
2005 Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); 2048 Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name);
2006 ASSERT(!getter_function.IsNull()); 2049 ASSERT(!getter_function.IsNull());
2007 ASSERT(node->receiver() != NULL); 2050 ASSERT(node->receiver() != NULL);
2008 ValueGraphVisitor receiver_value(owner(), temp_index()); 2051 ValueGraphVisitor receiver_value(owner(), temp_index(), loop_depth());
2009 node->receiver()->Visit(&receiver_value); 2052 node->receiver()->Visit(&receiver_value);
2010 Append(receiver_value); 2053 Append(receiver_value);
2011 arguments->Add(PushArgument(receiver_value.value())); 2054 arguments->Add(PushArgument(receiver_value.value()));
2012 } else { 2055 } else {
2013 getter_function = node->cls().LookupStaticFunction(getter_name); 2056 getter_function = node->cls().LookupStaticFunction(getter_name);
2014 if (getter_function.IsNull()) { 2057 if (getter_function.IsNull()) {
2015 // When the parser encounters a reference to a static field materialized 2058 // When the parser encounters a reference to a static field materialized
2016 // only by a static setter, but no corresponding static getter, it creates 2059 // only by a static setter, but no corresponding static getter, it creates
2017 // a StaticGetterNode ast node referring to the non-existing static getter 2060 // a StaticGetterNode ast node referring to the non-existing static getter
2018 // for the case this field reference appears in a left hand side 2061 // for the case this field reference appears in a left hand side
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2066 const Function& setter_function = 2109 const Function& setter_function =
2067 Function::ZoneHandle(is_super_setter 2110 Function::ZoneHandle(is_super_setter
2068 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name) 2111 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name)
2069 : node->cls().LookupStaticFunction(setter_name)); 2112 : node->cls().LookupStaticFunction(setter_name));
2070 ASSERT(!setter_function.IsNull()); 2113 ASSERT(!setter_function.IsNull());
2071 2114
2072 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2115 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2073 new ZoneGrowableArray<PushArgumentInstr*>(1); 2116 new ZoneGrowableArray<PushArgumentInstr*>(1);
2074 if (is_super_setter) { 2117 if (is_super_setter) {
2075 // Add receiver of instance getter. 2118 // Add receiver of instance getter.
2076 ValueGraphVisitor for_receiver(owner(), temp_index()); 2119 ValueGraphVisitor for_receiver(owner(), temp_index(), loop_depth());
2077 node->receiver()->Visit(&for_receiver); 2120 node->receiver()->Visit(&for_receiver);
2078 Append(for_receiver); 2121 Append(for_receiver);
2079 arguments->Add(PushArgument(for_receiver.value())); 2122 arguments->Add(PushArgument(for_receiver.value()));
2080 } 2123 }
2081 ValueGraphVisitor for_value(owner(), temp_index()); 2124 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth());
2082 node->value()->Visit(&for_value); 2125 node->value()->Visit(&for_value);
2083 Append(for_value); 2126 Append(for_value);
2084 Value* value = NULL; 2127 Value* value = NULL;
2085 if (result_is_needed) { 2128 if (result_is_needed) {
2086 value = Bind(BuildStoreExprTemp(for_value.value())); 2129 value = Bind(BuildStoreExprTemp(for_value.value()));
2087 } else { 2130 } else {
2088 value = for_value.value(); 2131 value = for_value.value();
2089 } 2132 }
2090 arguments->Add(PushArgument(value)); 2133 arguments->Add(PushArgument(value));
2091 2134
(...skipping 29 matching lines...) Expand all
2121 2164
2122 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { 2165 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) {
2123 // PrimaryNodes are temporary during parsing. 2166 // PrimaryNodes are temporary during parsing.
2124 UNREACHABLE(); 2167 UNREACHABLE();
2125 } 2168 }
2126 2169
2127 2170
2128 // <Expression> ::= LoadLocal { local: LocalVariable } 2171 // <Expression> ::= LoadLocal { local: LocalVariable }
2129 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { 2172 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) {
2130 if (node->HasPseudo()) { 2173 if (node->HasPseudo()) {
2131 EffectGraphVisitor for_pseudo(owner(), temp_index()); 2174 EffectGraphVisitor for_pseudo(owner(), temp_index(), loop_depth());
2132 node->pseudo()->Visit(&for_pseudo); 2175 node->pseudo()->Visit(&for_pseudo);
2133 Append(for_pseudo); 2176 Append(for_pseudo);
2134 } 2177 }
2135 } 2178 }
2136 2179
2137 2180
2138 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { 2181 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) {
2139 EffectGraphVisitor::VisitLoadLocalNode(node); 2182 EffectGraphVisitor::VisitLoadLocalNode(node);
2140 Definition* load = BuildLoadLocal(node->local()); 2183 Definition* load = BuildLoadLocal(node->local());
2141 ReturnDefinition(load); 2184 ReturnDefinition(load);
2142 } 2185 }
2143 2186
2144 2187
2145 // <Expression> ::= StoreLocal { local: LocalVariable 2188 // <Expression> ::= StoreLocal { local: LocalVariable
2146 // value: <Expression> } 2189 // value: <Expression> }
2147 void EffectGraphVisitor::HandleStoreLocal(StoreLocalNode* node, 2190 void EffectGraphVisitor::HandleStoreLocal(StoreLocalNode* node,
2148 bool result_is_needed) { 2191 bool result_is_needed) {
2149 ValueGraphVisitor for_value(owner(), temp_index()); 2192 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth());
2150 node->value()->Visit(&for_value); 2193 node->value()->Visit(&for_value);
2151 Append(for_value); 2194 Append(for_value);
2152 Value* store_value = for_value.value(); 2195 Value* store_value = for_value.value();
2153 if (FLAG_enable_type_checks) { 2196 if (FLAG_enable_type_checks) {
2154 store_value = BuildAssignableValue(node->value()->token_pos(), 2197 store_value = BuildAssignableValue(node->value()->token_pos(),
2155 store_value, 2198 store_value,
2156 node->local().type(), 2199 node->local().type(),
2157 node->local().name()); 2200 node->local().name());
2158 } 2201 }
2159 Definition* store = BuildStoreLocal(node->local(), 2202 Definition* store = BuildStoreLocal(node->local(),
2160 store_value, 2203 store_value,
2161 result_is_needed); 2204 result_is_needed);
2162 ReturnDefinition(store); 2205 ReturnDefinition(store);
2163 } 2206 }
2164 2207
2165 2208
2166 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { 2209 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
2167 HandleStoreLocal(node, kResultNotNeeded); 2210 HandleStoreLocal(node, kResultNotNeeded);
2168 } 2211 }
2169 2212
2170 2213
2171 void ValueGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { 2214 void ValueGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
2172 HandleStoreLocal(node, kResultNeeded); 2215 HandleStoreLocal(node, kResultNeeded);
2173 } 2216 }
2174 2217
2175 2218
2176 void EffectGraphVisitor::VisitLoadInstanceFieldNode( 2219 void EffectGraphVisitor::VisitLoadInstanceFieldNode(
2177 LoadInstanceFieldNode* node) { 2220 LoadInstanceFieldNode* node) {
2178 ValueGraphVisitor for_instance(owner(), temp_index()); 2221 ValueGraphVisitor for_instance(owner(), temp_index(), loop_depth());
2179 node->instance()->Visit(&for_instance); 2222 node->instance()->Visit(&for_instance);
2180 Append(for_instance); 2223 Append(for_instance);
2181 LoadFieldInstr* load = new LoadFieldInstr( 2224 LoadFieldInstr* load = new LoadFieldInstr(
2182 for_instance.value(), 2225 for_instance.value(),
2183 node->field().Offset(), 2226 node->field().Offset(),
2184 AbstractType::ZoneHandle(node->field().type())); 2227 AbstractType::ZoneHandle(node->field().type()));
2185 ReturnDefinition(load); 2228 ReturnDefinition(load);
2186 } 2229 }
2187 2230
2188 2231
2189 void EffectGraphVisitor::VisitStoreInstanceFieldNode( 2232 void EffectGraphVisitor::VisitStoreInstanceFieldNode(
2190 StoreInstanceFieldNode* node) { 2233 StoreInstanceFieldNode* node) {
2191 ValueGraphVisitor for_instance(owner(), temp_index()); 2234 ValueGraphVisitor for_instance(owner(), temp_index(), loop_depth());
2192 node->instance()->Visit(&for_instance); 2235 node->instance()->Visit(&for_instance);
2193 Append(for_instance); 2236 Append(for_instance);
2194 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); 2237 ValueGraphVisitor for_value(owner(), for_instance.temp_index(), loop_depth());
2195 node->value()->Visit(&for_value); 2238 node->value()->Visit(&for_value);
2196 Append(for_value); 2239 Append(for_value);
2197 Value* store_value = for_value.value(); 2240 Value* store_value = for_value.value();
2198 if (FLAG_enable_type_checks) { 2241 if (FLAG_enable_type_checks) {
2199 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); 2242 const AbstractType& type = AbstractType::ZoneHandle(node->field().type());
2200 const String& dst_name = String::ZoneHandle(node->field().name()); 2243 const String& dst_name = String::ZoneHandle(node->field().name());
2201 store_value = BuildAssignableValue(node->value()->token_pos(), 2244 store_value = BuildAssignableValue(node->value()->token_pos(),
2202 store_value, 2245 store_value,
2203 type, 2246 type,
2204 dst_name); 2247 dst_name);
(...skipping 13 matching lines...) Expand all
2218 2261
2219 2262
2220 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { 2263 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) {
2221 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(node->field()); 2264 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(node->field());
2222 ReturnDefinition(load); 2265 ReturnDefinition(load);
2223 } 2266 }
2224 2267
2225 2268
2226 Definition* EffectGraphVisitor::BuildStoreStaticField( 2269 Definition* EffectGraphVisitor::BuildStoreStaticField(
2227 StoreStaticFieldNode* node, bool result_is_needed) { 2270 StoreStaticFieldNode* node, bool result_is_needed) {
2228 ValueGraphVisitor for_value(owner(), temp_index()); 2271 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth());
2229 node->value()->Visit(&for_value); 2272 node->value()->Visit(&for_value);
2230 Append(for_value); 2273 Append(for_value);
2231 Value* store_value = NULL; 2274 Value* store_value = NULL;
2232 if (result_is_needed) { 2275 if (result_is_needed) {
2233 store_value = Bind(BuildStoreExprTemp(for_value.value())); 2276 store_value = Bind(BuildStoreExprTemp(for_value.value()));
2234 } else { 2277 } else {
2235 store_value = for_value.value(); 2278 store_value = for_value.value();
2236 } 2279 }
2237 if (FLAG_enable_type_checks) { 2280 if (FLAG_enable_type_checks) {
2238 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); 2281 const AbstractType& type = AbstractType::ZoneHandle(node->field().type());
(...skipping 21 matching lines...) Expand all
2260 2303
2261 2304
2262 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { 2305 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
2263 ReturnDefinition(BuildStoreStaticField(node, kResultNeeded)); 2306 ReturnDefinition(BuildStoreStaticField(node, kResultNeeded));
2264 } 2307 }
2265 2308
2266 2309
2267 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { 2310 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) {
2268 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2311 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2269 new ZoneGrowableArray<PushArgumentInstr*>(2); 2312 new ZoneGrowableArray<PushArgumentInstr*>(2);
2270 ValueGraphVisitor for_array(owner(), temp_index()); 2313 ValueGraphVisitor for_array(owner(), temp_index(), loop_depth());
2271 node->array()->Visit(&for_array); 2314 node->array()->Visit(&for_array);
2272 Append(for_array); 2315 Append(for_array);
2273 arguments->Add(PushArgument(for_array.value())); 2316 arguments->Add(PushArgument(for_array.value()));
2274 2317
2275 ValueGraphVisitor for_index(owner(), temp_index()); 2318 ValueGraphVisitor for_index(owner(), temp_index(), loop_depth());
2276 node->index_expr()->Visit(&for_index); 2319 node->index_expr()->Visit(&for_index);
2277 Append(for_index); 2320 Append(for_index);
2278 arguments->Add(PushArgument(for_index.value())); 2321 arguments->Add(PushArgument(for_index.value()));
2279 2322
2280 const intptr_t checked_argument_count = 1; 2323 const intptr_t checked_argument_count = 1;
2281 const String& name = 2324 const String& name =
2282 String::ZoneHandle(Symbols::New(Token::Str(Token::kINDEX))); 2325 String::ZoneHandle(Symbols::New(Token::Str(Token::kINDEX)));
2283 InstanceCallInstr* load = new InstanceCallInstr(node->token_pos(), 2326 InstanceCallInstr* load = new InstanceCallInstr(node->token_pos(),
2284 name, 2327 name,
2285 Token::kINDEX, 2328 Token::kINDEX,
2286 arguments, 2329 arguments,
2287 Array::ZoneHandle(), 2330 Array::ZoneHandle(),
2288 checked_argument_count); 2331 checked_argument_count);
2289 ReturnDefinition(load); 2332 ReturnDefinition(load);
2290 } 2333 }
2291 2334
2292 2335
2293 Definition* EffectGraphVisitor::BuildStoreIndexedValues( 2336 Definition* EffectGraphVisitor::BuildStoreIndexedValues(
2294 StoreIndexedNode* node, 2337 StoreIndexedNode* node,
2295 bool result_is_needed) { 2338 bool result_is_needed) {
2296 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2339 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2297 new ZoneGrowableArray<PushArgumentInstr*>(3); 2340 new ZoneGrowableArray<PushArgumentInstr*>(3);
2298 ValueGraphVisitor for_array(owner(), temp_index()); 2341 ValueGraphVisitor for_array(owner(), temp_index(), loop_depth());
2299 node->array()->Visit(&for_array); 2342 node->array()->Visit(&for_array);
2300 Append(for_array); 2343 Append(for_array);
2301 arguments->Add(PushArgument(for_array.value())); 2344 arguments->Add(PushArgument(for_array.value()));
2302 2345
2303 ValueGraphVisitor for_index(owner(), temp_index()); 2346 ValueGraphVisitor for_index(owner(), temp_index(), loop_depth());
2304 node->index_expr()->Visit(&for_index); 2347 node->index_expr()->Visit(&for_index);
2305 Append(for_index); 2348 Append(for_index);
2306 arguments->Add(PushArgument(for_index.value())); 2349 arguments->Add(PushArgument(for_index.value()));
2307 2350
2308 ValueGraphVisitor for_value(owner(), temp_index()); 2351 ValueGraphVisitor for_value(owner(), temp_index(), loop_depth());
2309 node->value()->Visit(&for_value); 2352 node->value()->Visit(&for_value);
2310 Append(for_value); 2353 Append(for_value);
2311 Value* value = NULL; 2354 Value* value = NULL;
2312 if (result_is_needed) { 2355 if (result_is_needed) {
2313 value = Bind(BuildStoreExprTemp(for_value.value())); 2356 value = Bind(BuildStoreExprTemp(for_value.value()));
2314 } else { 2357 } else {
2315 value = for_value.value(); 2358 value = for_value.value();
2316 } 2359 }
2317 arguments->Add(PushArgument(value)); 2360 arguments->Add(PushArgument(value));
2318 2361
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
2464 // variable so that ssa renaming detects the dependency and makes use 2507 // variable so that ssa renaming detects the dependency and makes use
2465 // of the checked type in type propagation. 2508 // of the checked type in type propagation.
2466 Do(BuildStoreLocal(parameter, parameter_value, kResultNotNeeded)); 2509 Do(BuildStoreLocal(parameter, parameter_value, kResultNotNeeded));
2467 } 2510 }
2468 pos++; 2511 pos++;
2469 } 2512 }
2470 } 2513 }
2471 2514
2472 intptr_t i = 0; 2515 intptr_t i = 0;
2473 while (is_open() && (i < node->length())) { 2516 while (is_open() && (i < node->length())) {
2474 EffectGraphVisitor for_effect(owner(), temp_index()); 2517 EffectGraphVisitor for_effect(owner(), temp_index(), loop_depth());
2475 node->NodeAt(i++)->Visit(&for_effect); 2518 node->NodeAt(i++)->Visit(&for_effect);
2476 Append(for_effect); 2519 Append(for_effect);
2477 if (!is_open()) { 2520 if (!is_open()) {
2478 // E.g., because of a JumpNode. 2521 // E.g., because of a JumpNode.
2479 break; 2522 break;
2480 } 2523 }
2481 } 2524 }
2482 2525
2483 if (is_open()) { 2526 if (is_open()) {
2484 if (MustSaveRestoreContext(node)) { 2527 if (MustSaveRestoreContext(node)) {
2485 ASSERT(num_context_variables > 0); 2528 ASSERT(num_context_variables > 0);
2486 BuildLoadContext(*owner()->parsed_function().saved_context_var()); 2529 BuildLoadContext(*owner()->parsed_function().saved_context_var());
2487 } else if (num_context_variables > 0) { 2530 } else if (num_context_variables > 0) {
2488 UnchainContext(); 2531 UnchainContext();
2489 } 2532 }
2490 } 2533 }
2491 2534
2492 // No continue on sequence allowed. 2535 // No continue on sequence allowed.
2493 ASSERT((node->label() == NULL) || 2536 ASSERT((node->label() == NULL) ||
2494 (node->label()->join_for_continue() == NULL)); 2537 (node->label()->join_for_continue() == NULL));
2495 // If this node sequence is labeled, a break out of the sequence will have 2538 // If this node sequence is labeled, a break out of the sequence will have
2496 // taken care of unchaining the context. 2539 // taken care of unchaining the context.
2497 if ((node->label() != NULL) && 2540 if ((node->label() != NULL) &&
2498 (node->label()->join_for_break() != NULL)) { 2541 (node->label()->join_for_break() != NULL)) {
2542 node->label()->join_for_break()->set_loop_depth(loop_depth());
2499 if (is_open()) Goto(node->label()->join_for_break()); 2543 if (is_open()) Goto(node->label()->join_for_break());
2500 exit_ = node->label()->join_for_break(); 2544 exit_ = node->label()->join_for_break();
2501 } 2545 }
2502 2546
2503 // The outermost function sequence cannot contain a label. 2547 // The outermost function sequence cannot contain a label.
2504 ASSERT((node->label() == NULL) || 2548 ASSERT((node->label() == NULL) ||
2505 (node != owner()->parsed_function().node_sequence())); 2549 (node != owner()->parsed_function().node_sequence()));
2506 owner()->set_context_level(previous_context_level); 2550 owner()->set_context_level(previous_context_level);
2507 } 2551 }
2508 2552
2509 2553
2510 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { 2554 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) {
2511 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)"); 2555 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)");
2512 // NOTE: The implicit variables ':saved_context', ':exception_var' 2556 // NOTE: The implicit variables ':saved_context', ':exception_var'
2513 // and ':stacktrace_var' can never be captured variables. 2557 // and ':stacktrace_var' can never be captured variables.
2514 // Restores CTX from local variable ':saved_context'. 2558 // Restores CTX from local variable ':saved_context'.
2515 AddInstruction( 2559 AddInstruction(
2516 new CatchEntryInstr(node->exception_var(), node->stacktrace_var())); 2560 new CatchEntryInstr(node->exception_var(), node->stacktrace_var()));
2517 BuildLoadContext(node->context_var()); 2561 BuildLoadContext(node->context_var());
2518 2562
2519 EffectGraphVisitor for_catch(owner(), temp_index()); 2563 EffectGraphVisitor for_catch(owner(), temp_index(), loop_depth());
2520 node->VisitChildren(&for_catch); 2564 node->VisitChildren(&for_catch);
2521 Append(for_catch); 2565 Append(for_catch);
2522 } 2566 }
2523 2567
2524 2568
2525 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { 2569 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) {
2526 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); 2570 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)");
2527 intptr_t old_try_index = owner()->try_index(); 2571 intptr_t old_try_index = owner()->try_index();
2528 intptr_t try_index = owner()->AllocateTryIndex(); 2572 intptr_t try_index = owner()->AllocateTryIndex();
2529 owner()->set_try_index(try_index); 2573 owner()->set_try_index(try_index);
2530 2574
2531 // Preserve CTX into local variable '%saved_context'. 2575 // Preserve CTX into local variable '%saved_context'.
2532 BuildStoreContext(node->context_var()); 2576 BuildStoreContext(node->context_var());
2533 2577
2534 EffectGraphVisitor for_try_block(owner(), temp_index()); 2578 EffectGraphVisitor for_try_block(owner(), temp_index(), loop_depth());
2535 node->try_block()->Visit(&for_try_block); 2579 node->try_block()->Visit(&for_try_block);
2536 2580
2537 if (for_try_block.is_open()) { 2581 if (for_try_block.is_open()) {
2538 JoinEntryInstr* after_try = 2582 JoinEntryInstr* after_try =
2539 new JoinEntryInstr(owner()->AllocateBlockId(), old_try_index); 2583 new JoinEntryInstr(owner()->AllocateBlockId(),
2584 old_try_index,
2585 loop_depth());
2540 for_try_block.Goto(after_try); 2586 for_try_block.Goto(after_try);
2541 for_try_block.exit_ = after_try; 2587 for_try_block.exit_ = after_try;
2542 } 2588 }
2543 2589
2544 JoinEntryInstr* try_entry = 2590 JoinEntryInstr* try_entry =
2545 new JoinEntryInstr(owner()->AllocateBlockId(), try_index); 2591 new JoinEntryInstr(owner()->AllocateBlockId(), try_index, loop_depth());
2546 2592
2547 Goto(try_entry); 2593 Goto(try_entry);
2548 AppendFragment(try_entry, for_try_block); 2594 AppendFragment(try_entry, for_try_block);
2549 exit_ = for_try_block.exit_; 2595 exit_ = for_try_block.exit_;
2550 2596
2551 // We are done generating code for the try block. 2597 // We are done generating code for the try block.
2552 owner()->set_try_index(old_try_index); 2598 owner()->set_try_index(old_try_index);
2553 2599
2554 CatchClauseNode* catch_block = node->catch_block(); 2600 CatchClauseNode* catch_block = node->catch_block();
2555 if (catch_block != NULL) { 2601 if (catch_block != NULL) {
2556 // Set the corresponding try index for this catch block so 2602 // Set the corresponding try index for this catch block so
2557 // that we can set the appropriate handler pc when we generate 2603 // that we can set the appropriate handler pc when we generate
2558 // code for this catch block. 2604 // code for this catch block.
2559 catch_block->set_try_index(try_index); 2605 catch_block->set_try_index(try_index);
2560 EffectGraphVisitor for_catch_block(owner(), temp_index()); 2606 EffectGraphVisitor for_catch_block(owner(), temp_index(), loop_depth());
2561 catch_block->Visit(&for_catch_block); 2607 catch_block->Visit(&for_catch_block);
2562 TargetEntryInstr* catch_entry = 2608 TargetEntryInstr* catch_entry =
2563 new TargetEntryInstr(owner()->AllocateBlockId(), old_try_index); 2609 new TargetEntryInstr(owner()->AllocateBlockId(),
2610 old_try_index,
2611 loop_depth());
2564 catch_entry->set_catch_try_index(try_index); 2612 catch_entry->set_catch_try_index(try_index);
2565 owner()->AddCatchEntry(catch_entry); 2613 owner()->AddCatchEntry(catch_entry);
2566 ASSERT(!for_catch_block.is_open()); 2614 ASSERT(!for_catch_block.is_open());
2567 AppendFragment(catch_entry, for_catch_block); 2615 AppendFragment(catch_entry, for_catch_block);
2568 if (node->end_catch_label() != NULL) { 2616 if (node->end_catch_label() != NULL) {
2569 JoinEntryInstr* join = node->end_catch_label()->join_for_continue(); 2617 JoinEntryInstr* join = node->end_catch_label()->join_for_continue();
2570 if (join != NULL) { 2618 if (join != NULL) {
2619 join->set_loop_depth(loop_depth());
2571 if (is_open()) Goto(join); 2620 if (is_open()) Goto(join);
2572 exit_ = join; 2621 exit_ = join;
2573 } 2622 }
2574 } 2623 }
2575 } 2624 }
2576 2625
2577 // Generate code for the finally block if one exists. 2626 // Generate code for the finally block if one exists.
2578 if ((node->finally_block() != NULL) && is_open()) { 2627 if ((node->finally_block() != NULL) && is_open()) {
2579 EffectGraphVisitor for_finally_block(owner(), temp_index()); 2628 EffectGraphVisitor for_finally_block(owner(), temp_index(), loop_depth());
2580 node->finally_block()->Visit(&for_finally_block); 2629 node->finally_block()->Visit(&for_finally_block);
2581 Append(for_finally_block); 2630 Append(for_finally_block);
2582 } 2631 }
2583 } 2632 }
2584 2633
2585 2634
2586 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { 2635 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) {
2587 // TODO(kmillikin) non-local control flow is not handled correctly 2636 // TODO(kmillikin) non-local control flow is not handled correctly
2588 // by the inliner. 2637 // by the inliner.
2589 InlineBailout("EffectGraphVisitor::BuildThrowNode (exception)"); 2638 InlineBailout("EffectGraphVisitor::BuildThrowNode (exception)");
2590 ValueGraphVisitor for_exception(owner(), temp_index()); 2639 ValueGraphVisitor for_exception(owner(), temp_index(), loop_depth());
2591 node->exception()->Visit(&for_exception); 2640 node->exception()->Visit(&for_exception);
2592 Append(for_exception); 2641 Append(for_exception);
2593 PushArgument(for_exception.value()); 2642 PushArgument(for_exception.value());
2594 Instruction* instr = NULL; 2643 Instruction* instr = NULL;
2595 if (node->stacktrace() == NULL) { 2644 if (node->stacktrace() == NULL) {
2596 instr = new ThrowInstr(node->token_pos()); 2645 instr = new ThrowInstr(node->token_pos());
2597 } else { 2646 } else {
2598 ValueGraphVisitor for_stack_trace(owner(), temp_index()); 2647 ValueGraphVisitor for_stack_trace(owner(), temp_index(), loop_depth());
2599 node->stacktrace()->Visit(&for_stack_trace); 2648 node->stacktrace()->Visit(&for_stack_trace);
2600 Append(for_stack_trace); 2649 Append(for_stack_trace);
2601 PushArgument(for_stack_trace.value()); 2650 PushArgument(for_stack_trace.value());
2602 instr = new ReThrowInstr(node->token_pos()); 2651 instr = new ReThrowInstr(node->token_pos());
2603 } 2652 }
2604 AddInstruction(instr); 2653 AddInstruction(instr);
2605 } 2654 }
2606 2655
2607 2656
2608 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { 2657 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) {
(...skipping 16 matching lines...) Expand all
2625 const intptr_t try_index = owner()->try_index(); 2674 const intptr_t try_index = owner()->try_index();
2626 if (try_index >= 0) { 2675 if (try_index >= 0) {
2627 // We are about to generate code for an inlined finally block. Exceptions 2676 // We are about to generate code for an inlined finally block. Exceptions
2628 // thrown in this block of code should be treated as though they are 2677 // thrown in this block of code should be treated as though they are
2629 // thrown not from the current try block but the outer try block if any. 2678 // thrown not from the current try block but the outer try block if any.
2630 owner()->set_try_index((try_index - 1)); 2679 owner()->set_try_index((try_index - 1));
2631 } 2680 }
2632 BuildLoadContext(node->context_var()); 2681 BuildLoadContext(node->context_var());
2633 2682
2634 JoinEntryInstr* finally_entry = 2683 JoinEntryInstr* finally_entry =
2635 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 2684 new JoinEntryInstr(owner()->AllocateBlockId(),
2636 EffectGraphVisitor for_finally_block(owner(), temp_index()); 2685 owner()->try_index(),
2686 loop_depth());
2687 EffectGraphVisitor for_finally_block(owner(), temp_index(), loop_depth());
2637 node->finally_block()->Visit(&for_finally_block); 2688 node->finally_block()->Visit(&for_finally_block);
2638 2689
2639 if (try_index >= 0) { 2690 if (try_index >= 0) {
2640 owner()->set_try_index(try_index); 2691 owner()->set_try_index(try_index);
2641 } 2692 }
2642 2693
2643 if (for_finally_block.is_open()) { 2694 if (for_finally_block.is_open()) {
2644 JoinEntryInstr* after_finally = 2695 JoinEntryInstr* after_finally =
2645 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 2696 new JoinEntryInstr(owner()->AllocateBlockId(),
2697 owner()->try_index(),
2698 loop_depth());
2646 for_finally_block.Goto(after_finally); 2699 for_finally_block.Goto(after_finally);
2647 for_finally_block.exit_ = after_finally; 2700 for_finally_block.exit_ = after_finally;
2648 } 2701 }
2649 2702
2650 Goto(finally_entry); 2703 Goto(finally_entry);
2651 AppendFragment(finally_entry, for_finally_block); 2704 AppendFragment(finally_entry, for_finally_block);
2652 exit_ = for_finally_block.exit_; 2705 exit_ = for_finally_block.exit_;
2653 } 2706 }
2654 2707
2655 2708
2656 FlowGraph* FlowGraphBuilder::BuildGraph(InliningContext context) { 2709 FlowGraph* FlowGraphBuilder::BuildGraph(InliningContext context,
2710 intptr_t initial_loop_depth) {
2657 if (FLAG_print_ast) { 2711 if (FLAG_print_ast) {
2658 // Print the function ast before IL generation. 2712 // Print the function ast before IL generation.
2659 AstPrinter::PrintFunctionNodes(parsed_function()); 2713 AstPrinter::PrintFunctionNodes(parsed_function());
2660 } 2714 }
2661 // Set the inlining context. 2715 // Set the inlining context.
2662 ASSERT(inlining_context_ == kNotInlining); 2716 ASSERT(inlining_context_ == kNotInlining);
2663 inlining_context_ = context; 2717 inlining_context_ = context;
2664 if (InInliningContext()) exits_ = new ZoneGrowableArray<ReturnInstr*>(); 2718 if (InInliningContext()) exits_ = new ZoneGrowableArray<ReturnInstr*>();
2665 // Compilation can be nested, preserve the computation-id. 2719 // Compilation can be nested, preserve the computation-id.
2666 const Function& function = parsed_function().function(); 2720 const Function& function = parsed_function().function();
2667 TargetEntryInstr* normal_entry = 2721 TargetEntryInstr* normal_entry =
2668 new TargetEntryInstr(AllocateBlockId(), 2722 new TargetEntryInstr(AllocateBlockId(),
2669 CatchClauseNode::kInvalidTryIndex); 2723 CatchClauseNode::kInvalidTryIndex,
2724 initial_loop_depth);
2670 graph_entry_ = new GraphEntryInstr(normal_entry); 2725 graph_entry_ = new GraphEntryInstr(normal_entry);
2671 EffectGraphVisitor for_effect(this, 0); 2726 EffectGraphVisitor for_effect(this, 0, initial_loop_depth);
2672 if (InInliningContext()) { 2727 if (InInliningContext()) {
2673 exits_ = new ZoneGrowableArray<ReturnInstr*>(); 2728 exits_ = new ZoneGrowableArray<ReturnInstr*>();
2674 } 2729 }
2675 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the 2730 // TODO(kmillikin): We can eliminate stack checks in some cases (e.g., the
2676 // stack check on entry for leaf routines). 2731 // stack check on entry for leaf routines).
2677 Instruction* check = new CheckStackOverflowInstr(function.token_pos()); 2732 Instruction* check = new CheckStackOverflowInstr(function.token_pos());
2678 // If we are inlining don't actually attach the stack check. We must still 2733 // If we are inlining don't actually attach the stack check. We must still
2679 // create the stack check inorder to allocate a deopt id. 2734 // create the stack check inorder to allocate a deopt id.
2680 if (!InInliningContext()) for_effect.AddInstruction(check); 2735 if (!InInliningContext()) for_effect.AddInstruction(check);
2681 parsed_function().node_sequence()->Visit(&for_effect); 2736 parsed_function().node_sequence()->Visit(&for_effect);
(...skipping 12 matching lines...) Expand all
2694 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 2749 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
2695 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 2750 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
2696 OS::SNPrint(chars, len, kFormat, function_name, reason); 2751 OS::SNPrint(chars, len, kFormat, function_name, reason);
2697 const Error& error = Error::Handle( 2752 const Error& error = Error::Handle(
2698 LanguageError::New(String::Handle(String::New(chars)))); 2753 LanguageError::New(String::Handle(String::New(chars))));
2699 Isolate::Current()->long_jump_base()->Jump(1, error); 2754 Isolate::Current()->long_jump_base()->Jump(1, error);
2700 } 2755 }
2701 2756
2702 2757
2703 } // namespace dart 2758 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698