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