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

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

Issue 2904733003: Revert "Shuffle around deopt id allocation to give the flow graph builder a chance to record other … (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_builder.h" 5 #include "vm/flow_graph_builder.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/ast_printer.h" 8 #include "vm/ast_printer.h"
9 #include "vm/bit_vector.h" 9 #include "vm/bit_vector.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 166
167 167
168 intptr_t FlowGraphBuilder::context_level() const { 168 intptr_t FlowGraphBuilder::context_level() const {
169 return (nesting_stack() == NULL) ? 0 : nesting_stack()->ContextLevel(); 169 return (nesting_stack() == NULL) ? 0 : nesting_stack()->ContextLevel();
170 } 170 }
171 171
172 172
173 JoinEntryInstr* NestedStatement::BreakTargetFor(SourceLabel* label) { 173 JoinEntryInstr* NestedStatement::BreakTargetFor(SourceLabel* label) {
174 if (label != label_) return NULL; 174 if (label != label_) return NULL;
175 if (break_target_ == NULL) { 175 if (break_target_ == NULL) {
176 break_target_ = new (owner()->zone()) JoinEntryInstr( 176 break_target_ = new (owner()->zone())
177 owner()->AllocateBlockId(), try_index(), owner()->GetNextDeoptId()); 177 JoinEntryInstr(owner()->AllocateBlockId(), try_index());
178 } 178 }
179 return break_target_; 179 return break_target_;
180 } 180 }
181 181
182 182
183 JoinEntryInstr* NestedStatement::ContinueTargetFor(SourceLabel* label) { 183 JoinEntryInstr* NestedStatement::ContinueTargetFor(SourceLabel* label) {
184 return NULL; 184 return NULL;
185 } 185 }
186 186
187 187
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 virtual JoinEntryInstr* ContinueTargetFor(SourceLabel* label); 239 virtual JoinEntryInstr* ContinueTargetFor(SourceLabel* label);
240 240
241 private: 241 private:
242 JoinEntryInstr* continue_target_; 242 JoinEntryInstr* continue_target_;
243 }; 243 };
244 244
245 245
246 JoinEntryInstr* NestedLoop::ContinueTargetFor(SourceLabel* label) { 246 JoinEntryInstr* NestedLoop::ContinueTargetFor(SourceLabel* label) {
247 if (label != this->label()) return NULL; 247 if (label != this->label()) return NULL;
248 if (continue_target_ == NULL) { 248 if (continue_target_ == NULL) {
249 continue_target_ = new (owner()->zone()) JoinEntryInstr( 249 continue_target_ = new (owner()->zone())
250 owner()->AllocateBlockId(), try_index(), owner()->GetNextDeoptId()); 250 JoinEntryInstr(owner()->AllocateBlockId(), try_index());
251 } 251 }
252 return continue_target_; 252 return continue_target_;
253 } 253 }
254 254
255 255
256 // A nested switch which can be the target of a break if labeled, and whose 256 // A nested switch which can be the target of a break if labeled, and whose
257 // cases can be the targets of continues. 257 // cases can be the targets of continues.
258 class NestedSwitch : public NestedStatement { 258 class NestedSwitch : public NestedStatement {
259 public: 259 public:
260 NestedSwitch(FlowGraphBuilder* owner, SwitchNode* node); 260 NestedSwitch(FlowGraphBuilder* owner, SwitchNode* node);
(...skipping 21 matching lines...) Expand all
282 } 282 }
283 283
284 284
285 JoinEntryInstr* NestedSwitch::ContinueTargetFor(SourceLabel* label) { 285 JoinEntryInstr* NestedSwitch::ContinueTargetFor(SourceLabel* label) {
286 // Allocate a join for a case clause that matches the label. This block 286 // Allocate a join for a case clause that matches the label. This block
287 // is not necessarily targeted by a continue, but we always use a join in 287 // is not necessarily targeted by a continue, but we always use a join in
288 // the graph anyway. 288 // the graph anyway.
289 for (intptr_t i = 0; i < case_labels_.length(); ++i) { 289 for (intptr_t i = 0; i < case_labels_.length(); ++i) {
290 if (label != case_labels_[i]) continue; 290 if (label != case_labels_[i]) continue;
291 if (case_targets_[i] == NULL) { 291 if (case_targets_[i] == NULL) {
292 case_targets_[i] = new (owner()->zone()) JoinEntryInstr( 292 case_targets_[i] = new (owner()->zone())
293 owner()->AllocateBlockId(), try_index(), owner()->GetNextDeoptId()); 293 JoinEntryInstr(owner()->AllocateBlockId(), try_index());
294 } 294 }
295 return case_targets_[i]; 295 return case_targets_[i];
296 } 296 }
297 return NULL; 297 return NULL;
298 } 298 }
299 299
300 300
301 FlowGraphBuilder::FlowGraphBuilder( 301 FlowGraphBuilder::FlowGraphBuilder(
302 const ParsedFunction& parsed_function, 302 const ParsedFunction& parsed_function,
303 const ZoneGrowableArray<const ICData*>& ic_data_array, 303 const ZoneGrowableArray<const ICData*>& ic_data_array,
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 if (num_exits == 1) { 435 if (num_exits == 1) {
436 ReturnAt(0)->UnuseAllInputs(); 436 ReturnAt(0)->UnuseAllInputs();
437 *exit_block = ExitBlockAt(0); 437 *exit_block = ExitBlockAt(0);
438 *last_instruction = LastInstructionAt(0); 438 *last_instruction = LastInstructionAt(0);
439 return call_->HasUses() ? ValueAt(0)->definition() : NULL; 439 return call_->HasUses() ? ValueAt(0)->definition() : NULL;
440 } else { 440 } else {
441 ASSERT(num_exits > 1); 441 ASSERT(num_exits > 1);
442 // Create a join of the returns. 442 // Create a join of the returns.
443 intptr_t join_id = caller_graph_->max_block_id() + 1; 443 intptr_t join_id = caller_graph_->max_block_id() + 1;
444 caller_graph_->set_max_block_id(join_id); 444 caller_graph_->set_max_block_id(join_id);
445 JoinEntryInstr* join = new (Z) 445 JoinEntryInstr* join = new (Z) JoinEntryInstr(join_id, try_index);
446 JoinEntryInstr(join_id, try_index, Thread::Current()->GetNextDeoptId());
447 446
448 // The dominator set of the join is the intersection of the dominator 447 // The dominator set of the join is the intersection of the dominator
449 // sets of all the predecessors. If we keep the dominator sets ordered 448 // sets of all the predecessors. If we keep the dominator sets ordered
450 // by height in the dominator tree, we can also get the immediate 449 // by height in the dominator tree, we can also get the immediate
451 // dominator of the join node from the intersection. 450 // dominator of the join node from the intersection.
452 // 451 //
453 // block_dominators is the dominator set for each block, ordered from 452 // block_dominators is the dominator set for each block, ordered from
454 // the immediate dominator to the root of the dominator tree. This is 453 // the immediate dominator to the root of the dominator tree. This is
455 // the order we collect them in (adding at the end). 454 // the order we collect them in (adding at the end).
456 // 455 //
457 // join_dominators is the join's dominators ordered from the root of the 456 // join_dominators is the join's dominators ordered from the root of the
458 // dominator tree to the immediate dominator. This order supports 457 // dominator tree to the immediate dominator. This order supports
459 // removing during intersection by truncating the list. 458 // removing during intersection by truncating the list.
460 GrowableArray<BlockEntryInstr*> block_dominators; 459 GrowableArray<BlockEntryInstr*> block_dominators;
461 GrowableArray<BlockEntryInstr*> join_dominators; 460 GrowableArray<BlockEntryInstr*> join_dominators;
462 for (intptr_t i = 0; i < num_exits; ++i) { 461 for (intptr_t i = 0; i < num_exits; ++i) {
463 // Add the control-flow edge. 462 // Add the control-flow edge.
464 GotoInstr* goto_instr = 463 GotoInstr* goto_instr = new (Z) GotoInstr(join);
465 new (Z) GotoInstr(join, Thread::Current()->GetNextDeoptId());
466 goto_instr->InheritDeoptTarget(zone(), ReturnAt(i)); 464 goto_instr->InheritDeoptTarget(zone(), ReturnAt(i));
467 LastInstructionAt(i)->LinkTo(goto_instr); 465 LastInstructionAt(i)->LinkTo(goto_instr);
468 ExitBlockAt(i)->set_last_instruction(LastInstructionAt(i)->next()); 466 ExitBlockAt(i)->set_last_instruction(LastInstructionAt(i)->next());
469 join->predecessors_.Add(ExitBlockAt(i)); 467 join->predecessors_.Add(ExitBlockAt(i));
470 468
471 // Collect the block's dominators. 469 // Collect the block's dominators.
472 block_dominators.Clear(); 470 block_dominators.Clear();
473 BlockEntryInstr* dominator = ExitBlockAt(i)->dominator(); 471 BlockEntryInstr* dominator = ExitBlockAt(i)->dominator();
474 while (dominator != NULL) { 472 while (dominator != NULL) {
475 block_dominators.Add(dominator); 473 block_dominators.Add(dominator);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 Instruction* callee_last_instruction = NULL; 539 Instruction* callee_last_instruction = NULL;
542 540
543 if (exits_.length() == 0) { 541 if (exits_.length() == 0) {
544 // Handle the case when there are no normal return exits from the callee 542 // Handle the case when there are no normal return exits from the callee
545 // (i.e. the callee unconditionally throws) by inserting an artificial 543 // (i.e. the callee unconditionally throws) by inserting an artificial
546 // branch (true === true). 544 // branch (true === true).
547 // The true successor is the inlined body, the false successor 545 // The true successor is the inlined body, the false successor
548 // goes to the rest of the caller graph. It is removed as unreachable code 546 // goes to the rest of the caller graph. It is removed as unreachable code
549 // by the constant propagation. 547 // by the constant propagation.
550 TargetEntryInstr* false_block = new (Z) TargetEntryInstr( 548 TargetEntryInstr* false_block = new (Z) TargetEntryInstr(
551 caller_graph_->allocate_block_id(), call_block->try_index(), 549 caller_graph_->allocate_block_id(), call_block->try_index());
552 Thread::Current()->GetNextDeoptId());
553 false_block->InheritDeoptTargetAfter(caller_graph_, call_, NULL); 550 false_block->InheritDeoptTargetAfter(caller_graph_, call_, NULL);
554 false_block->LinkTo(call_->next()); 551 false_block->LinkTo(call_->next());
555 call_block->ReplaceAsPredecessorWith(false_block); 552 call_block->ReplaceAsPredecessorWith(false_block);
556 553
557 ConstantInstr* true_const = caller_graph_->GetConstant(Bool::True()); 554 ConstantInstr* true_const = caller_graph_->GetConstant(Bool::True());
558 BranchInstr* branch = new (Z) 555 BranchInstr* branch = new (Z) BranchInstr(new (Z) StrictCompareInstr(
559 BranchInstr(new (Z) StrictCompareInstr( 556 TokenPosition::kNoSource, Token::kEQ_STRICT, new (Z) Value(true_const),
560 TokenPosition::kNoSource, Token::kEQ_STRICT, 557 new (Z) Value(true_const),
561 new (Z) Value(true_const), new (Z) Value(true_const), 558 false)); // No number check.
562 false, Thread::Current()->GetNextDeoptId()),
563 Thread::Current()->GetNextDeoptId()); // No number check.
564 branch->InheritDeoptTarget(zone(), call_); 559 branch->InheritDeoptTarget(zone(), call_);
565 *branch->true_successor_address() = callee_entry; 560 *branch->true_successor_address() = callee_entry;
566 *branch->false_successor_address() = false_block; 561 *branch->false_successor_address() = false_block;
567 562
568 call_->previous()->AppendInstruction(branch); 563 call_->previous()->AppendInstruction(branch);
569 call_block->set_last_instruction(branch); 564 call_block->set_last_instruction(branch);
570 565
571 // Replace uses of the return value with null to maintain valid 566 // Replace uses of the return value with null to maintain valid
572 // SSA form - even though the rest of the caller is unreachable. 567 // SSA form - even though the rest of the caller is unreachable.
573 call_->ReplaceUsesWith(caller_graph_->constant_null()); 568 call_->ReplaceUsesWith(caller_graph_->constant_null());
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 entry_ = exit_ = instruction; 692 entry_ = exit_ = instruction;
698 } else { 693 } else {
699 exit()->LinkTo(instruction); 694 exit()->LinkTo(instruction);
700 exit_ = instruction; 695 exit_ = instruction;
701 } 696 }
702 } 697 }
703 698
704 699
705 void EffectGraphVisitor::AddReturnExit(TokenPosition token_pos, Value* value) { 700 void EffectGraphVisitor::AddReturnExit(TokenPosition token_pos, Value* value) {
706 ASSERT(is_open()); 701 ASSERT(is_open());
707 ReturnInstr* return_instr = 702 ReturnInstr* return_instr = new (Z) ReturnInstr(token_pos, value);
708 new (Z) ReturnInstr(token_pos, value, owner()->GetNextDeoptId());
709 AddInstruction(return_instr); 703 AddInstruction(return_instr);
710 InlineExitCollector* exit_collector = owner()->exit_collector(); 704 InlineExitCollector* exit_collector = owner()->exit_collector();
711 if (exit_collector != NULL) { 705 if (exit_collector != NULL) {
712 exit_collector->AddExit(return_instr); 706 exit_collector->AddExit(return_instr);
713 } 707 }
714 CloseFragment(); 708 CloseFragment();
715 } 709 }
716 710
717 711
718 void EffectGraphVisitor::Goto(JoinEntryInstr* join) { 712 void EffectGraphVisitor::Goto(JoinEntryInstr* join) {
719 ASSERT(is_open()); 713 ASSERT(is_open());
720 if (is_empty()) { 714 if (is_empty()) {
721 entry_ = new (Z) GotoInstr(join, owner()->GetNextDeoptId()); 715 entry_ = new (Z) GotoInstr(join);
722 } else { 716 } else {
723 exit()->Goto(join); 717 exit()->Goto(join);
724 } 718 }
725 CloseFragment(); 719 CloseFragment();
726 } 720 }
727 721
728 722
729 // Appends a graph fragment to a block entry instruction. Returns the entry 723 // Appends a graph fragment to a block entry instruction. Returns the entry
730 // instruction if the fragment was empty or else the exit of the fragment if 724 // instruction if the fragment was empty or else the exit of the fragment if
731 // it was non-empty (so NULL if the fragment is closed). 725 // it was non-empty (so NULL if the fragment is closed).
(...skipping 28 matching lines...) Expand all
760 754
761 BlockEntryInstr* false_entry = test_fragment.CreateFalseSuccessor(); 755 BlockEntryInstr* false_entry = test_fragment.CreateFalseSuccessor();
762 Instruction* false_exit = AppendFragment(false_entry, false_fragment); 756 Instruction* false_exit = AppendFragment(false_entry, false_fragment);
763 757
764 // 3. Add a join or select one (or neither) of the arms as exit. 758 // 3. Add a join or select one (or neither) of the arms as exit.
765 if (true_exit == NULL) { 759 if (true_exit == NULL) {
766 exit_ = false_exit; // May be NULL. 760 exit_ = false_exit; // May be NULL.
767 } else if (false_exit == NULL) { 761 } else if (false_exit == NULL) {
768 exit_ = true_exit; 762 exit_ = true_exit;
769 } else { 763 } else {
770 JoinEntryInstr* join = 764 JoinEntryInstr* join = new (Z)
771 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(), 765 JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
772 owner()->GetNextDeoptId());
773 true_exit->Goto(join); 766 true_exit->Goto(join);
774 false_exit->Goto(join); 767 false_exit->Goto(join);
775 exit_ = join; 768 exit_ = join;
776 } 769 }
777 } 770 }
778 771
779 772
780 void EffectGraphVisitor::TieLoop( 773 void EffectGraphVisitor::TieLoop(
781 TokenPosition token_pos, 774 TokenPosition token_pos,
782 const TestGraphVisitor& test_fragment, 775 const TestGraphVisitor& test_fragment,
783 const EffectGraphVisitor& body_fragment, 776 const EffectGraphVisitor& body_fragment,
784 const EffectGraphVisitor& test_preamble_fragment) { 777 const EffectGraphVisitor& test_preamble_fragment) {
785 // We have: a test graph fragment with zero, one, or two available exits; 778 // We have: a test graph fragment with zero, one, or two available exits;
786 // and an effect graph fragment with zero or one available exits. We want 779 // and an effect graph fragment with zero or one available exits. We want
787 // to append the 'while loop' consisting of the test graph fragment as 780 // to append the 'while loop' consisting of the test graph fragment as
788 // condition and the effect graph fragment as body. 781 // condition and the effect graph fragment as body.
789 ASSERT(is_open()); 782 ASSERT(is_open());
790 783
791 // 1. Connect the body to the test if it is reachable, and if so record 784 // 1. Connect the body to the test if it is reachable, and if so record
792 // its exit (if any). 785 // its exit (if any).
793 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor(); 786 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor();
794 Instruction* body_exit = AppendFragment(body_entry, body_fragment); 787 Instruction* body_exit = AppendFragment(body_entry, body_fragment);
795 788
796 // 2. Connect the test to this graph, including the body if reachable and 789 // 2. Connect the test to this graph, including the body if reachable and
797 // using a fresh join node if the body is reachable and has an open exit. 790 // using a fresh join node if the body is reachable and has an open exit.
798 if (body_exit == NULL) { 791 if (body_exit == NULL) {
799 Append(test_preamble_fragment); 792 Append(test_preamble_fragment);
800 Append(test_fragment); 793 Append(test_fragment);
801 } else { 794 } else {
802 JoinEntryInstr* join = 795 JoinEntryInstr* join = new (Z)
803 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(), 796 JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
804 owner()->GetNextDeoptId()); 797 CheckStackOverflowInstr* check =
805 CheckStackOverflowInstr* check = new (Z) CheckStackOverflowInstr( 798 new (Z) CheckStackOverflowInstr(token_pos, owner()->loop_depth());
806 token_pos, owner()->loop_depth(), owner()->GetNextDeoptId());
807 join->LinkTo(check); 799 join->LinkTo(check);
808 if (!test_preamble_fragment.is_empty()) { 800 if (!test_preamble_fragment.is_empty()) {
809 check->LinkTo(test_preamble_fragment.entry()); 801 check->LinkTo(test_preamble_fragment.entry());
810 test_preamble_fragment.exit()->LinkTo(test_fragment.entry()); 802 test_preamble_fragment.exit()->LinkTo(test_fragment.entry());
811 } else { 803 } else {
812 check->LinkTo(test_fragment.entry()); 804 check->LinkTo(test_fragment.entry());
813 } 805 }
814 Goto(join); 806 Goto(join);
815 body_exit->Goto(join); 807 body_exit->Goto(join);
816 } 808 }
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 *owner()->parsed_function().current_context_var(), token_pos); 922 *owner()->parsed_function().current_context_var(), token_pos);
931 } 923 }
932 924
933 925
934 void TestGraphVisitor::ConnectBranchesTo( 926 void TestGraphVisitor::ConnectBranchesTo(
935 const GrowableArray<TargetEntryInstr**>& branches, 927 const GrowableArray<TargetEntryInstr**>& branches,
936 JoinEntryInstr* join) const { 928 JoinEntryInstr* join) const {
937 ASSERT(!branches.is_empty()); 929 ASSERT(!branches.is_empty());
938 for (intptr_t i = 0; i < branches.length(); i++) { 930 for (intptr_t i = 0; i < branches.length(); i++) {
939 TargetEntryInstr* target = new (Z) 931 TargetEntryInstr* target = new (Z)
940 TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index(), 932 TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
941 owner()->GetNextDeoptId());
942 *(branches[i]) = target; 933 *(branches[i]) = target;
943 target->Goto(join); 934 target->Goto(join);
944 } 935 }
945 } 936 }
946 937
947 938
948 void TestGraphVisitor::IfTrueGoto(JoinEntryInstr* join) const { 939 void TestGraphVisitor::IfTrueGoto(JoinEntryInstr* join) const {
949 ConnectBranchesTo(true_successor_addresses_, join); 940 ConnectBranchesTo(true_successor_addresses_, join);
950 } 941 }
951 942
952 943
953 void TestGraphVisitor::IfFalseGoto(JoinEntryInstr* join) const { 944 void TestGraphVisitor::IfFalseGoto(JoinEntryInstr* join) const {
954 ConnectBranchesTo(false_successor_addresses_, join); 945 ConnectBranchesTo(false_successor_addresses_, join);
955 } 946 }
956 947
957 948
958 BlockEntryInstr* TestGraphVisitor::CreateSuccessorFor( 949 BlockEntryInstr* TestGraphVisitor::CreateSuccessorFor(
959 const GrowableArray<TargetEntryInstr**>& branches) const { 950 const GrowableArray<TargetEntryInstr**>& branches) const {
960 ASSERT(!branches.is_empty()); 951 ASSERT(!branches.is_empty());
961 952
962 if (branches.length() == 1) { 953 if (branches.length() == 1) {
963 TargetEntryInstr* target = new (Z) 954 TargetEntryInstr* target = new (Z)
964 TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index(), 955 TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
965 owner()->GetNextDeoptId());
966 *(branches[0]) = target; 956 *(branches[0]) = target;
967 return target; 957 return target;
968 } 958 }
969 959
970 JoinEntryInstr* join = 960 JoinEntryInstr* join =
971 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(), 961 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
972 owner()->GetNextDeoptId());
973 ConnectBranchesTo(branches, join); 962 ConnectBranchesTo(branches, join);
974 return join; 963 return join;
975 } 964 }
976 965
977 966
978 BlockEntryInstr* TestGraphVisitor::CreateTrueSuccessor() const { 967 BlockEntryInstr* TestGraphVisitor::CreateTrueSuccessor() const {
979 return CreateSuccessorFor(true_successor_addresses_); 968 return CreateSuccessorFor(true_successor_addresses_);
980 } 969 }
981 970
982 971
983 BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const { 972 BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const {
984 return CreateSuccessorFor(false_successor_addresses_); 973 return CreateSuccessorFor(false_successor_addresses_);
985 } 974 }
986 975
987 976
988 void TestGraphVisitor::ReturnValue(Value* value) { 977 void TestGraphVisitor::ReturnValue(Value* value) {
989 Isolate* isolate = Isolate::Current(); 978 Isolate* isolate = Isolate::Current();
990 if (isolate->type_checks() || isolate->asserts()) { 979 if (isolate->type_checks() || isolate->asserts()) {
991 value = Bind(new (Z) AssertBooleanInstr(condition_token_pos(), value, 980 value = Bind(new (Z) AssertBooleanInstr(condition_token_pos(), value));
992 owner()->GetNextDeoptId()));
993 } 981 }
994 Value* constant_true = Bind(new (Z) ConstantInstr(Bool::True())); 982 Value* constant_true = Bind(new (Z) ConstantInstr(Bool::True()));
995 StrictCompareInstr* comp = new (Z) StrictCompareInstr( 983 StrictCompareInstr* comp = new (Z) StrictCompareInstr(
996 condition_token_pos(), Token::kEQ_STRICT, value, constant_true, false, 984 condition_token_pos(), Token::kEQ_STRICT, value, constant_true,
997 owner()->GetNextDeoptId()); // No number check. 985 false); // No number check.
998 BranchInstr* branch = new (Z) BranchInstr(comp, owner()->GetNextDeoptId()); 986 BranchInstr* branch = new (Z) BranchInstr(comp);
999 AddInstruction(branch); 987 AddInstruction(branch);
1000 CloseFragment(); 988 CloseFragment();
1001 989
1002 true_successor_addresses_.Add(branch->true_successor_address()); 990 true_successor_addresses_.Add(branch->true_successor_address());
1003 false_successor_addresses_.Add(branch->false_successor_address()); 991 false_successor_addresses_.Add(branch->false_successor_address());
1004 } 992 }
1005 993
1006 994
1007 void TestGraphVisitor::MergeBranchWithStrictCompare(StrictCompareInstr* comp) { 995 void TestGraphVisitor::MergeBranchWithStrictCompare(StrictCompareInstr* comp) {
1008 BranchInstr* branch = new (Z) BranchInstr(comp, owner()->GetNextDeoptId()); 996 BranchInstr* branch = new (Z) BranchInstr(comp);
1009 AddInstruction(branch); 997 AddInstruction(branch);
1010 CloseFragment(); 998 CloseFragment();
1011 true_successor_addresses_.Add(branch->true_successor_address()); 999 true_successor_addresses_.Add(branch->true_successor_address());
1012 false_successor_addresses_.Add(branch->false_successor_address()); 1000 false_successor_addresses_.Add(branch->false_successor_address());
1013 } 1001 }
1014 1002
1015 1003
1016 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) { 1004 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) {
1017 ASSERT(!Isolate::Current()->type_checks()); 1005 ASSERT(!Isolate::Current()->type_checks());
1018 Value* constant_true = Bind(new (Z) ConstantInstr(Bool::True())); 1006 Value* constant_true = Bind(new (Z) ConstantInstr(Bool::True()));
1019 StrictCompareInstr* comp = new (Z) StrictCompareInstr( 1007 StrictCompareInstr* comp = new (Z) StrictCompareInstr(
1020 condition_token_pos(), Token::kNE_STRICT, neg->value(), constant_true, 1008 condition_token_pos(), Token::kNE_STRICT, neg->value(), constant_true,
1021 false, owner()->GetNextDeoptId()); // No number check. 1009 false); // No number check.
1022 BranchInstr* branch = new (Z) BranchInstr(comp, owner()->GetNextDeoptId()); 1010 BranchInstr* branch = new (Z) BranchInstr(comp);
1023 AddInstruction(branch); 1011 AddInstruction(branch);
1024 CloseFragment(); 1012 CloseFragment();
1025 true_successor_addresses_.Add(branch->true_successor_address()); 1013 true_successor_addresses_.Add(branch->true_successor_address());
1026 false_successor_addresses_.Add(branch->false_successor_address()); 1014 false_successor_addresses_.Add(branch->false_successor_address());
1027 } 1015 }
1028 1016
1029 1017
1030 void TestGraphVisitor::ReturnDefinition(Definition* definition) { 1018 void TestGraphVisitor::ReturnDefinition(Definition* definition) {
1031 StrictCompareInstr* comp = definition->AsStrictCompare(); 1019 StrictCompareInstr* comp = definition->AsStrictCompare();
1032 if (comp != NULL) { 1020 if (comp != NULL) {
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1146 1134
1147 if (FLAG_causal_async_stacks && 1135 if (FLAG_causal_async_stacks &&
1148 (function.IsAsyncClosure() || function.IsAsyncGenClosure())) { 1136 (function.IsAsyncClosure() || function.IsAsyncGenClosure())) {
1149 // We are returning from an asynchronous closure. Before we do that, be 1137 // We are returning from an asynchronous closure. Before we do that, be
1150 // sure to clear the thread's asynchronous stack trace. 1138 // sure to clear the thread's asynchronous stack trace.
1151 const Function& async_clear_thread_stack_trace = Function::ZoneHandle( 1139 const Function& async_clear_thread_stack_trace = Function::ZoneHandle(
1152 Z, isolate()->object_store()->async_clear_thread_stack_trace()); 1140 Z, isolate()->object_store()->async_clear_thread_stack_trace());
1153 ZoneGrowableArray<PushArgumentInstr*>* no_arguments = 1141 ZoneGrowableArray<PushArgumentInstr*>* no_arguments =
1154 new (Z) ZoneGrowableArray<PushArgumentInstr*>(0); 1142 new (Z) ZoneGrowableArray<PushArgumentInstr*>(0);
1155 const int kTypeArgsLen = 0; 1143 const int kTypeArgsLen = 0;
1156 StaticCallInstr* call_async_clear_thread_stack_trace = new (Z) 1144 StaticCallInstr* call_async_clear_thread_stack_trace =
1157 StaticCallInstr(node->token_pos().ToSynthetic(), 1145 new (Z) StaticCallInstr(node->token_pos().ToSynthetic(),
1158 async_clear_thread_stack_trace, kTypeArgsLen, 1146 async_clear_thread_stack_trace, kTypeArgsLen,
1159 Object::null_array(), no_arguments, 1147 Object::null_array(), no_arguments,
1160 owner()->ic_data_array(), owner()->GetNextDeoptId()); 1148 owner()->ic_data_array());
1161 Do(call_async_clear_thread_stack_trace); 1149 Do(call_async_clear_thread_stack_trace);
1162 } 1150 }
1163 1151
1164 // Async functions contain two types of return statements: 1152 // Async functions contain two types of return statements:
1165 // 1) Returns that should complete the completer once all finally blocks have 1153 // 1) Returns that should complete the completer once all finally blocks have
1166 // been inlined (call: :async_completer.complete(return_value)). These 1154 // been inlined (call: :async_completer.complete(return_value)). These
1167 // returns end up returning null in the end. 1155 // returns end up returning null in the end.
1168 // 2) "Continuation" returns that should not complete the completer but return 1156 // 2) "Continuation" returns that should not complete the completer but return
1169 // the value. 1157 // the value.
1170 // 1158 //
(...skipping 14 matching lines...) Expand all
1185 Value* returned_value = Bind(BuildLoadExprTemp(node->token_pos())); 1173 Value* returned_value = Bind(BuildLoadExprTemp(node->token_pos()));
1186 arguments->Add(PushArgument(returned_value)); 1174 arguments->Add(PushArgument(returned_value));
1187 // Call a helper function to complete the completer. The debugger 1175 // Call a helper function to complete the completer. The debugger
1188 // uses the helper function to know when to step-out. 1176 // uses the helper function to know when to step-out.
1189 const Function& complete_on_async_return = Function::ZoneHandle( 1177 const Function& complete_on_async_return = Function::ZoneHandle(
1190 Z, isolate()->object_store()->complete_on_async_return()); 1178 Z, isolate()->object_store()->complete_on_async_return());
1191 ASSERT(!complete_on_async_return.IsNull()); 1179 ASSERT(!complete_on_async_return.IsNull());
1192 const int kTypeArgsLen = 0; 1180 const int kTypeArgsLen = 0;
1193 StaticCallInstr* call = new (Z) StaticCallInstr( 1181 StaticCallInstr* call = new (Z) StaticCallInstr(
1194 node->token_pos().ToSynthetic(), complete_on_async_return, kTypeArgsLen, 1182 node->token_pos().ToSynthetic(), complete_on_async_return, kTypeArgsLen,
1195 Object::null_array(), arguments, owner()->ic_data_array(), 1183 Object::null_array(), arguments, owner()->ic_data_array());
1196 owner()->GetNextDeoptId());
1197 Do(call); 1184 Do(call);
1198 1185
1199 // Rebind the return value for the actual return call to be null. 1186 // Rebind the return value for the actual return call to be null.
1200 return_value = BuildNullValue(node->token_pos()); 1187 return_value = BuildNullValue(node->token_pos());
1201 } 1188 }
1202 1189
1203 intptr_t current_context_level = owner()->context_level(); 1190 intptr_t current_context_level = owner()->context_level();
1204 ASSERT(current_context_level >= 0); 1191 ASSERT(current_context_level >= 0);
1205 if (HasContextScope()) { 1192 if (HasContextScope()) {
1206 UnchainContexts(current_context_level); 1193 UnchainContexts(current_context_level);
1207 } 1194 }
1208 1195
1209 AddReturnExit(node->token_pos(), return_value); 1196 AddReturnExit(node->token_pos(), return_value);
1210 1197
1211 if ((function.IsAsyncClosure() || function.IsSyncGenClosure() || 1198 if ((function.IsAsyncClosure() || function.IsSyncGenClosure() ||
1212 function.IsAsyncGenClosure()) && 1199 function.IsAsyncGenClosure()) &&
1213 (node->return_type() == ReturnNode::kContinuationTarget)) { 1200 (node->return_type() == ReturnNode::kContinuationTarget)) {
1214 JoinEntryInstr* const join = 1201 JoinEntryInstr* const join = new (Z)
1215 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(), 1202 JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
1216 owner()->GetNextDeoptId());
1217 owner()->await_joins()->Add(join); 1203 owner()->await_joins()->Add(join);
1218 exit_ = join; 1204 exit_ = join;
1219 } 1205 }
1220 } 1206 }
1221 1207
1222 1208
1223 // <Expression> ::= Literal { literal: Instance } 1209 // <Expression> ::= Literal { literal: Instance }
1224 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) { 1210 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) {
1225 ReturnDefinition(new (Z) ConstantInstr(node->literal(), node->token_pos())); 1211 ReturnDefinition(new (Z) ConstantInstr(node->literal(), node->token_pos()));
1226 } 1212 }
(...skipping 22 matching lines...) Expand all
1249 } else { 1235 } else {
1250 instantiator_type_arguments = BuildInstantiatorTypeArguments(token_pos); 1236 instantiator_type_arguments = BuildInstantiatorTypeArguments(token_pos);
1251 } 1237 }
1252 Value* function_type_arguments = NULL; 1238 Value* function_type_arguments = NULL;
1253 if (type.IsInstantiated(kFunctions)) { 1239 if (type.IsInstantiated(kFunctions)) {
1254 function_type_arguments = BuildNullValue(token_pos); 1240 function_type_arguments = BuildNullValue(token_pos);
1255 } else { 1241 } else {
1256 function_type_arguments = BuildFunctionTypeArguments(token_pos); 1242 function_type_arguments = BuildFunctionTypeArguments(token_pos);
1257 } 1243 }
1258 ReturnDefinition(new (Z) InstantiateTypeInstr( 1244 ReturnDefinition(new (Z) InstantiateTypeInstr(
1259 token_pos, type, instantiator_type_arguments, function_type_arguments, 1245 token_pos, type, instantiator_type_arguments, function_type_arguments));
1260 owner()->GetNextDeoptId()));
1261 } 1246 }
1262 1247
1263 1248
1264 // Returns true if the type check can be skipped, for example, if the 1249 // Returns true if the type check can be skipped, for example, if the
1265 // destination type is dynamic or if the compile type of the value is a subtype 1250 // destination type is dynamic or if the compile type of the value is a subtype
1266 // of the destination type. 1251 // of the destination type.
1267 bool EffectGraphVisitor::CanSkipTypeCheck(TokenPosition token_pos, 1252 bool EffectGraphVisitor::CanSkipTypeCheck(TokenPosition token_pos,
1268 Value* value, 1253 Value* value,
1269 const AbstractType& dst_type, 1254 const AbstractType& dst_type,
1270 const String& dst_name) { 1255 const String& dst_name) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1340 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { 1325 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
1341 // See ValueGraphVisitor::VisitBinaryOpNode. 1326 // See ValueGraphVisitor::VisitBinaryOpNode.
1342 TestGraphVisitor for_left(owner(), node->left()->token_pos()); 1327 TestGraphVisitor for_left(owner(), node->left()->token_pos());
1343 node->left()->Visit(&for_left); 1328 node->left()->Visit(&for_left);
1344 EffectGraphVisitor empty(owner()); 1329 EffectGraphVisitor empty(owner());
1345 Isolate* isolate = Isolate::Current(); 1330 Isolate* isolate = Isolate::Current();
1346 if (isolate->type_checks() || isolate->asserts()) { 1331 if (isolate->type_checks() || isolate->asserts()) {
1347 ValueGraphVisitor for_right(owner()); 1332 ValueGraphVisitor for_right(owner());
1348 node->right()->Visit(&for_right); 1333 node->right()->Visit(&for_right);
1349 Value* right_value = for_right.value(); 1334 Value* right_value = for_right.value();
1350 for_right.Do(new (Z) AssertBooleanInstr( 1335 for_right.Do(
1351 node->right()->token_pos(), right_value, owner()->GetNextDeoptId())); 1336 new (Z) AssertBooleanInstr(node->right()->token_pos(), right_value));
1352 if (node->kind() == Token::kAND) { 1337 if (node->kind() == Token::kAND) {
1353 Join(for_left, for_right, empty); 1338 Join(for_left, for_right, empty);
1354 } else { 1339 } else {
1355 Join(for_left, empty, for_right); 1340 Join(for_left, empty, for_right);
1356 } 1341 }
1357 } else { 1342 } else {
1358 EffectGraphVisitor for_right(owner()); 1343 EffectGraphVisitor for_right(owner());
1359 node->right()->Visit(&for_right); 1344 node->right()->Visit(&for_right);
1360 if (node->kind() == Token::kAND) { 1345 if (node->kind() == Token::kAND) {
1361 Join(for_left, for_right, empty); 1346 Join(for_left, for_right, empty);
(...skipping 14 matching lines...) Expand all
1376 Append(for_right_value); 1361 Append(for_right_value);
1377 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); 1362 PushArgumentInstr* push_right = PushArgument(for_right_value.value());
1378 1363
1379 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1364 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1380 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2); 1365 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
1381 arguments->Add(push_left); 1366 arguments->Add(push_left);
1382 arguments->Add(push_right); 1367 arguments->Add(push_right);
1383 const String& name = Symbols::Token(node->kind()); 1368 const String& name = Symbols::Token(node->kind());
1384 const intptr_t kTypeArgsLen = 0; 1369 const intptr_t kTypeArgsLen = 0;
1385 const intptr_t kNumArgsChecked = 2; 1370 const intptr_t kNumArgsChecked = 2;
1386 InstanceCallInstr* call = new (Z) 1371 InstanceCallInstr* call = new (Z) InstanceCallInstr(
1387 InstanceCallInstr(node->token_pos(), name, node->kind(), arguments, 1372 node->token_pos(), name, node->kind(), arguments, kTypeArgsLen,
1388 kTypeArgsLen, Object::null_array(), kNumArgsChecked, 1373 Object::null_array(), kNumArgsChecked, owner()->ic_data_array());
1389 owner()->ic_data_array(), owner()->GetNextDeoptId());
1390 ReturnDefinition(call); 1374 ReturnDefinition(call);
1391 } 1375 }
1392 1376
1393 1377
1394 // Special handling for AND/OR. 1378 // Special handling for AND/OR.
1395 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { 1379 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
1396 // Operators "&&" and "||" cannot be overloaded therefore do not call 1380 // Operators "&&" and "||" cannot be overloaded therefore do not call
1397 // operator. 1381 // operator.
1398 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { 1382 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
1399 // Implement short-circuit logic: do not evaluate right if evaluation 1383 // Implement short-circuit logic: do not evaluate right if evaluation
1400 // of left is sufficient. 1384 // of left is sufficient.
1401 // AND: left ? right === true : false; 1385 // AND: left ? right === true : false;
1402 // OR: left ? true : right === true; 1386 // OR: left ? true : right === true;
1403 1387
1404 TestGraphVisitor for_test(owner(), node->left()->token_pos()); 1388 TestGraphVisitor for_test(owner(), node->left()->token_pos());
1405 node->left()->Visit(&for_test); 1389 node->left()->Visit(&for_test);
1406 1390
1407 ValueGraphVisitor for_right(owner()); 1391 ValueGraphVisitor for_right(owner());
1408 node->right()->Visit(&for_right); 1392 node->right()->Visit(&for_right);
1409 Value* right_value = for_right.value(); 1393 Value* right_value = for_right.value();
1410 Isolate* isolate = Isolate::Current(); 1394 Isolate* isolate = Isolate::Current();
1411 if (isolate->type_checks() || isolate->asserts()) { 1395 if (isolate->type_checks() || isolate->asserts()) {
1412 right_value = for_right.Bind(new (Z) AssertBooleanInstr( 1396 right_value = for_right.Bind(
1413 node->right()->token_pos(), right_value, owner()->GetNextDeoptId())); 1397 new (Z) AssertBooleanInstr(node->right()->token_pos(), right_value));
1414 } 1398 }
1415 Value* constant_true = for_right.Bind(new (Z) ConstantInstr(Bool::True())); 1399 Value* constant_true = for_right.Bind(new (Z) ConstantInstr(Bool::True()));
1416 Value* compare = for_right.Bind(new (Z) StrictCompareInstr( 1400 Value* compare = for_right.Bind(new (Z) StrictCompareInstr(
1417 node->token_pos(), Token::kEQ_STRICT, right_value, constant_true, false, 1401 node->token_pos(), Token::kEQ_STRICT, right_value, constant_true,
1418 owner()->GetNextDeoptId())); // No number check. 1402 false)); // No number check.
1419 for_right.Do(BuildStoreExprTemp(compare, node->token_pos())); 1403 for_right.Do(BuildStoreExprTemp(compare, node->token_pos()));
1420 1404
1421 if (node->kind() == Token::kAND) { 1405 if (node->kind() == Token::kAND) {
1422 ValueGraphVisitor for_false(owner()); 1406 ValueGraphVisitor for_false(owner());
1423 Value* constant_false = 1407 Value* constant_false =
1424 for_false.Bind(new (Z) ConstantInstr(Bool::False())); 1408 for_false.Bind(new (Z) ConstantInstr(Bool::False()));
1425 for_false.Do(BuildStoreExprTemp(constant_false, node->token_pos())); 1409 for_false.Do(BuildStoreExprTemp(constant_false, node->token_pos()));
1426 Join(for_test, for_right, for_false); 1410 Join(for_test, for_right, for_false);
1427 } else { 1411 } else {
1428 ASSERT(node->kind() == Token::kOR); 1412 ASSERT(node->kind() == Token::kOR);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1544 arguments->Add(push_left); 1528 arguments->Add(push_left);
1545 Value* type_const = Bind(new (Z) ConstantInstr(type)); 1529 Value* type_const = Bind(new (Z) ConstantInstr(type));
1546 arguments->Add(PushArgument(type_const)); 1530 arguments->Add(PushArgument(type_const));
1547 const intptr_t kTypeArgsLen = 0; 1531 const intptr_t kTypeArgsLen = 0;
1548 const intptr_t kNumArgsChecked = 2; 1532 const intptr_t kNumArgsChecked = 2;
1549 Definition* result = new (Z) InstanceCallInstr( 1533 Definition* result = new (Z) InstanceCallInstr(
1550 node->token_pos(), 1534 node->token_pos(),
1551 Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()), node->kind(), 1535 Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()), node->kind(),
1552 arguments, kTypeArgsLen, 1536 arguments, kTypeArgsLen,
1553 Object::null_array(), // No argument names. 1537 Object::null_array(), // No argument names.
1554 kNumArgsChecked, owner()->ic_data_array(), owner()->GetNextDeoptId()); 1538 kNumArgsChecked, owner()->ic_data_array());
1555 if (negate_result) { 1539 if (negate_result) {
1556 result = new (Z) BooleanNegateInstr(Bind(result)); 1540 result = new (Z) BooleanNegateInstr(Bind(result));
1557 } 1541 }
1558 ReturnDefinition(result); 1542 ReturnDefinition(result);
1559 return; 1543 return;
1560 } 1544 }
1561 1545
1562 PushArgumentInstr* push_instantiator_type_args = 1546 PushArgumentInstr* push_instantiator_type_args =
1563 PushInstantiatorTypeArguments(type, node->token_pos()); 1547 PushInstantiatorTypeArguments(type, node->token_pos());
1564 PushArgumentInstr* push_function_type_args = 1548 PushArgumentInstr* push_function_type_args =
1565 PushFunctionTypeArguments(type, node->token_pos()); 1549 PushFunctionTypeArguments(type, node->token_pos());
1566 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1550 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1567 new (Z) ZoneGrowableArray<PushArgumentInstr*>(4); 1551 new (Z) ZoneGrowableArray<PushArgumentInstr*>(4);
1568 arguments->Add(push_left); 1552 arguments->Add(push_left);
1569 arguments->Add(push_instantiator_type_args); 1553 arguments->Add(push_instantiator_type_args);
1570 arguments->Add(push_function_type_args); 1554 arguments->Add(push_function_type_args);
1571 Value* type_const = Bind(new (Z) ConstantInstr(type)); 1555 Value* type_const = Bind(new (Z) ConstantInstr(type));
1572 arguments->Add(PushArgument(type_const)); 1556 arguments->Add(PushArgument(type_const));
1573 const intptr_t kTypeArgsLen = 0; 1557 const intptr_t kTypeArgsLen = 0;
1574 const intptr_t kNumArgsChecked = 1; 1558 const intptr_t kNumArgsChecked = 1;
1575 Definition* result = new (Z) InstanceCallInstr( 1559 Definition* result = new (Z) InstanceCallInstr(
1576 node->token_pos(), Library::PrivateCoreLibName(Symbols::_instanceOf()), 1560 node->token_pos(), Library::PrivateCoreLibName(Symbols::_instanceOf()),
1577 node->kind(), arguments, kTypeArgsLen, 1561 node->kind(), arguments, kTypeArgsLen,
1578 Object::null_array(), // No argument names. 1562 Object::null_array(), // No argument names.
1579 kNumArgsChecked, owner()->ic_data_array(), owner()->GetNextDeoptId()); 1563 kNumArgsChecked, owner()->ic_data_array());
1580 if (negate_result) { 1564 if (negate_result) {
1581 result = new (Z) BooleanNegateInstr(Bind(result)); 1565 result = new (Z) BooleanNegateInstr(Bind(result));
1582 } 1566 }
1583 ReturnDefinition(result); 1567 ReturnDefinition(result);
1584 } 1568 }
1585 1569
1586 1570
1587 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { 1571 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) {
1588 ASSERT(Token::IsTypeCastOperator(node->kind())); 1572 ASSERT(Token::IsTypeCastOperator(node->kind()));
1589 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); 1573 ASSERT(!node->right()->AsTypeNode()->type().IsNull());
(...skipping 18 matching lines...) Expand all
1608 arguments->Add(push_instantiator_type_args); 1592 arguments->Add(push_instantiator_type_args);
1609 arguments->Add(push_function_type_args); 1593 arguments->Add(push_function_type_args);
1610 Value* type_arg = Bind(new (Z) ConstantInstr(type)); 1594 Value* type_arg = Bind(new (Z) ConstantInstr(type));
1611 arguments->Add(PushArgument(type_arg)); 1595 arguments->Add(PushArgument(type_arg));
1612 const int kTypeArgsLen = 0; 1596 const int kTypeArgsLen = 0;
1613 const intptr_t kNumArgsChecked = 1; 1597 const intptr_t kNumArgsChecked = 1;
1614 InstanceCallInstr* call = new (Z) InstanceCallInstr( 1598 InstanceCallInstr* call = new (Z) InstanceCallInstr(
1615 node->token_pos(), Library::PrivateCoreLibName(Symbols::_as()), 1599 node->token_pos(), Library::PrivateCoreLibName(Symbols::_as()),
1616 node->kind(), arguments, kTypeArgsLen, 1600 node->kind(), arguments, kTypeArgsLen,
1617 Object::null_array(), // No argument names. 1601 Object::null_array(), // No argument names.
1618 kNumArgsChecked, owner()->ic_data_array(), owner()->GetNextDeoptId()); 1602 kNumArgsChecked, owner()->ic_data_array());
1619 ReturnDefinition(call); 1603 ReturnDefinition(call);
1620 } 1604 }
1621 1605
1622 1606
1623 StrictCompareInstr* EffectGraphVisitor::BuildStrictCompare( 1607 StrictCompareInstr* EffectGraphVisitor::BuildStrictCompare(
1624 AstNode* left, 1608 AstNode* left,
1625 AstNode* right, 1609 AstNode* right,
1626 Token::Kind kind, 1610 Token::Kind kind,
1627 TokenPosition token_pos) { 1611 TokenPosition token_pos) {
1628 ValueGraphVisitor for_left_value(owner()); 1612 ValueGraphVisitor for_left_value(owner());
1629 left->Visit(&for_left_value); 1613 left->Visit(&for_left_value);
1630 Append(for_left_value); 1614 Append(for_left_value);
1631 ValueGraphVisitor for_right_value(owner()); 1615 ValueGraphVisitor for_right_value(owner());
1632 right->Visit(&for_right_value); 1616 right->Visit(&for_right_value);
1633 Append(for_right_value); 1617 Append(for_right_value);
1634 StrictCompareInstr* comp = new (Z) StrictCompareInstr( 1618 StrictCompareInstr* comp = new (Z) StrictCompareInstr(
1635 token_pos, kind, for_left_value.value(), for_right_value.value(), true, 1619 token_pos, kind, for_left_value.value(), for_right_value.value(),
1636 owner()->GetNextDeoptId()); // Number check. 1620 true); // Number check.
1637 return comp; 1621 return comp;
1638 } 1622 }
1639 1623
1640 1624
1641 // <Expression> :: Comparison { kind: Token::Kind 1625 // <Expression> :: Comparison { kind: Token::Kind
1642 // left: <Expression> 1626 // left: <Expression>
1643 // right: <Expression> } 1627 // right: <Expression> }
1644 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { 1628 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) {
1645 if (Token::IsTypeTestOperator(node->kind())) { 1629 if (Token::IsTypeTestOperator(node->kind())) {
1646 BuildTypeTest(node); 1630 BuildTypeTest(node);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1682 arguments->Add(push_left); 1666 arguments->Add(push_left);
1683 1667
1684 ValueGraphVisitor for_right_value(owner()); 1668 ValueGraphVisitor for_right_value(owner());
1685 node->right()->Visit(&for_right_value); 1669 node->right()->Visit(&for_right_value);
1686 Append(for_right_value); 1670 Append(for_right_value);
1687 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); 1671 PushArgumentInstr* push_right = PushArgument(for_right_value.value());
1688 arguments->Add(push_right); 1672 arguments->Add(push_right);
1689 1673
1690 const intptr_t kTypeArgsLen = 0; 1674 const intptr_t kTypeArgsLen = 0;
1691 const intptr_t kNumArgsChecked = 2; 1675 const intptr_t kNumArgsChecked = 2;
1692 Definition* result = new (Z) InstanceCallInstr( 1676 Definition* result = new (Z)
1693 node->token_pos(), Symbols::EqualOperator(), 1677 InstanceCallInstr(node->token_pos(), Symbols::EqualOperator(),
1694 Token::kEQ, // Result is negated later for kNE. 1678 Token::kEQ, // Result is negated later for kNE.
1695 arguments, kTypeArgsLen, Object::null_array(), kNumArgsChecked, 1679 arguments, kTypeArgsLen, Object::null_array(),
1696 owner()->ic_data_array(), owner()->GetNextDeoptId()); 1680 kNumArgsChecked, owner()->ic_data_array());
1697 if (node->kind() == Token::kNE) { 1681 if (node->kind() == Token::kNE) {
1698 Isolate* isolate = Isolate::Current(); 1682 Isolate* isolate = Isolate::Current();
1699 if (isolate->type_checks() || isolate->asserts()) { 1683 if (isolate->type_checks() || isolate->asserts()) {
1700 Value* value = Bind(result); 1684 Value* value = Bind(result);
1701 result = new (Z) AssertBooleanInstr(node->token_pos(), value, 1685 result = new (Z) AssertBooleanInstr(node->token_pos(), value);
1702 owner()->GetNextDeoptId());
1703 } 1686 }
1704 Value* value = Bind(result); 1687 Value* value = Bind(result);
1705 result = new (Z) BooleanNegateInstr(value); 1688 result = new (Z) BooleanNegateInstr(value);
1706 } 1689 }
1707 ReturnDefinition(result); 1690 ReturnDefinition(result);
1708 return; 1691 return;
1709 } 1692 }
1710 1693
1711 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1694 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1712 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2); 1695 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
1713 1696
1714 ValueGraphVisitor for_left_value(owner()); 1697 ValueGraphVisitor for_left_value(owner());
1715 node->left()->Visit(&for_left_value); 1698 node->left()->Visit(&for_left_value);
1716 Append(for_left_value); 1699 Append(for_left_value);
1717 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 1700 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
1718 arguments->Add(push_left); 1701 arguments->Add(push_left);
1719 1702
1720 ValueGraphVisitor for_right_value(owner()); 1703 ValueGraphVisitor for_right_value(owner());
1721 node->right()->Visit(&for_right_value); 1704 node->right()->Visit(&for_right_value);
1722 Append(for_right_value); 1705 Append(for_right_value);
1723 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); 1706 PushArgumentInstr* push_right = PushArgument(for_right_value.value());
1724 arguments->Add(push_right); 1707 arguments->Add(push_right);
1725 1708
1726 ASSERT(Token::IsRelationalOperator(node->kind())); 1709 ASSERT(Token::IsRelationalOperator(node->kind()));
1727 const intptr_t kTypeArgsLen = 0; 1710 const intptr_t kTypeArgsLen = 0;
1728 InstanceCallInstr* comp = new (Z) InstanceCallInstr( 1711 InstanceCallInstr* comp = new (Z) InstanceCallInstr(
1729 node->token_pos(), Symbols::Token(node->kind()), node->kind(), arguments, 1712 node->token_pos(), Symbols::Token(node->kind()), node->kind(), arguments,
1730 kTypeArgsLen, Object::null_array(), 2, owner()->ic_data_array(), 1713 kTypeArgsLen, Object::null_array(), 2, owner()->ic_data_array());
1731 owner()->GetNextDeoptId());
1732 ReturnDefinition(comp); 1714 ReturnDefinition(comp);
1733 } 1715 }
1734 1716
1735 1717
1736 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { 1718 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
1737 // "!" cannot be overloaded, therefore do not call operator. 1719 // "!" cannot be overloaded, therefore do not call operator.
1738 if (node->kind() == Token::kNOT) { 1720 if (node->kind() == Token::kNOT) {
1739 ValueGraphVisitor for_value(owner()); 1721 ValueGraphVisitor for_value(owner());
1740 node->operand()->Visit(&for_value); 1722 node->operand()->Visit(&for_value);
1741 Append(for_value); 1723 Append(for_value);
1742 Value* value = for_value.value(); 1724 Value* value = for_value.value();
1743 Isolate* isolate = Isolate::Current(); 1725 Isolate* isolate = Isolate::Current();
1744 if (isolate->type_checks() || isolate->asserts()) { 1726 if (isolate->type_checks() || isolate->asserts()) {
1745 value = Bind(new (Z) AssertBooleanInstr( 1727 value =
1746 node->operand()->token_pos(), value, owner()->GetNextDeoptId())); 1728 Bind(new (Z) AssertBooleanInstr(node->operand()->token_pos(), value));
1747 } 1729 }
1748 BooleanNegateInstr* negate = new (Z) BooleanNegateInstr(value); 1730 BooleanNegateInstr* negate = new (Z) BooleanNegateInstr(value);
1749 ReturnDefinition(negate); 1731 ReturnDefinition(negate);
1750 return; 1732 return;
1751 } 1733 }
1752 1734
1753 ValueGraphVisitor for_value(owner()); 1735 ValueGraphVisitor for_value(owner());
1754 node->operand()->Visit(&for_value); 1736 node->operand()->Visit(&for_value);
1755 Append(for_value); 1737 Append(for_value);
1756 PushArgumentInstr* push_value = PushArgument(for_value.value()); 1738 PushArgumentInstr* push_value = PushArgument(for_value.value());
1757 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1739 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1758 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1); 1740 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1);
1759 arguments->Add(push_value); 1741 arguments->Add(push_value);
1760 const intptr_t kTypeArgsLen = 0; 1742 const intptr_t kTypeArgsLen = 0;
1761 InstanceCallInstr* call = new (Z) InstanceCallInstr( 1743 InstanceCallInstr* call = new (Z) InstanceCallInstr(
1762 node->token_pos(), Symbols::Token(node->kind()), node->kind(), arguments, 1744 node->token_pos(), Symbols::Token(node->kind()), node->kind(), arguments,
1763 kTypeArgsLen, Object::null_array(), 1, owner()->ic_data_array(), 1745 kTypeArgsLen, Object::null_array(), 1, owner()->ic_data_array());
1764 owner()->GetNextDeoptId());
1765 ReturnDefinition(call); 1746 ReturnDefinition(call);
1766 } 1747 }
1767 1748
1768 1749
1769 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { 1750 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
1770 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); 1751 TestGraphVisitor for_test(owner(), node->condition()->token_pos());
1771 node->condition()->Visit(&for_test); 1752 node->condition()->Visit(&for_test);
1772 1753
1773 // Translate the subexpressions for their effects. 1754 // Translate the subexpressions for their effects.
1774 EffectGraphVisitor for_true(owner()); 1755 EffectGraphVisitor for_true(owner());
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1852 // 1833 //
1853 // Note: The specification of switch/case is under discussion and may change 1834 // Note: The specification of switch/case is under discussion and may change
1854 // drastically. 1835 // drastically.
1855 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { 1836 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) {
1856 const intptr_t len = node->case_expressions()->length(); 1837 const intptr_t len = node->case_expressions()->length();
1857 // Create case statements instructions. 1838 // Create case statements instructions.
1858 EffectGraphVisitor for_case_statements(owner()); 1839 EffectGraphVisitor for_case_statements(owner());
1859 // Compute the start of the statements fragment. 1840 // Compute the start of the statements fragment.
1860 JoinEntryInstr* statement_start = NULL; 1841 JoinEntryInstr* statement_start = NULL;
1861 if (node->label() == NULL) { 1842 if (node->label() == NULL) {
1862 statement_start = 1843 statement_start = new (Z)
1863 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(), 1844 JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
1864 owner()->GetNextDeoptId());
1865 } else { 1845 } else {
1866 // The case nodes are nested inside a SequenceNode that is the body of a 1846 // The case nodes are nested inside a SequenceNode that is the body of a
1867 // SwitchNode. The SwitchNode on the nesting stack contains the 1847 // SwitchNode. The SwitchNode on the nesting stack contains the
1868 // continue labels for all the case clauses. 1848 // continue labels for all the case clauses.
1869 statement_start = 1849 statement_start =
1870 owner()->nesting_stack()->outer()->ContinueTargetFor(node->label()); 1850 owner()->nesting_stack()->outer()->ContinueTargetFor(node->label());
1871 } 1851 }
1872 ASSERT(statement_start != NULL); 1852 ASSERT(statement_start != NULL);
1873 node->statements()->Visit(&for_case_statements); 1853 node->statements()->Visit(&for_case_statements);
1874 Instruction* statement_exit = 1854 Instruction* statement_exit =
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1906 // node contains default. 1886 // node contains default.
1907 if (len > 0) { 1887 if (len > 0) {
1908 ASSERT(next_target != NULL); 1888 ASSERT(next_target != NULL);
1909 if (node->contains_default()) { 1889 if (node->contains_default()) {
1910 // True and false go to statement start. 1890 // True and false go to statement start.
1911 next_target->Goto(statement_start); 1891 next_target->Goto(statement_start);
1912 exit_instruction = statement_exit; 1892 exit_instruction = statement_exit;
1913 } else { 1893 } else {
1914 if (statement_exit != NULL) { 1894 if (statement_exit != NULL) {
1915 JoinEntryInstr* join = new (Z) 1895 JoinEntryInstr* join = new (Z)
1916 JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(), 1896 JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
1917 owner()->GetNextDeoptId());
1918 statement_exit->Goto(join); 1897 statement_exit->Goto(join);
1919 next_target->Goto(join); 1898 next_target->Goto(join);
1920 exit_instruction = join; 1899 exit_instruction = join;
1921 } else { 1900 } else {
1922 exit_instruction = next_target; 1901 exit_instruction = next_target;
1923 } 1902 }
1924 } 1903 }
1925 } else { 1904 } else {
1926 // A CaseNode without case expressions must contain default. 1905 // A CaseNode without case expressions must contain default.
1927 ASSERT(node->contains_default()); 1906 ASSERT(node->contains_default());
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1990 // Traverse the body first in order to generate continue and break labels. 1969 // Traverse the body first in order to generate continue and break labels.
1991 EffectGraphVisitor for_body(owner()); 1970 EffectGraphVisitor for_body(owner());
1992 node->body()->Visit(&for_body); 1971 node->body()->Visit(&for_body);
1993 1972
1994 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); 1973 TestGraphVisitor for_test(owner(), node->condition()->token_pos());
1995 node->condition()->Visit(&for_test); 1974 node->condition()->Visit(&for_test);
1996 ASSERT(is_open()); 1975 ASSERT(is_open());
1997 1976
1998 // Tie do-while loop (test is after the body). 1977 // Tie do-while loop (test is after the body).
1999 JoinEntryInstr* body_entry_join = 1978 JoinEntryInstr* body_entry_join =
2000 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(), 1979 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
2001 owner()->GetNextDeoptId());
2002 Goto(body_entry_join); 1980 Goto(body_entry_join);
2003 Instruction* body_exit = AppendFragment(body_entry_join, for_body); 1981 Instruction* body_exit = AppendFragment(body_entry_join, for_body);
2004 1982
2005 JoinEntryInstr* join = nested_loop.continue_target(); 1983 JoinEntryInstr* join = nested_loop.continue_target();
2006 if ((body_exit != NULL) || (join != NULL)) { 1984 if ((body_exit != NULL) || (join != NULL)) {
2007 if (join == NULL) { 1985 if (join == NULL) {
2008 join = new (Z) 1986 join = new (Z)
2009 JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(), 1987 JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
2010 owner()->GetNextDeoptId());
2011 } 1988 }
2012 CheckStackOverflowInstr* check = new (Z) CheckStackOverflowInstr( 1989 CheckStackOverflowInstr* check = new (Z)
2013 node->token_pos(), owner()->loop_depth(), owner()->GetNextDeoptId()); 1990 CheckStackOverflowInstr(node->token_pos(), owner()->loop_depth());
2014 join->LinkTo(check); 1991 join->LinkTo(check);
2015 check->LinkTo(for_test.entry()); 1992 check->LinkTo(for_test.entry());
2016 if (body_exit != NULL) { 1993 if (body_exit != NULL) {
2017 body_exit->Goto(join); 1994 body_exit->Goto(join);
2018 } 1995 }
2019 } 1996 }
2020 1997
2021 for_test.IfTrueGoto(body_entry_join); 1998 for_test.IfTrueGoto(body_entry_join);
2022 join = nested_loop.break_target(); 1999 join = nested_loop.break_target();
2023 if (join == NULL) { 2000 if (join == NULL) {
(...skipping 27 matching lines...) Expand all
2051 // Compose body to set any jump labels. 2028 // Compose body to set any jump labels.
2052 EffectGraphVisitor for_body(owner()); 2029 EffectGraphVisitor for_body(owner());
2053 node->body()->Visit(&for_body); 2030 node->body()->Visit(&for_body);
2054 2031
2055 EffectGraphVisitor for_increment(owner()); 2032 EffectGraphVisitor for_increment(owner());
2056 node->increment()->Visit(&for_increment); 2033 node->increment()->Visit(&for_increment);
2057 2034
2058 // Join the loop body and increment and then tie the loop. 2035 // Join the loop body and increment and then tie the loop.
2059 JoinEntryInstr* continue_join = nested_loop.continue_target(); 2036 JoinEntryInstr* continue_join = nested_loop.continue_target();
2060 if ((continue_join != NULL) || for_body.is_open()) { 2037 if ((continue_join != NULL) || for_body.is_open()) {
2061 JoinEntryInstr* loop_entry = 2038 JoinEntryInstr* loop_entry = new (Z)
2062 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(), 2039 JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
2063 owner()->GetNextDeoptId());
2064 if (continue_join != NULL) { 2040 if (continue_join != NULL) {
2065 if (for_body.is_open()) for_body.Goto(continue_join); 2041 if (for_body.is_open()) for_body.Goto(continue_join);
2066 Instruction* current = AppendFragment(continue_join, for_increment); 2042 Instruction* current = AppendFragment(continue_join, for_increment);
2067 current->Goto(loop_entry); 2043 current->Goto(loop_entry);
2068 } else { 2044 } else {
2069 for_body.Append(for_increment); 2045 for_body.Append(for_increment);
2070 for_body.Goto(loop_entry); 2046 for_body.Goto(loop_entry);
2071 } 2047 }
2072 Goto(loop_entry); 2048 Goto(loop_entry);
2073 exit_ = loop_entry; 2049 exit_ = loop_entry;
2074 // Note: the stack overflow check happens on the back branch that jumps 2050 // Note: the stack overflow check happens on the back branch that jumps
2075 // to the increment instruction. The token position for the overflow 2051 // to the increment instruction. The token position for the overflow
2076 // check must match the position of the increment expression, so that 2052 // check must match the position of the increment expression, so that
2077 // the context level (if any) matches the that of the increment 2053 // the context level (if any) matches the that of the increment
2078 // expression. 2054 // expression.
2079 AddInstruction(new (Z) CheckStackOverflowInstr( 2055 AddInstruction(new (Z) CheckStackOverflowInstr(
2080 node->increment()->token_pos(), owner()->loop_depth(), 2056 node->increment()->token_pos(), owner()->loop_depth()));
2081 owner()->GetNextDeoptId()));
2082 } 2057 }
2083 2058
2084 if (node->condition() == NULL) { 2059 if (node->condition() == NULL) {
2085 // Endless loop, no test. 2060 // Endless loop, no test.
2086 Append(for_body); 2061 Append(for_body);
2087 exit_ = nested_loop.break_target(); // May be NULL. 2062 exit_ = nested_loop.break_target(); // May be NULL.
2088 } else { 2063 } else {
2089 EffectGraphVisitor for_test_preamble(owner()); 2064 EffectGraphVisitor for_test_preamble(owner());
2090 if (node->condition_preamble() != NULL) { 2065 if (node->condition_preamble() != NULL) {
2091 node->condition_preamble()->Visit(&for_test_preamble); 2066 node->condition_preamble()->Visit(&for_test_preamble);
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
2266 } 2241 }
2267 2242
2268 2243
2269 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { 2244 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) {
2270 const TypeArguments& type_args = 2245 const TypeArguments& type_args =
2271 TypeArguments::ZoneHandle(Z, node->type().arguments()); 2246 TypeArguments::ZoneHandle(Z, node->type().arguments());
2272 Value* element_type = 2247 Value* element_type =
2273 BuildInstantiatedTypeArguments(node->token_pos(), type_args); 2248 BuildInstantiatedTypeArguments(node->token_pos(), type_args);
2274 Value* num_elements = 2249 Value* num_elements =
2275 Bind(new (Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(node->length())))); 2250 Bind(new (Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(node->length()))));
2276 CreateArrayInstr* create = new (Z) CreateArrayInstr( 2251 CreateArrayInstr* create =
2277 node->token_pos(), element_type, num_elements, owner()->GetNextDeoptId()); 2252 new (Z) CreateArrayInstr(node->token_pos(), element_type, num_elements);
2278 Value* array_val = Bind(create); 2253 Value* array_val = Bind(create);
2279 2254
2280 { 2255 {
2281 LocalVariable* tmp_var = EnterTempLocalScope(array_val); 2256 LocalVariable* tmp_var = EnterTempLocalScope(array_val);
2282 const intptr_t class_id = kArrayCid; 2257 const intptr_t class_id = kArrayCid;
2283 const intptr_t deopt_id = Thread::kNoDeoptId; 2258 const intptr_t deopt_id = Thread::kNoDeoptId;
2284 for (int i = 0; i < node->length(); ++i) { 2259 for (int i = 0; i < node->length(); ++i) {
2285 Value* array = Bind(new (Z) LoadLocalInstr(*tmp_var, node->token_pos())); 2260 Value* array = Bind(new (Z) LoadLocalInstr(*tmp_var, node->token_pos()));
2286 Value* index = Bind(new (Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(i)), 2261 Value* index = Bind(new (Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(i)),
2287 node->token_pos())); 2262 node->token_pos()));
(...skipping 29 matching lines...) Expand all
2317 const int kTypeArgsLen = 0; 2292 const int kTypeArgsLen = 0;
2318 const int kNumberOfArguments = 1; 2293 const int kNumberOfArguments = 1;
2319 const Array& kNoArgumentNames = Object::null_array(); 2294 const Array& kNoArgumentNames = Object::null_array();
2320 const Class& cls = 2295 const Class& cls =
2321 Class::Handle(Library::LookupCoreClass(Symbols::StringBase())); 2296 Class::Handle(Library::LookupCoreClass(Symbols::StringBase()));
2322 ASSERT(!cls.IsNull()); 2297 ASSERT(!cls.IsNull());
2323 const Function& function = Function::ZoneHandle( 2298 const Function& function = Function::ZoneHandle(
2324 Z, Resolver::ResolveStatic( 2299 Z, Resolver::ResolveStatic(
2325 cls, Library::PrivateCoreLibName(Symbols::InterpolateSingle()), 2300 cls, Library::PrivateCoreLibName(Symbols::InterpolateSingle()),
2326 kTypeArgsLen, kNumberOfArguments, kNoArgumentNames)); 2301 kTypeArgsLen, kNumberOfArguments, kNoArgumentNames));
2327 StaticCallInstr* call = new (Z) StaticCallInstr( 2302 StaticCallInstr* call = new (Z)
2328 node->token_pos(), function, kTypeArgsLen, kNoArgumentNames, values, 2303 StaticCallInstr(node->token_pos(), function, kTypeArgsLen,
2329 owner()->ic_data_array(), owner()->GetNextDeoptId()); 2304 kNoArgumentNames, values, owner()->ic_data_array());
2330 ReturnDefinition(call); 2305 ReturnDefinition(call);
2331 return; 2306 return;
2332 } 2307 }
2333 arguments->Visit(&for_argument); 2308 arguments->Visit(&for_argument);
2334 Append(for_argument); 2309 Append(for_argument);
2335 StringInterpolateInstr* instr = new (Z) StringInterpolateInstr( 2310 StringInterpolateInstr* instr =
2336 for_argument.value(), node->token_pos(), owner()->GetNextDeoptId()); 2311 new (Z) StringInterpolateInstr(for_argument.value(), node->token_pos());
2337 ReturnDefinition(instr); 2312 ReturnDefinition(instr);
2338 } 2313 }
2339 2314
2340 2315
2341 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { 2316 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) {
2342 const Function& function = node->function(); 2317 const Function& function = node->function();
2343 if (function.IsImplicitStaticClosureFunction()) { 2318 if (function.IsImplicitStaticClosureFunction()) {
2344 const Instance& closure = 2319 const Instance& closure =
2345 Instance::ZoneHandle(Z, function.ImplicitStaticClosure()); 2320 Instance::ZoneHandle(Z, function.ImplicitStaticClosure());
2346 ReturnDefinition(new (Z) ConstantInstr(closure)); 2321 ReturnDefinition(new (Z) ConstantInstr(closure));
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
2548 BuildPushTypeArguments(*node->arguments(), arguments); 2523 BuildPushTypeArguments(*node->arguments(), arguments);
2549 ValueGraphVisitor for_receiver(owner()); 2524 ValueGraphVisitor for_receiver(owner());
2550 node->receiver()->Visit(&for_receiver); 2525 node->receiver()->Visit(&for_receiver);
2551 Append(for_receiver); 2526 Append(for_receiver);
2552 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); 2527 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
2553 arguments->Add(push_receiver); 2528 arguments->Add(push_receiver);
2554 BuildPushArguments(*node->arguments(), arguments); 2529 BuildPushArguments(*node->arguments(), arguments);
2555 InstanceCallInstr* call = new (Z) InstanceCallInstr( 2530 InstanceCallInstr* call = new (Z) InstanceCallInstr(
2556 node->token_pos(), node->function_name(), Token::kILLEGAL, arguments, 2531 node->token_pos(), node->function_name(), Token::kILLEGAL, arguments,
2557 node->arguments()->type_args_len(), node->arguments()->names(), 1, 2532 node->arguments()->type_args_len(), node->arguments()->names(), 1,
2558 owner()->ic_data_array(), owner()->GetNextDeoptId()); 2533 owner()->ic_data_array());
2559 ReturnDefinition(call); 2534 ReturnDefinition(call);
2560 } 2535 }
2561 } 2536 }
2562 2537
2563 2538
2564 // <Expression> ::= StaticCall { function: Function 2539 // <Expression> ::= StaticCall { function: Function
2565 // arguments: <ArgumentList> } 2540 // arguments: <ArgumentList> }
2566 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { 2541 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
2567 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2542 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2568 new (Z) ZoneGrowableArray<PushArgumentInstr*>( 2543 new (Z) ZoneGrowableArray<PushArgumentInstr*>(
2569 node->arguments()->LengthWithTypeArgs()); 2544 node->arguments()->LengthWithTypeArgs());
2570 BuildPushTypeArguments(*node->arguments(), arguments); 2545 BuildPushTypeArguments(*node->arguments(), arguments);
2571 BuildPushArguments(*node->arguments(), arguments); 2546 BuildPushArguments(*node->arguments(), arguments);
2572 StaticCallInstr* call = new (Z) StaticCallInstr( 2547 StaticCallInstr* call = new (Z) StaticCallInstr(
2573 node->token_pos(), node->function(), node->arguments()->type_args_len(), 2548 node->token_pos(), node->function(), node->arguments()->type_args_len(),
2574 node->arguments()->names(), arguments, owner()->ic_data_array(), 2549 node->arguments()->names(), arguments, owner()->ic_data_array());
2575 owner()->GetNextDeoptId());
2576 if (node->function().recognized_kind() != MethodRecognizer::kUnknown) { 2550 if (node->function().recognized_kind() != MethodRecognizer::kUnknown) {
2577 call->set_result_cid(MethodRecognizer::ResultCid(node->function())); 2551 call->set_result_cid(MethodRecognizer::ResultCid(node->function()));
2578 } 2552 }
2579 ReturnDefinition(call); 2553 ReturnDefinition(call);
2580 } 2554 }
2581 2555
2582 2556
2583 void EffectGraphVisitor::BuildClosureCall(ClosureCallNode* node, 2557 void EffectGraphVisitor::BuildClosureCall(ClosureCallNode* node,
2584 bool result_needed) { 2558 bool result_needed) {
2585 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2559 ZoneGrowableArray<PushArgumentInstr*>* arguments =
(...skipping 13 matching lines...) Expand all
2599 arguments->Add(push_closure); 2573 arguments->Add(push_closure);
2600 BuildPushArguments(*node->arguments(), arguments); 2574 BuildPushArguments(*node->arguments(), arguments);
2601 2575
2602 closure_val = Bind(new (Z) LoadLocalInstr(*tmp_var, node->token_pos())); 2576 closure_val = Bind(new (Z) LoadLocalInstr(*tmp_var, node->token_pos()));
2603 LoadFieldInstr* function_load = new (Z) LoadFieldInstr( 2577 LoadFieldInstr* function_load = new (Z) LoadFieldInstr(
2604 closure_val, Closure::function_offset(), 2578 closure_val, Closure::function_offset(),
2605 AbstractType::ZoneHandle(Z, AbstractType::null()), node->token_pos()); 2579 AbstractType::ZoneHandle(Z, AbstractType::null()), node->token_pos());
2606 function_load->set_is_immutable(true); 2580 function_load->set_is_immutable(true);
2607 Value* function_val = Bind(function_load); 2581 Value* function_val = Bind(function_load);
2608 2582
2609 Definition* closure_call = new (Z) ClosureCallInstr( 2583 Definition* closure_call =
2610 function_val, node, arguments, owner()->GetNextDeoptId()); 2584 new (Z) ClosureCallInstr(function_val, node, arguments);
2611 if (result_needed) { 2585 if (result_needed) {
2612 Value* result = Bind(closure_call); 2586 Value* result = Bind(closure_call);
2613 Do(new (Z) StoreLocalInstr(*tmp_var, result, ST(node->token_pos()))); 2587 Do(new (Z) StoreLocalInstr(*tmp_var, result, ST(node->token_pos())));
2614 } else { 2588 } else {
2615 Do(closure_call); 2589 Do(closure_call);
2616 } 2590 }
2617 ReturnDefinition(ExitTempLocalScope(closure_value)); 2591 ReturnDefinition(ExitTempLocalScope(closure_value));
2618 } 2592 }
2619 2593
2620 2594
2621 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { 2595 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
2622 BuildClosureCall(node, false); 2596 BuildClosureCall(node, false);
2623 } 2597 }
2624 2598
2625 2599
2626 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { 2600 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
2627 BuildClosureCall(node, true); 2601 BuildClosureCall(node, true);
2628 } 2602 }
2629 2603
2630 2604
2631 void EffectGraphVisitor::VisitInitStaticFieldNode(InitStaticFieldNode* node) { 2605 void EffectGraphVisitor::VisitInitStaticFieldNode(InitStaticFieldNode* node) {
2632 Value* field = Bind( 2606 Value* field = Bind(
2633 new (Z) ConstantInstr(Field::ZoneHandle(Z, node->field().Original()))); 2607 new (Z) ConstantInstr(Field::ZoneHandle(Z, node->field().Original())));
2634 AddInstruction(new (Z) InitStaticFieldInstr(field, node->field(), 2608 AddInstruction(new (Z) InitStaticFieldInstr(field, node->field()));
2635 owner()->GetNextDeoptId()));
2636 } 2609 }
2637 2610
2638 2611
2639 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { 2612 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
2640 Value* context = Bind(BuildCurrentContext(node->token_pos())); 2613 Value* context = Bind(BuildCurrentContext(node->token_pos()));
2641 Value* clone = Bind(new (Z) CloneContextInstr(node->token_pos(), context, 2614 Value* clone = Bind(new (Z) CloneContextInstr(node->token_pos(), context));
2642 owner()->GetNextDeoptId()));
2643 Do(BuildStoreContext(clone, node->token_pos())); 2615 Do(BuildStoreContext(clone, node->token_pos()));
2644 } 2616 }
2645 2617
2646 2618
2647 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) { 2619 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) {
2648 const Class& cls = Class::ZoneHandle(Z, node->constructor().Owner()); 2620 const Class& cls = Class::ZoneHandle(Z, node->constructor().Owner());
2649 const bool cls_is_parameterized = cls.NumTypeArguments() > 0; 2621 const bool cls_is_parameterized = cls.NumTypeArguments() > 0;
2650 2622
2651 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = new (Z) 2623 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = new (Z)
2652 ZoneGrowableArray<PushArgumentInstr*>(cls_is_parameterized ? 1 : 0); 2624 ZoneGrowableArray<PushArgumentInstr*>(cls_is_parameterized ? 1 : 0);
(...skipping 13 matching lines...) Expand all
2666 2638
2667 void EffectGraphVisitor::BuildConstructorCall( 2639 void EffectGraphVisitor::BuildConstructorCall(
2668 ConstructorCallNode* node, 2640 ConstructorCallNode* node,
2669 PushArgumentInstr* push_alloc_value) { 2641 PushArgumentInstr* push_alloc_value) {
2670 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2642 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2671 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2); 2643 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
2672 arguments->Add(push_alloc_value); 2644 arguments->Add(push_alloc_value);
2673 2645
2674 BuildPushArguments(*node->arguments(), arguments); 2646 BuildPushArguments(*node->arguments(), arguments);
2675 const intptr_t kTypeArgsLen = 0; 2647 const intptr_t kTypeArgsLen = 0;
2676 Do(new (Z) 2648 Do(new (Z) StaticCallInstr(node->token_pos(), node->constructor(),
2677 StaticCallInstr(node->token_pos(), node->constructor(), kTypeArgsLen, 2649 kTypeArgsLen, node->arguments()->names(),
2678 node->arguments()->names(), arguments, 2650 arguments, owner()->ic_data_array()));
2679 owner()->ic_data_array(), owner()->GetNextDeoptId()));
2680 } 2651 }
2681 2652
2682 2653
2683 static intptr_t GetResultCidOfListFactory(ConstructorCallNode* node) { 2654 static intptr_t GetResultCidOfListFactory(ConstructorCallNode* node) {
2684 const Function& function = node->constructor(); 2655 const Function& function = node->constructor();
2685 const Class& function_class = Class::Handle(function.Owner()); 2656 const Class& function_class = Class::Handle(function.Owner());
2686 2657
2687 if ((function_class.library() != Library::CoreLibrary()) && 2658 if ((function_class.library() != Library::CoreLibrary()) &&
2688 (function_class.library() != Library::TypedDataLibrary())) { 2659 (function_class.library() != Library::TypedDataLibrary())) {
2689 return kDynamicCid; 2660 return kDynamicCid;
(...skipping 18 matching lines...) Expand all
2708 if (node->constructor().IsFactory()) { 2679 if (node->constructor().IsFactory()) {
2709 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2680 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2710 new (Z) ZoneGrowableArray<PushArgumentInstr*>(); 2681 new (Z) ZoneGrowableArray<PushArgumentInstr*>();
2711 PushArgumentInstr* push_type_arguments = 2682 PushArgumentInstr* push_type_arguments =
2712 PushArgument(BuildInstantiatedTypeArguments(node->token_pos(), 2683 PushArgument(BuildInstantiatedTypeArguments(node->token_pos(),
2713 node->type_arguments())); 2684 node->type_arguments()));
2714 arguments->Add(push_type_arguments); 2685 arguments->Add(push_type_arguments);
2715 ASSERT(arguments->length() == 1); 2686 ASSERT(arguments->length() == 1);
2716 BuildPushArguments(*node->arguments(), arguments); 2687 BuildPushArguments(*node->arguments(), arguments);
2717 const int kTypeArgsLen = 0; 2688 const int kTypeArgsLen = 0;
2718 StaticCallInstr* call = new (Z) 2689 StaticCallInstr* call = new (Z) StaticCallInstr(
2719 StaticCallInstr(node->token_pos(), node->constructor(), kTypeArgsLen, 2690 node->token_pos(), node->constructor(), kTypeArgsLen,
2720 node->arguments()->names(), arguments, 2691 node->arguments()->names(), arguments, owner()->ic_data_array());
2721 owner()->ic_data_array(), owner()->GetNextDeoptId());
2722 const intptr_t result_cid = GetResultCidOfListFactory(node); 2692 const intptr_t result_cid = GetResultCidOfListFactory(node);
2723 if (result_cid != kDynamicCid) { 2693 if (result_cid != kDynamicCid) {
2724 call->set_result_cid(result_cid); 2694 call->set_result_cid(result_cid);
2725 call->set_is_known_list_constructor(true); 2695 call->set_is_known_list_constructor(true);
2726 // Recognized fixed length array factory must have two arguments: 2696 // Recognized fixed length array factory must have two arguments:
2727 // (0) type-arguments, (1) length. 2697 // (0) type-arguments, (1) length.
2728 ASSERT(!LoadFieldInstr::IsFixedLengthArrayCid(result_cid) || 2698 ASSERT(!LoadFieldInstr::IsFixedLengthArrayCid(result_cid) ||
2729 arguments->length() == 2); 2699 arguments->length() == 2);
2730 } else if (node->constructor().recognized_kind() != 2700 } else if (node->constructor().recognized_kind() !=
2731 MethodRecognizer::kUnknown) { 2701 MethodRecognizer::kUnknown) {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
2853 } 2823 }
2854 } 2824 }
2855 Value* function_type_args = NULL; 2825 Value* function_type_args = NULL;
2856 if (type_arguments.IsInstantiated(kFunctions)) { 2826 if (type_arguments.IsInstantiated(kFunctions)) {
2857 function_type_args = BuildNullValue(token_pos); 2827 function_type_args = BuildNullValue(token_pos);
2858 } else { 2828 } else {
2859 function_type_args = BuildFunctionTypeArguments(token_pos); 2829 function_type_args = BuildFunctionTypeArguments(token_pos);
2860 } 2830 }
2861 return Bind(new (Z) InstantiateTypeArgumentsInstr( 2831 return Bind(new (Z) InstantiateTypeArgumentsInstr(
2862 token_pos, type_arguments, instantiator_class, instantiator_type_args, 2832 token_pos, type_arguments, instantiator_class, instantiator_type_args,
2863 function_type_args, owner()->GetNextDeoptId())); 2833 function_type_args));
2864 } 2834 }
2865 2835
2866 2836
2867 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { 2837 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
2868 if (node->constructor().IsFactory()) { 2838 if (node->constructor().IsFactory()) {
2869 EffectGraphVisitor::VisitConstructorCallNode(node); 2839 EffectGraphVisitor::VisitConstructorCallNode(node);
2870 return; 2840 return;
2871 } 2841 }
2872 2842
2873 // t_n contains the allocated and initialized object. 2843 // t_n contains the allocated and initialized object.
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2942 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos())); 2912 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos()));
2943 BuildInstanceGetterConditional(node); 2913 BuildInstanceGetterConditional(node);
2944 } else { 2914 } else {
2945 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); 2915 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
2946 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2916 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2947 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1); 2917 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1);
2948 arguments->Add(push_receiver); 2918 arguments->Add(push_receiver);
2949 const String& name = 2919 const String& name =
2950 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name())); 2920 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name()));
2951 const intptr_t kTypeArgsLen = 0; 2921 const intptr_t kTypeArgsLen = 0;
2952 InstanceCallInstr* call = new (Z) 2922 InstanceCallInstr* call = new (Z) InstanceCallInstr(
2953 InstanceCallInstr(node->token_pos(), name, Token::kGET, arguments, 2923 node->token_pos(), name, Token::kGET, arguments, kTypeArgsLen,
2954 kTypeArgsLen, Object::null_array(), 1, 2924 Object::null_array(), 1, owner()->ic_data_array());
2955 owner()->ic_data_array(), owner()->GetNextDeoptId());
2956 ReturnDefinition(call); 2925 ReturnDefinition(call);
2957 } 2926 }
2958 } 2927 }
2959 2928
2960 2929
2961 void EffectGraphVisitor::BuildInstanceSetterArguments( 2930 void EffectGraphVisitor::BuildInstanceSetterArguments(
2962 InstanceSetterNode* node, 2931 InstanceSetterNode* node,
2963 ZoneGrowableArray<PushArgumentInstr*>* arguments, 2932 ZoneGrowableArray<PushArgumentInstr*>* arguments,
2964 bool result_is_needed) { 2933 bool result_is_needed) {
2965 ValueGraphVisitor for_receiver(owner()); 2934 ValueGraphVisitor for_receiver(owner());
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3007 Join(for_test, for_true, for_false); 2976 Join(for_test, for_true, for_false);
3008 return; 2977 return;
3009 } 2978 }
3010 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2979 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3011 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2); 2980 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
3012 BuildInstanceSetterArguments(node, arguments, kResultNotNeeded); 2981 BuildInstanceSetterArguments(node, arguments, kResultNotNeeded);
3013 const String& name = 2982 const String& name =
3014 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name())); 2983 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
3015 const int kTypeArgsLen = 0; 2984 const int kTypeArgsLen = 0;
3016 const intptr_t kNumArgsChecked = 1; // Do not check value type. 2985 const intptr_t kNumArgsChecked = 1; // Do not check value type.
3017 InstanceCallInstr* call = new (Z) 2986 InstanceCallInstr* call = new (Z) InstanceCallInstr(
3018 InstanceCallInstr(token_pos, name, Token::kSET, arguments, kTypeArgsLen, 2987 token_pos, name, Token::kSET, arguments, kTypeArgsLen,
3019 Object::null_array(), kNumArgsChecked, 2988 Object::null_array(), kNumArgsChecked, owner()->ic_data_array());
3020 owner()->ic_data_array(), owner()->GetNextDeoptId());
3021 ReturnDefinition(call); 2989 ReturnDefinition(call);
3022 } 2990 }
3023 2991
3024 2992
3025 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { 2993 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
3026 const TokenPosition token_pos = node->token_pos(); 2994 const TokenPosition token_pos = node->token_pos();
3027 if (node->is_conditional()) { 2995 if (node->is_conditional()) {
3028 ValueGraphVisitor for_receiver(owner()); 2996 ValueGraphVisitor for_receiver(owner());
3029 node->receiver()->Visit(&for_receiver); 2997 node->receiver()->Visit(&for_receiver);
3030 Append(for_receiver); 2998 Append(for_receiver);
(...skipping 24 matching lines...) Expand all
3055 } 3023 }
3056 ZoneGrowableArray<PushArgumentInstr*>* arguments = 3024 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3057 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2); 3025 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
3058 BuildInstanceSetterArguments(node, arguments, kResultNeeded); 3026 BuildInstanceSetterArguments(node, arguments, kResultNeeded);
3059 const String& name = 3027 const String& name =
3060 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name())); 3028 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
3061 const intptr_t kTypeArgsLen = 0; 3029 const intptr_t kTypeArgsLen = 0;
3062 const intptr_t kNumArgsChecked = 1; // Do not check value type. 3030 const intptr_t kNumArgsChecked = 1; // Do not check value type.
3063 Do(new (Z) InstanceCallInstr(token_pos, name, Token::kSET, arguments, 3031 Do(new (Z) InstanceCallInstr(token_pos, name, Token::kSET, arguments,
3064 kTypeArgsLen, Object::null_array(), 3032 kTypeArgsLen, Object::null_array(),
3065 kNumArgsChecked, owner()->ic_data_array(), 3033 kNumArgsChecked, owner()->ic_data_array()));
3066 owner()->GetNextDeoptId()));
3067 ReturnDefinition(BuildLoadExprTemp(token_pos)); 3034 ReturnDefinition(BuildLoadExprTemp(token_pos));
3068 } 3035 }
3069 3036
3070 3037
3071 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { 3038 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) {
3072 const String& getter_name = 3039 const String& getter_name =
3073 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name())); 3040 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name()));
3074 ZoneGrowableArray<PushArgumentInstr*>* arguments = 3041 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3075 new (Z) ZoneGrowableArray<PushArgumentInstr*>(); 3042 new (Z) ZoneGrowableArray<PushArgumentInstr*>();
3076 Function& getter_function = Function::ZoneHandle(Z, Function::null()); 3043 Function& getter_function = Function::ZoneHandle(Z, Function::null());
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
3119 InvocationMirror::EncodeType(node->cls().IsTopLevel() 3086 InvocationMirror::EncodeType(node->cls().IsTopLevel()
3120 ? InvocationMirror::kTopLevel 3087 ? InvocationMirror::kTopLevel
3121 : InvocationMirror::kStatic, 3088 : InvocationMirror::kStatic,
3122 InvocationMirror::kGetter)); 3089 InvocationMirror::kGetter));
3123 ReturnDefinition(call); 3090 ReturnDefinition(call);
3124 return; 3091 return;
3125 } 3092 }
3126 } 3093 }
3127 ASSERT(!getter_function.IsNull()); 3094 ASSERT(!getter_function.IsNull());
3128 const intptr_t kTypeArgsLen = 0; 3095 const intptr_t kTypeArgsLen = 0;
3129 StaticCallInstr* call = new (Z) StaticCallInstr( 3096 StaticCallInstr* call =
3130 node->token_pos(), getter_function, kTypeArgsLen, 3097 new (Z) StaticCallInstr(node->token_pos(), getter_function, kTypeArgsLen,
3131 Object::null_array(), // No names 3098 Object::null_array(), // No names
3132 arguments, owner()->ic_data_array(), owner()->GetNextDeoptId()); 3099 arguments, owner()->ic_data_array());
3133 ReturnDefinition(call); 3100 ReturnDefinition(call);
3134 } 3101 }
3135 3102
3136 3103
3137 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, 3104 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node,
3138 bool result_is_needed) { 3105 bool result_is_needed) {
3139 const String& setter_name = 3106 const String& setter_name =
3140 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name())); 3107 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
3141 ZoneGrowableArray<PushArgumentInstr*>* arguments = 3108 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3142 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1); 3109 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3184 Value* value = NULL; 3151 Value* value = NULL;
3185 if (result_is_needed) { 3152 if (result_is_needed) {
3186 value = Bind(BuildStoreExprTemp(for_value.value(), token_pos)); 3153 value = Bind(BuildStoreExprTemp(for_value.value(), token_pos));
3187 } else { 3154 } else {
3188 value = for_value.value(); 3155 value = for_value.value();
3189 } 3156 }
3190 arguments->Add(PushArgument(value)); 3157 arguments->Add(PushArgument(value));
3191 const intptr_t kTypeArgsLen = 0; 3158 const intptr_t kTypeArgsLen = 0;
3192 call = new (Z) StaticCallInstr(token_pos, setter_function, kTypeArgsLen, 3159 call = new (Z) StaticCallInstr(token_pos, setter_function, kTypeArgsLen,
3193 Object::null_array(), // No names. 3160 Object::null_array(), // No names.
3194 arguments, owner()->ic_data_array(), 3161 arguments, owner()->ic_data_array());
3195 owner()->GetNextDeoptId());
3196 } 3162 }
3197 if (result_is_needed) { 3163 if (result_is_needed) {
3198 Do(call); 3164 Do(call);
3199 ReturnDefinition(BuildLoadExprTemp(token_pos)); 3165 ReturnDefinition(BuildLoadExprTemp(token_pos));
3200 } else { 3166 } else {
3201 ReturnDefinition(call); 3167 ReturnDefinition(call);
3202 } 3168 }
3203 } 3169 }
3204 3170
3205 3171
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
3277 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function); 3243 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
3278 switch (kind) { 3244 switch (kind) {
3279 case MethodRecognizer::kObjectEquals: { 3245 case MethodRecognizer::kObjectEquals: {
3280 Value* receiver = Bind(BuildLoadThisVar(node->scope(), token_pos)); 3246 Value* receiver = Bind(BuildLoadThisVar(node->scope(), token_pos));
3281 LocalVariable* other_var = 3247 LocalVariable* other_var =
3282 node->scope()->LookupVariable(Symbols::Other(), 3248 node->scope()->LookupVariable(Symbols::Other(),
3283 true); // Test only. 3249 true); // Test only.
3284 Value* other = Bind(new (Z) LoadLocalInstr(*other_var, token_pos)); 3250 Value* other = Bind(new (Z) LoadLocalInstr(*other_var, token_pos));
3285 // Receiver is not a number because numbers override equality. 3251 // Receiver is not a number because numbers override equality.
3286 const bool kNoNumberCheck = false; 3252 const bool kNoNumberCheck = false;
3287 StrictCompareInstr* compare = new (Z) 3253 StrictCompareInstr* compare = new (Z) StrictCompareInstr(
3288 StrictCompareInstr(token_pos, Token::kEQ_STRICT, receiver, other, 3254 token_pos, Token::kEQ_STRICT, receiver, other, kNoNumberCheck);
3289 kNoNumberCheck, owner()->GetNextDeoptId());
3290 return ReturnDefinition(compare); 3255 return ReturnDefinition(compare);
3291 } 3256 }
3292 case MethodRecognizer::kStringBaseLength: 3257 case MethodRecognizer::kStringBaseLength:
3293 case MethodRecognizer::kStringBaseIsEmpty: { 3258 case MethodRecognizer::kStringBaseIsEmpty: {
3294 // Treat length loads as mutable (i.e. affected by side effects) to 3259 // Treat length loads as mutable (i.e. affected by side effects) to
3295 // avoid hoisting them since we can't hoist the preceding class-check. 3260 // avoid hoisting them since we can't hoist the preceding class-check.
3296 // This is because of externalization of strings that affects their 3261 // This is because of externalization of strings that affects their
3297 // class-id. 3262 // class-id.
3298 LoadFieldInstr* load = BuildNativeGetter( 3263 LoadFieldInstr* load = BuildNativeGetter(
3299 node, MethodRecognizer::kStringBaseLength, String::length_offset(), 3264 node, MethodRecognizer::kStringBaseLength, String::length_offset(),
3300 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); 3265 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid);
3301 load->set_is_immutable(!FLAG_support_externalizable_strings); 3266 load->set_is_immutable(!FLAG_support_externalizable_strings);
3302 if (kind == MethodRecognizer::kStringBaseLength) { 3267 if (kind == MethodRecognizer::kStringBaseLength) {
3303 return ReturnDefinition(load); 3268 return ReturnDefinition(load);
3304 } 3269 }
3305 ASSERT(kind == MethodRecognizer::kStringBaseIsEmpty); 3270 ASSERT(kind == MethodRecognizer::kStringBaseIsEmpty);
3306 Value* zero_val = 3271 Value* zero_val =
3307 Bind(new (Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(0)))); 3272 Bind(new (Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(0))));
3308 Value* load_val = Bind(load); 3273 Value* load_val = Bind(load);
3309 StrictCompareInstr* compare = new (Z) StrictCompareInstr( 3274 StrictCompareInstr* compare = new (Z)
3310 token_pos, Token::kEQ_STRICT, load_val, zero_val, false, 3275 StrictCompareInstr(token_pos, Token::kEQ_STRICT, load_val, zero_val,
3311 owner()->GetNextDeoptId()); // No number check. 3276 false); // No number check.
3312 return ReturnDefinition(compare); 3277 return ReturnDefinition(compare);
3313 } 3278 }
3314 case MethodRecognizer::kGrowableArrayLength: 3279 case MethodRecognizer::kGrowableArrayLength:
3315 case MethodRecognizer::kObjectArrayLength: 3280 case MethodRecognizer::kObjectArrayLength:
3316 case MethodRecognizer::kImmutableArrayLength: 3281 case MethodRecognizer::kImmutableArrayLength:
3317 case MethodRecognizer::kTypedDataLength: { 3282 case MethodRecognizer::kTypedDataLength: {
3318 LoadFieldInstr* load = 3283 LoadFieldInstr* load =
3319 BuildNativeGetter(node, kind, OffsetForLengthGetter(kind), 3284 BuildNativeGetter(node, kind, OffsetForLengthGetter(kind),
3320 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); 3285 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid);
3321 load->set_is_immutable(kind != MethodRecognizer::kGrowableArrayLength); 3286 load->set_is_immutable(kind != MethodRecognizer::kGrowableArrayLength);
(...skipping 22 matching lines...) Expand all
3344 } 3309 }
3345 case MethodRecognizer::kObjectArrayAllocate: { 3310 case MethodRecognizer::kObjectArrayAllocate: {
3346 LocalVariable* type_args_parameter = node->scope()->LookupVariable( 3311 LocalVariable* type_args_parameter = node->scope()->LookupVariable(
3347 Symbols::TypeArgumentsParameter(), true); 3312 Symbols::TypeArgumentsParameter(), true);
3348 Value* element_type = 3313 Value* element_type =
3349 Bind(new (Z) LoadLocalInstr(*type_args_parameter, token_pos)); 3314 Bind(new (Z) LoadLocalInstr(*type_args_parameter, token_pos));
3350 LocalVariable* length_parameter = 3315 LocalVariable* length_parameter =
3351 node->scope()->LookupVariable(Symbols::Length(), true); 3316 node->scope()->LookupVariable(Symbols::Length(), true);
3352 Value* length = 3317 Value* length =
3353 Bind(new (Z) LoadLocalInstr(*length_parameter, token_pos)); 3318 Bind(new (Z) LoadLocalInstr(*length_parameter, token_pos));
3354 CreateArrayInstr* create_array = new CreateArrayInstr( 3319 CreateArrayInstr* create_array =
3355 token_pos, element_type, length, owner()->GetNextDeoptId()); 3320 new CreateArrayInstr(token_pos, element_type, length);
3356 return ReturnDefinition(create_array); 3321 return ReturnDefinition(create_array);
3357 } 3322 }
3358 case MethodRecognizer::kBigint_getDigits: { 3323 case MethodRecognizer::kBigint_getDigits: {
3359 return ReturnDefinition(BuildNativeGetter( 3324 return ReturnDefinition(BuildNativeGetter(
3360 node, kind, Bigint::digits_offset(), Object::dynamic_type(), 3325 node, kind, Bigint::digits_offset(), Object::dynamic_type(),
3361 kTypedDataUint32ArrayCid)); 3326 kTypedDataUint32ArrayCid));
3362 } 3327 }
3363 case MethodRecognizer::kBigint_getUsed: { 3328 case MethodRecognizer::kBigint_getUsed: {
3364 return ReturnDefinition( 3329 return ReturnDefinition(
3365 BuildNativeGetter(node, kind, Bigint::used_offset(), 3330 BuildNativeGetter(node, kind, Bigint::used_offset(),
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
3635 ValueGraphVisitor for_index(owner()); 3600 ValueGraphVisitor for_index(owner());
3636 node->index_expr()->Visit(&for_index); 3601 node->index_expr()->Visit(&for_index);
3637 Append(for_index); 3602 Append(for_index);
3638 arguments->Add(PushArgument(for_index.value())); 3603 arguments->Add(PushArgument(for_index.value()));
3639 3604
3640 const intptr_t kTypeArgsLen = 0; 3605 const intptr_t kTypeArgsLen = 0;
3641 if (super_function != NULL) { 3606 if (super_function != NULL) {
3642 // Generate static call to super operator. 3607 // Generate static call to super operator.
3643 StaticCallInstr* load = new (Z) StaticCallInstr( 3608 StaticCallInstr* load = new (Z) StaticCallInstr(
3644 node->token_pos(), *super_function, kTypeArgsLen, Object::null_array(), 3609 node->token_pos(), *super_function, kTypeArgsLen, Object::null_array(),
3645 arguments, owner()->ic_data_array(), owner()->GetNextDeoptId()); 3610 arguments, owner()->ic_data_array());
3646 ReturnDefinition(load); 3611 ReturnDefinition(load);
3647 } else { 3612 } else {
3648 // Generate dynamic call to index operator. 3613 // Generate dynamic call to index operator.
3649 const intptr_t checked_argument_count = 1; 3614 const intptr_t checked_argument_count = 1;
3650 InstanceCallInstr* load = new (Z) InstanceCallInstr( 3615 InstanceCallInstr* load = new (Z) InstanceCallInstr(
3651 node->token_pos(), Symbols::IndexToken(), Token::kINDEX, arguments, 3616 node->token_pos(), Symbols::IndexToken(), Token::kINDEX, arguments,
3652 kTypeArgsLen, Object::null_array(), checked_argument_count, 3617 kTypeArgsLen, Object::null_array(), checked_argument_count,
3653 owner()->ic_data_array(), owner()->GetNextDeoptId()); 3618 owner()->ic_data_array());
3654 ReturnDefinition(load); 3619 ReturnDefinition(load);
3655 } 3620 }
3656 } 3621 }
3657 3622
3658 3623
3659 Definition* EffectGraphVisitor::BuildStoreIndexedValues(StoreIndexedNode* node, 3624 Definition* EffectGraphVisitor::BuildStoreIndexedValues(StoreIndexedNode* node,
3660 bool result_is_needed) { 3625 bool result_is_needed) {
3661 Function* super_function = NULL; 3626 Function* super_function = NULL;
3662 const TokenPosition token_pos = node->token_pos(); 3627 const TokenPosition token_pos = node->token_pos();
3663 if (node->IsSuperStore()) { 3628 if (node->IsSuperStore()) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3709 value = for_value.value(); 3674 value = for_value.value();
3710 } 3675 }
3711 arguments->Add(PushArgument(value)); 3676 arguments->Add(PushArgument(value));
3712 3677
3713 const intptr_t kTypeArgsLen = 0; 3678 const intptr_t kTypeArgsLen = 0;
3714 if (super_function != NULL) { 3679 if (super_function != NULL) {
3715 // Generate static call to super operator []=. 3680 // Generate static call to super operator []=.
3716 3681
3717 StaticCallInstr* store = new (Z) StaticCallInstr( 3682 StaticCallInstr* store = new (Z) StaticCallInstr(
3718 token_pos, *super_function, kTypeArgsLen, Object::null_array(), 3683 token_pos, *super_function, kTypeArgsLen, Object::null_array(),
3719 arguments, owner()->ic_data_array(), owner()->GetNextDeoptId()); 3684 arguments, owner()->ic_data_array());
3720 if (result_is_needed) { 3685 if (result_is_needed) {
3721 Do(store); 3686 Do(store);
3722 return BuildLoadExprTemp(token_pos); 3687 return BuildLoadExprTemp(token_pos);
3723 } else { 3688 } else {
3724 return store; 3689 return store;
3725 } 3690 }
3726 } else { 3691 } else {
3727 // Generate dynamic call to operator []=. 3692 // Generate dynamic call to operator []=.
3728 const intptr_t checked_argument_count = 2; // Do not check for value type. 3693 const intptr_t checked_argument_count = 2; // Do not check for value type.
3729 InstanceCallInstr* store = new (Z) InstanceCallInstr( 3694 InstanceCallInstr* store = new (Z) InstanceCallInstr(
3730 token_pos, Symbols::AssignIndexToken(), Token::kASSIGN_INDEX, arguments, 3695 token_pos, Symbols::AssignIndexToken(), Token::kASSIGN_INDEX, arguments,
3731 kTypeArgsLen, Object::null_array(), checked_argument_count, 3696 kTypeArgsLen, Object::null_array(), checked_argument_count,
3732 owner()->ic_data_array(), owner()->GetNextDeoptId()); 3697 owner()->ic_data_array());
3733 if (result_is_needed) { 3698 if (result_is_needed) {
3734 Do(store); 3699 Do(store);
3735 return BuildLoadExprTemp(token_pos); 3700 return BuildLoadExprTemp(token_pos);
3736 } else { 3701 } else {
3737 return store; 3702 return store;
3738 } 3703 }
3739 } 3704 }
3740 } 3705 }
3741 3706
3742 3707
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
3893 // Setup arguments for _asyncSetThreadStackTrace. 3858 // Setup arguments for _asyncSetThreadStackTrace.
3894 ZoneGrowableArray<PushArgumentInstr*>* arguments = 3859 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3895 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1); 3860 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1);
3896 arguments->Add(PushArgument(async_stack_trace_value)); 3861 arguments->Add(PushArgument(async_stack_trace_value));
3897 3862
3898 const Function& async_set_thread_stack_trace = Function::ZoneHandle( 3863 const Function& async_set_thread_stack_trace = Function::ZoneHandle(
3899 Z, isolate()->object_store()->async_set_thread_stack_trace()); 3864 Z, isolate()->object_store()->async_set_thread_stack_trace());
3900 ASSERT(!async_set_thread_stack_trace.IsNull()); 3865 ASSERT(!async_set_thread_stack_trace.IsNull());
3901 // Call _asyncSetThreadStackTrace 3866 // Call _asyncSetThreadStackTrace
3902 const intptr_t kTypeArgsLen = 0; 3867 const intptr_t kTypeArgsLen = 0;
3903 StaticCallInstr* call_async_set_thread_stack_trace = new (Z) 3868 StaticCallInstr* call_async_set_thread_stack_trace =
3904 StaticCallInstr(node->token_pos().ToSynthetic(), 3869 new (Z) StaticCallInstr(node->token_pos().ToSynthetic(),
3905 async_set_thread_stack_trace, kTypeArgsLen, 3870 async_set_thread_stack_trace, kTypeArgsLen,
3906 Object::null_array(), arguments, 3871 Object::null_array(), arguments,
3907 owner()->ic_data_array(), owner()->GetNextDeoptId()); 3872 owner()->ic_data_array());
3908 Do(call_async_set_thread_stack_trace); 3873 Do(call_async_set_thread_stack_trace);
3909 } 3874 }
3910 3875
3911 3876
3912 if (FLAG_support_debugger && is_top_level_sequence && 3877 if (FLAG_support_debugger && is_top_level_sequence &&
3913 function.is_debuggable()) { 3878 function.is_debuggable()) {
3914 // Place a debug check at method entry to ensure breaking on a method always 3879 // Place a debug check at method entry to ensure breaking on a method always
3915 // happens, even if there are no assignments/calls/runtimecalls in the first 3880 // happens, even if there are no assignments/calls/runtimecalls in the first
3916 // basic block. Place this check at the last parameter to ensure parameters 3881 // basic block. Place this check at the last parameter to ensure parameters
3917 // are in scope in the debugger at method entry. 3882 // are in scope in the debugger at method entry.
(...skipping 13 matching lines...) Expand all
3931 new (Z) DebugStepCheckInstr(check_pos, RawPcDescriptors::kRuntimeCall)); 3896 new (Z) DebugStepCheckInstr(check_pos, RawPcDescriptors::kRuntimeCall));
3932 } 3897 }
3933 3898
3934 // This check may be deleted if the generated code is leaf. 3899 // This check may be deleted if the generated code is leaf.
3935 // Native functions don't need a stack check at entry. 3900 // Native functions don't need a stack check at entry.
3936 if (is_top_level_sequence && !function.is_native()) { 3901 if (is_top_level_sequence && !function.is_native()) {
3937 // Always allocate CheckOverflowInstr so that deopt-ids match regardless 3902 // Always allocate CheckOverflowInstr so that deopt-ids match regardless
3938 // if we inline or not. 3903 // if we inline or not.
3939 if (!function.IsImplicitGetterFunction() && 3904 if (!function.IsImplicitGetterFunction() &&
3940 !function.IsImplicitSetterFunction()) { 3905 !function.IsImplicitSetterFunction()) {
3941 CheckStackOverflowInstr* check = new (Z) CheckStackOverflowInstr( 3906 CheckStackOverflowInstr* check =
3942 node->token_pos(), 0, owner()->GetNextDeoptId()); 3907 new (Z) CheckStackOverflowInstr(node->token_pos(), 0);
3943 // If we are inlining don't actually attach the stack check. We must still 3908 // If we are inlining don't actually attach the stack check. We must still
3944 // create the stack check in order to allocate a deopt id. 3909 // create the stack check in order to allocate a deopt id.
3945 if (!owner()->IsInlining()) { 3910 if (!owner()->IsInlining()) {
3946 AddInstruction(check); 3911 AddInstruction(check);
3947 } 3912 }
3948 } 3913 }
3949 } 3914 }
3950 3915
3951 if (Isolate::Current()->type_checks() && is_top_level_sequence) { 3916 if (Isolate::Current()->type_checks() && is_top_level_sequence) {
3952 const int num_params = function.NumParameters(); 3917 const int num_params = function.NumParameters();
(...skipping 19 matching lines...) Expand all
3972 } 3937 }
3973 3938
3974 // Continuation part: 3939 // Continuation part:
3975 // If this node sequence is the body of a function with continuations, 3940 // If this node sequence is the body of a function with continuations,
3976 // leave room for a preamble. 3941 // leave room for a preamble.
3977 // The preamble is generated after visiting the body. 3942 // The preamble is generated after visiting the body.
3978 GotoInstr* preamble_start = NULL; 3943 GotoInstr* preamble_start = NULL;
3979 if (is_top_level_sequence && 3944 if (is_top_level_sequence &&
3980 (function.IsAsyncClosure() || function.IsSyncGenClosure() || 3945 (function.IsAsyncClosure() || function.IsSyncGenClosure() ||
3981 function.IsAsyncGenClosure())) { 3946 function.IsAsyncGenClosure())) {
3982 JoinEntryInstr* preamble_end = 3947 JoinEntryInstr* preamble_end = new (Z)
3983 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(), 3948 JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
3984 owner()->GetNextDeoptId());
3985 ASSERT(exit() != NULL); 3949 ASSERT(exit() != NULL);
3986 exit()->Goto(preamble_end); 3950 exit()->Goto(preamble_end);
3987 ASSERT(exit()->next()->IsGoto()); 3951 ASSERT(exit()->next()->IsGoto());
3988 preamble_start = exit()->next()->AsGoto(); 3952 preamble_start = exit()->next()->AsGoto();
3989 ASSERT(preamble_start->IsGoto()); 3953 ASSERT(preamble_start->IsGoto());
3990 exit_ = preamble_end; 3954 exit_ = preamble_end;
3991 } 3955 }
3992 3956
3993 intptr_t i = 0; 3957 intptr_t i = 0;
3994 while (is_open() && (i < node->length())) { 3958 while (is_open() && (i < node->length())) {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
4116 owner()->set_try_index(try_handler_index); 4080 owner()->set_try_index(try_handler_index);
4117 4081
4118 // Preserve current context into local variable ':saved_try_context_var'. 4082 // Preserve current context into local variable ':saved_try_context_var'.
4119 BuildSaveContext(node->context_var(), ST(node->token_pos())); 4083 BuildSaveContext(node->context_var(), ST(node->token_pos()));
4120 4084
4121 EffectGraphVisitor for_try(owner()); 4085 EffectGraphVisitor for_try(owner());
4122 node->try_block()->Visit(&for_try); 4086 node->try_block()->Visit(&for_try);
4123 4087
4124 if (for_try.is_open()) { 4088 if (for_try.is_open()) {
4125 JoinEntryInstr* after_try = new (Z) 4089 JoinEntryInstr* after_try = new (Z)
4126 JoinEntryInstr(owner()->AllocateBlockId(), original_handler_index, 4090 JoinEntryInstr(owner()->AllocateBlockId(), original_handler_index);
4127 owner()->GetNextDeoptId());
4128 for_try.Goto(after_try); 4091 for_try.Goto(after_try);
4129 for_try.exit_ = after_try; 4092 for_try.exit_ = after_try;
4130 } 4093 }
4131 4094
4132 JoinEntryInstr* try_entry = new (Z) JoinEntryInstr( 4095 JoinEntryInstr* try_entry =
4133 owner()->AllocateBlockId(), try_handler_index, owner()->GetNextDeoptId()); 4096 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), try_handler_index);
4134 4097
4135 Goto(try_entry); 4098 Goto(try_entry);
4136 AppendFragment(try_entry, for_try); 4099 AppendFragment(try_entry, for_try);
4137 exit_ = for_try.exit_; 4100 exit_ = for_try.exit_;
4138 4101
4139 // We are done generating code for the try block. 4102 // We are done generating code for the try block.
4140 owner()->set_try_index(original_handler_index); 4103 owner()->set_try_index(original_handler_index);
4141 4104
4142 // If there is a finally block, it is the handler for code in the catch 4105 // If there is a finally block, it is the handler for code in the catch
4143 // block. 4106 // block.
(...skipping 19 matching lines...) Expand all
4163 catch_block->token_pos(), (node->token_pos() == TokenPosition::kNoSource), 4126 catch_block->token_pos(), (node->token_pos() == TokenPosition::kNoSource),
4164 owner()->AllocateBlockId(), catch_handler_index, owner()->graph_entry(), 4127 owner()->AllocateBlockId(), catch_handler_index, owner()->graph_entry(),
4165 catch_block->handler_types(), try_handler_index, 4128 catch_block->handler_types(), try_handler_index,
4166 catch_block->exception_var(), catch_block->stacktrace_var(), 4129 catch_block->exception_var(), catch_block->stacktrace_var(),
4167 catch_block->needs_stacktrace(), Thread::Current()->GetNextDeoptId()); 4130 catch_block->needs_stacktrace(), Thread::Current()->GetNextDeoptId());
4168 owner()->AddCatchEntry(catch_entry); 4131 owner()->AddCatchEntry(catch_entry);
4169 AppendFragment(catch_entry, for_catch); 4132 AppendFragment(catch_entry, for_catch);
4170 4133
4171 if (for_catch.is_open()) { 4134 if (for_catch.is_open()) {
4172 JoinEntryInstr* join = new (Z) 4135 JoinEntryInstr* join = new (Z)
4173 JoinEntryInstr(owner()->AllocateBlockId(), original_handler_index, 4136 JoinEntryInstr(owner()->AllocateBlockId(), original_handler_index);
4174 owner()->GetNextDeoptId());
4175 for_catch.Goto(join); 4137 for_catch.Goto(join);
4176 if (is_open()) Goto(join); 4138 if (is_open()) Goto(join);
4177 exit_ = join; 4139 exit_ = join;
4178 } 4140 }
4179 4141
4180 if (finally_block != NULL) { 4142 if (finally_block != NULL) {
4181 ASSERT(node->rethrow_clause() != NULL); 4143 ASSERT(node->rethrow_clause() != NULL);
4182 // Create a handler for the code in the catch block, containing the 4144 // Create a handler for the code in the catch block, containing the
4183 // code in the finally block. 4145 // code in the finally block.
4184 owner()->set_try_index(original_handler_index); 4146 owner()->set_try_index(original_handler_index);
4185 EffectGraphVisitor for_finally(owner()); 4147 EffectGraphVisitor for_finally(owner());
4186 for_finally.BuildRestoreContext(catch_block->context_var(), 4148 for_finally.BuildRestoreContext(catch_block->context_var(),
4187 finally_block->token_pos()); 4149 finally_block->token_pos());
4188 4150
4189 node->rethrow_clause()->Visit(&for_finally); 4151 node->rethrow_clause()->Visit(&for_finally);
4190 if (for_finally.is_open()) { 4152 if (for_finally.is_open()) {
4191 // Rethrow the exception. Manually build the graph for rethrow. 4153 // Rethrow the exception. Manually build the graph for rethrow.
4192 Value* exception = for_finally.Bind(for_finally.BuildLoadLocal( 4154 Value* exception = for_finally.Bind(for_finally.BuildLoadLocal(
4193 catch_block->rethrow_exception_var(), finally_block->token_pos())); 4155 catch_block->rethrow_exception_var(), finally_block->token_pos()));
4194 for_finally.PushArgument(exception); 4156 for_finally.PushArgument(exception);
4195 Value* stacktrace = for_finally.Bind(for_finally.BuildLoadLocal( 4157 Value* stacktrace = for_finally.Bind(for_finally.BuildLoadLocal(
4196 catch_block->rethrow_stacktrace_var(), finally_block->token_pos())); 4158 catch_block->rethrow_stacktrace_var(), finally_block->token_pos()));
4197 for_finally.PushArgument(stacktrace); 4159 for_finally.PushArgument(stacktrace);
4198 for_finally.AddInstruction( 4160 for_finally.AddInstruction(
4199 new (Z) ReThrowInstr(catch_block->token_pos(), catch_handler_index, 4161 new (Z) ReThrowInstr(catch_block->token_pos(), catch_handler_index));
4200 owner()->GetNextDeoptId()));
4201 for_finally.CloseFragment(); 4162 for_finally.CloseFragment();
4202 } 4163 }
4203 ASSERT(!for_finally.is_open()); 4164 ASSERT(!for_finally.is_open());
4204 4165
4205 const Array& types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld)); 4166 const Array& types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld));
4206 types.SetAt(0, Object::dynamic_type()); 4167 types.SetAt(0, Object::dynamic_type());
4207 CatchBlockEntryInstr* finally_entry = new (Z) CatchBlockEntryInstr( 4168 CatchBlockEntryInstr* finally_entry = new (Z) CatchBlockEntryInstr(
4208 finally_block->token_pos(), 4169 finally_block->token_pos(),
4209 true, // this is not a catch block from user code. 4170 true, // this is not a catch block from user code.
4210 owner()->AllocateBlockId(), original_handler_index, 4171 owner()->AllocateBlockId(), original_handler_index,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
4253 const Class& object_class = 4214 const Class& object_class =
4254 Class::ZoneHandle(Z, isolate()->object_store()->object_class()); 4215 Class::ZoneHandle(Z, isolate()->object_store()->object_class());
4255 no_such_method_func = Resolver::ResolveDynamicForReceiverClass( 4216 no_such_method_func = Resolver::ResolveDynamicForReceiverClass(
4256 object_class, Symbols::NoSuchMethod(), args_desc); 4217 object_class, Symbols::NoSuchMethod(), args_desc);
4257 } 4218 }
4258 // We are guaranteed to find noSuchMethod of class Object. 4219 // We are guaranteed to find noSuchMethod of class Object.
4259 ASSERT(!no_such_method_func.IsNull()); 4220 ASSERT(!no_such_method_func.IsNull());
4260 ZoneGrowableArray<PushArgumentInstr*>* push_arguments = 4221 ZoneGrowableArray<PushArgumentInstr*>* push_arguments =
4261 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2); 4222 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
4262 BuildPushArguments(*args, push_arguments); 4223 BuildPushArguments(*args, push_arguments);
4263 return new (Z) StaticCallInstr( 4224 return new (Z) StaticCallInstr(args_pos, no_such_method_func, kTypeArgsLen,
4264 args_pos, no_such_method_func, kTypeArgsLen, Object::null_array(), 4225 Object::null_array(), push_arguments,
4265 push_arguments, owner()->ic_data_array(), owner()->GetNextDeoptId()); 4226 owner()->ic_data_array());
4266 } 4227 }
4267 4228
4268 4229
4269 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError( 4230 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError(
4270 TokenPosition token_pos, 4231 TokenPosition token_pos,
4271 const Class& function_class, 4232 const Class& function_class,
4272 const String& function_name, 4233 const String& function_name,
4273 ArgumentListNode* function_arguments, 4234 ArgumentListNode* function_arguments,
4274 int invocation_type) { 4235 int invocation_type) {
4275 ZoneGrowableArray<PushArgumentInstr*>* arguments = 4236 ZoneGrowableArray<PushArgumentInstr*>* arguments =
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
4321 Class::Handle(Z, core_lib.LookupClass(Symbols::NoSuchMethodError())); 4282 Class::Handle(Z, core_lib.LookupClass(Symbols::NoSuchMethodError()));
4322 ASSERT(!cls.IsNull()); 4283 ASSERT(!cls.IsNull());
4323 const intptr_t kTypeArgsLen = 0; 4284 const intptr_t kTypeArgsLen = 0;
4324 const Function& func = Function::ZoneHandle( 4285 const Function& func = Function::ZoneHandle(
4325 Z, Resolver::ResolveStatic( 4286 Z, Resolver::ResolveStatic(
4326 cls, Library::PrivateCoreLibName(Symbols::ThrowNew()), 4287 cls, Library::PrivateCoreLibName(Symbols::ThrowNew()),
4327 kTypeArgsLen, arguments->length(), Object::null_array())); 4288 kTypeArgsLen, arguments->length(), Object::null_array()));
4328 ASSERT(!func.IsNull()); 4289 ASSERT(!func.IsNull());
4329 return new (Z) StaticCallInstr(token_pos, func, kTypeArgsLen, 4290 return new (Z) StaticCallInstr(token_pos, func, kTypeArgsLen,
4330 Object::null_array(), // No names. 4291 Object::null_array(), // No names.
4331 arguments, owner()->ic_data_array(), 4292 arguments, owner()->ic_data_array());
4332 owner()->GetNextDeoptId());
4333 } 4293 }
4334 4294
4335 4295
4336 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { 4296 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) {
4337 if (FLAG_support_debugger) { 4297 if (FLAG_support_debugger) {
4338 if (node->exception()->IsLiteralNode() || 4298 if (node->exception()->IsLiteralNode() ||
4339 node->exception()->IsLoadLocalNode() || 4299 node->exception()->IsLoadLocalNode() ||
4340 node->exception()->IsLoadStaticFieldNode() || 4300 node->exception()->IsLoadStaticFieldNode() ||
4341 node->exception()->IsClosureNode()) { 4301 node->exception()->IsClosureNode()) {
4342 AddInstruction(new (Z) DebugStepCheckInstr( 4302 AddInstruction(new (Z) DebugStepCheckInstr(
4343 node->token_pos(), RawPcDescriptors::kRuntimeCall)); 4303 node->token_pos(), RawPcDescriptors::kRuntimeCall));
4344 } 4304 }
4345 } 4305 }
4346 ValueGraphVisitor for_exception(owner()); 4306 ValueGraphVisitor for_exception(owner());
4347 node->exception()->Visit(&for_exception); 4307 node->exception()->Visit(&for_exception);
4348 Append(for_exception); 4308 Append(for_exception);
4349 PushArgument(for_exception.value()); 4309 PushArgument(for_exception.value());
4350 Instruction* instr = NULL; 4310 Instruction* instr = NULL;
4351 if (node->stacktrace() == NULL) { 4311 if (node->stacktrace() == NULL) {
4352 instr = new (Z) ThrowInstr(node->token_pos(), owner()->GetNextDeoptId()); 4312 instr = new (Z) ThrowInstr(node->token_pos());
4353 } else { 4313 } else {
4354 ValueGraphVisitor for_stack_trace(owner()); 4314 ValueGraphVisitor for_stack_trace(owner());
4355 node->stacktrace()->Visit(&for_stack_trace); 4315 node->stacktrace()->Visit(&for_stack_trace);
4356 Append(for_stack_trace); 4316 Append(for_stack_trace);
4357 PushArgument(for_stack_trace.value()); 4317 PushArgument(for_stack_trace.value());
4358 instr = new (Z) ReThrowInstr(node->token_pos(), owner()->catch_try_index(), 4318 instr = new (Z) ReThrowInstr(node->token_pos(), owner()->catch_try_index());
4359 owner()->GetNextDeoptId());
4360 } 4319 }
4361 AddInstruction(instr); 4320 AddInstruction(instr);
4362 } 4321 }
4363 4322
4364 4323
4365 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { 4324 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) {
4366 BuildThrowNode(node); 4325 BuildThrowNode(node);
4367 CloseFragment(); 4326 CloseFragment();
4368 } 4327 }
4369 4328
(...skipping 19 matching lines...) Expand all
4389 owner()->set_try_index(outer_try_index); 4348 owner()->set_try_index(outer_try_index);
4390 } 4349 }
4391 4350
4392 // Note: do not restore the saved_try_context here since the inlined 4351 // Note: do not restore the saved_try_context here since the inlined
4393 // code is not reached via an exception handler, therefore the context is 4352 // code is not reached via an exception handler, therefore the context is
4394 // always properly set on entry. In other words, the inlined finally clause is 4353 // always properly set on entry. In other words, the inlined finally clause is
4395 // never the target of a long jump that would find an uninitialized current 4354 // never the target of a long jump that would find an uninitialized current
4396 // context variable. 4355 // context variable.
4397 4356
4398 JoinEntryInstr* finally_entry = 4357 JoinEntryInstr* finally_entry =
4399 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(), 4358 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
4400 owner()->GetNextDeoptId());
4401 EffectGraphVisitor for_finally_block(owner()); 4359 EffectGraphVisitor for_finally_block(owner());
4402 for_finally_block.AdjustContextLevel(node->finally_block()->scope()); 4360 for_finally_block.AdjustContextLevel(node->finally_block()->scope());
4403 node->finally_block()->Visit(&for_finally_block); 4361 node->finally_block()->Visit(&for_finally_block);
4404 4362
4405 if (try_index >= 0) { 4363 if (try_index >= 0) {
4406 owner()->set_try_index(try_index); 4364 owner()->set_try_index(try_index);
4407 } 4365 }
4408 4366
4409 if (for_finally_block.is_open()) { 4367 if (for_finally_block.is_open()) {
4410 JoinEntryInstr* after_finally = 4368 JoinEntryInstr* after_finally = new (Z)
4411 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(), 4369 JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
4412 owner()->GetNextDeoptId());
4413 for_finally_block.Goto(after_finally); 4370 for_finally_block.Goto(after_finally);
4414 for_finally_block.exit_ = after_finally; 4371 for_finally_block.exit_ = after_finally;
4415 } 4372 }
4416 4373
4417 Goto(finally_entry); 4374 Goto(finally_entry);
4418 AppendFragment(finally_entry, for_finally_block); 4375 AppendFragment(finally_entry, for_finally_block);
4419 exit_ = for_finally_block.exit_; 4376 exit_ = for_finally_block.exit_;
4420 } 4377 }
4421 4378
4422 4379
4423 void EffectGraphVisitor::VisitStopNode(StopNode* node) { 4380 void EffectGraphVisitor::VisitStopNode(StopNode* node) {
4424 AddInstruction(new (Z) StopInstr(node->message())); 4381 AddInstruction(new (Z) StopInstr(node->message()));
4425 } 4382 }
4426 4383
4427 4384
4428 FlowGraph* FlowGraphBuilder::BuildGraph() { 4385 FlowGraph* FlowGraphBuilder::BuildGraph() {
4429 VMTagScope tagScope(thread(), VMTag::kCompileFlowGraphBuilderTagId, 4386 VMTagScope tagScope(thread(), VMTag::kCompileFlowGraphBuilderTagId,
4430 FLAG_profile_vm); 4387 FLAG_profile_vm);
4431 if (FLAG_support_ast_printer && FLAG_print_ast && 4388 if (FLAG_support_ast_printer && FLAG_print_ast &&
4432 FlowGraphPrinter::ShouldPrint(parsed_function().function())) { 4389 FlowGraphPrinter::ShouldPrint(parsed_function().function())) {
4433 // Print the function ast before IL generation. 4390 // Print the function ast before IL generation.
4434 AstPrinter ast_printer; 4391 AstPrinter ast_printer;
4435 ast_printer.PrintFunctionNodes(parsed_function()); 4392 ast_printer.PrintFunctionNodes(parsed_function());
4436 } 4393 }
4437 if (FLAG_support_ast_printer && FLAG_print_scopes && 4394 if (FLAG_support_ast_printer && FLAG_print_scopes &&
4438 FlowGraphPrinter::ShouldPrint(parsed_function().function())) { 4395 FlowGraphPrinter::ShouldPrint(parsed_function().function())) {
4439 AstPrinter ast_printer; 4396 AstPrinter ast_printer;
4440 ast_printer.PrintFunctionScope(parsed_function()); 4397 ast_printer.PrintFunctionScope(parsed_function());
4441 } 4398 }
4442 TargetEntryInstr* normal_entry = new (Z) TargetEntryInstr( 4399 TargetEntryInstr* normal_entry = new (Z)
4443 AllocateBlockId(), CatchClauseNode::kInvalidTryIndex, GetNextDeoptId()); 4400 TargetEntryInstr(AllocateBlockId(), CatchClauseNode::kInvalidTryIndex);
4444 graph_entry_ = 4401 graph_entry_ =
4445 new (Z) GraphEntryInstr(parsed_function(), normal_entry, osr_id_); 4402 new (Z) GraphEntryInstr(parsed_function(), normal_entry, osr_id_);
4446 EffectGraphVisitor for_effect(this); 4403 EffectGraphVisitor for_effect(this);
4447 parsed_function().node_sequence()->Visit(&for_effect); 4404 parsed_function().node_sequence()->Visit(&for_effect);
4448 AppendFragment(normal_entry, for_effect); 4405 AppendFragment(normal_entry, for_effect);
4449 // Check that the graph is properly terminated. 4406 // Check that the graph is properly terminated.
4450 ASSERT(!for_effect.is_open()); 4407 ASSERT(!for_effect.is_open());
4451 4408
4452 // When compiling for OSR, use a depth first search to prune instructions 4409 // When compiling for OSR, use a depth first search to prune instructions
4453 // unreachable from the OSR entry. Catch entries are always considered 4410 // unreachable from the OSR entry. Catch entries are always considered
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
4492 ASSERT(type.HasResolvedTypeClass()); 4449 ASSERT(type.HasResolvedTypeClass());
4493 const Class& type_class = Class::Handle(type.type_class()); 4450 const Class& type_class = Class::Handle(type.type_class());
4494 // Bail if the type has any type parameters. 4451 // Bail if the type has any type parameters.
4495 if (type_class.IsGeneric()) return false; 4452 if (type_class.IsGeneric()) return false;
4496 4453
4497 // Finally a simple class for instance of checking. 4454 // Finally a simple class for instance of checking.
4498 return true; 4455 return true;
4499 } 4456 }
4500 4457
4501 } // namespace dart 4458 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698