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