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

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

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