OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 #if !defined(DART_PRECOMPILED_RUNTIME) | 4 #if !defined(DART_PRECOMPILED_RUNTIME) |
5 #include "vm/flow_graph_inliner.h" | 5 #include "vm/flow_graph_inliner.h" |
6 | 6 |
7 #include "vm/aot_optimizer.h" | 7 #include "vm/aot_optimizer.h" |
8 #include "vm/precompiler.h" | 8 #include "vm/precompiler.h" |
9 #include "vm/block_scheduler.h" | 9 #include "vm/block_scheduler.h" |
10 #include "vm/branch_optimizer.h" | 10 #include "vm/branch_optimizer.h" |
(...skipping 1497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1508 | 1508 |
1509 JoinEntryInstr* new_join = | 1509 JoinEntryInstr* new_join = |
1510 BranchSimplifier::ToJoinEntry(zone(), old_target); | 1510 BranchSimplifier::ToJoinEntry(zone(), old_target); |
1511 old_target->ReplaceAsPredecessorWith(new_join); | 1511 old_target->ReplaceAsPredecessorWith(new_join); |
1512 for (intptr_t j = 0; j < old_target->dominated_blocks().length(); ++j) { | 1512 for (intptr_t j = 0; j < old_target->dominated_blocks().length(); ++j) { |
1513 BlockEntryInstr* block = old_target->dominated_blocks()[j]; | 1513 BlockEntryInstr* block = old_target->dominated_blocks()[j]; |
1514 new_join->AddDominatedBlock(block); | 1514 new_join->AddDominatedBlock(block); |
1515 } | 1515 } |
1516 // Create a new target with the join as unconditional successor. | 1516 // Create a new target with the join as unconditional successor. |
1517 TargetEntryInstr* new_target = | 1517 TargetEntryInstr* new_target = |
1518 new TargetEntryInstr(AllocateBlockId(), old_target->try_index()); | 1518 new TargetEntryInstr(AllocateBlockId(), old_target->try_index(), |
1519 Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:02
kNoDeoptId because InheritDeoptTarget below.
| |
1519 new_target->InheritDeoptTarget(zone(), new_join); | 1520 new_target->InheritDeoptTarget(zone(), new_join); |
1520 GotoInstr* new_goto = new (Z) GotoInstr(new_join); | 1521 GotoInstr* new_goto = |
1522 new (Z) GotoInstr(new_join, Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:02
ditto
| |
1521 new_goto->InheritDeoptTarget(zone(), new_join); | 1523 new_goto->InheritDeoptTarget(zone(), new_join); |
1522 new_target->LinkTo(new_goto); | 1524 new_target->LinkTo(new_goto); |
1523 new_target->set_last_instruction(new_goto); | 1525 new_target->set_last_instruction(new_goto); |
1524 new_join->predecessors_.Add(new_target); | 1526 new_join->predecessors_.Add(new_target); |
1525 | 1527 |
1526 // Record the new target for the first variant. | 1528 // Record the new target for the first variant. |
1527 inlined_entries_[i] = new_target; | 1529 inlined_entries_[i] = new_target; |
1528 } | 1530 } |
1529 ASSERT(inlined_entries_[i]->IsTargetEntry()); | 1531 ASSERT(inlined_entries_[i]->IsTargetEntry()); |
1530 // Record the shared join for this variant. | 1532 // Record the shared join for this variant. |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1650 if (FlowGraphInliner::TryInlineRecognizedMethod( | 1652 if (FlowGraphInliner::TryInlineRecognizedMethod( |
1651 owner_->caller_graph(), receiver_cid, target, call_, redefinition, | 1653 owner_->caller_graph(), receiver_cid, target, call_, redefinition, |
1652 call_->instance_call()->token_pos(), | 1654 call_->instance_call()->token_pos(), |
1653 *call_->instance_call()->ic_data(), &entry, &last)) { | 1655 *call_->instance_call()->ic_data(), &entry, &last)) { |
1654 // Create a graph fragment. | 1656 // Create a graph fragment. |
1655 redefinition->InsertAfter(entry); | 1657 redefinition->InsertAfter(entry); |
1656 InlineExitCollector* exit_collector = | 1658 InlineExitCollector* exit_collector = |
1657 new (Z) InlineExitCollector(owner_->caller_graph(), call_); | 1659 new (Z) InlineExitCollector(owner_->caller_graph(), call_); |
1658 | 1660 |
1659 ReturnInstr* result = new (Z) | 1661 ReturnInstr* result = new (Z) |
1660 ReturnInstr(call_->instance_call()->token_pos(), new (Z) Value(last)); | 1662 ReturnInstr(call_->instance_call()->token_pos(), new (Z) Value(last), |
1663 Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:02
should be call_->deopt_id() I think because we use
| |
1661 owner_->caller_graph()->AppendTo( | 1664 owner_->caller_graph()->AppendTo( |
1662 last, result, | 1665 last, result, |
1663 call_->env(), // Return can become deoptimization target. | 1666 call_->env(), // Return can become deoptimization target. |
1664 FlowGraph::kEffect); | 1667 FlowGraph::kEffect); |
1665 entry->set_last_instruction(result); | 1668 entry->set_last_instruction(result); |
1666 exit_collector->AddExit(result); | 1669 exit_collector->AddExit(result); |
1667 ParsedFunction* temp_parsed_function = | 1670 ParsedFunction* temp_parsed_function = |
1668 new ParsedFunction(Thread::Current(), target); | 1671 new ParsedFunction(Thread::Current(), target); |
1669 GraphEntryInstr* graph_entry = new (Z) | 1672 GraphEntryInstr* graph_entry = new (Z) |
1670 GraphEntryInstr(*temp_parsed_function, entry, Compiler::kNoOSRDeoptId); | 1673 GraphEntryInstr(*temp_parsed_function, entry, Compiler::kNoOSRDeoptId); |
1671 // Update polymorphic inliner state. | 1674 // Update polymorphic inliner state. |
1672 inlined_entries_.Add(graph_entry); | 1675 inlined_entries_.Add(graph_entry); |
1673 exit_collector_->Union(exit_collector); | 1676 exit_collector_->Union(exit_collector); |
1674 return true; | 1677 return true; |
1675 } | 1678 } |
1676 return false; | 1679 return false; |
1677 } | 1680 } |
1678 | 1681 |
1679 | 1682 |
1680 // Build a DAG to dispatch to the inlined function bodies. Load the class | 1683 // Build a DAG to dispatch to the inlined function bodies. Load the class |
1681 // id of the receiver and make explicit comparisons for each inlined body, | 1684 // id of the receiver and make explicit comparisons for each inlined body, |
1682 // in frequency order. If all variants are inlined, the entry to the last | 1685 // in frequency order. If all variants are inlined, the entry to the last |
1683 // inlined body is guarded by a CheckClassId instruction which can deopt. | 1686 // inlined body is guarded by a CheckClassId instruction which can deopt. |
1684 // If not all variants are inlined, we add a PolymorphicInstanceCall | 1687 // If not all variants are inlined, we add a PolymorphicInstanceCall |
1685 // instruction to handle the non-inlined variants. | 1688 // instruction to handle the non-inlined variants. |
1686 TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() { | 1689 TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() { |
1687 const intptr_t try_idx = call_->GetBlock()->try_index(); | 1690 const intptr_t try_idx = call_->GetBlock()->try_index(); |
1688 | 1691 |
1689 // Start with a fresh target entry. | 1692 // Start with a fresh target entry. |
1690 TargetEntryInstr* entry = | 1693 TargetEntryInstr* entry = new (Z) TargetEntryInstr( |
1691 new (Z) TargetEntryInstr(AllocateBlockId(), try_idx); | 1694 AllocateBlockId(), try_idx, Thread::Current()->GetNextDeoptId()); |
Vyacheslav Egorov (Google)
2017/05/23 12:00:02
kNoDeoptId because InheritDeoptTarget below.
| |
1692 entry->InheritDeoptTarget(zone(), call_); | 1695 entry->InheritDeoptTarget(zone(), call_); |
1693 | 1696 |
1694 // This function uses a cursor (a pointer to the 'current' instruction) to | 1697 // This function uses a cursor (a pointer to the 'current' instruction) to |
1695 // build the graph. The next instruction will be inserted after the | 1698 // build the graph. The next instruction will be inserted after the |
1696 // cursor. | 1699 // cursor. |
1697 BlockEntryInstr* current_block = entry; | 1700 BlockEntryInstr* current_block = entry; |
1698 Instruction* cursor = entry; | 1701 Instruction* cursor = entry; |
1699 | 1702 |
1700 Definition* receiver = call_->ArgumentAt(0); | 1703 Definition* receiver = call_->ArgumentAt(0); |
1701 // There are at least two variants including non-inlined ones, so we have | 1704 // There are at least two variants including non-inlined ones, so we have |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1752 for (intptr_t j = 0; j < target->dominated_blocks().length(); ++j) { | 1755 for (intptr_t j = 0; j < target->dominated_blocks().length(); ++j) { |
1753 BlockEntryInstr* block = target->dominated_blocks()[j]; | 1756 BlockEntryInstr* block = target->dominated_blocks()[j]; |
1754 current_block->AddDominatedBlock(block); | 1757 current_block->AddDominatedBlock(block); |
1755 } | 1758 } |
1756 } else if (callee_entry->IsJoinEntry()) { | 1759 } else if (callee_entry->IsJoinEntry()) { |
1757 // Shared inlined body and this is a subsequent entry. We have | 1760 // Shared inlined body and this is a subsequent entry. We have |
1758 // already constructed a join and set its dominator. Add a jump to | 1761 // already constructed a join and set its dominator. Add a jump to |
1759 // the join. | 1762 // the join. |
1760 JoinEntryInstr* join = callee_entry->AsJoinEntry(); | 1763 JoinEntryInstr* join = callee_entry->AsJoinEntry(); |
1761 ASSERT(join->dominator() != NULL); | 1764 ASSERT(join->dominator() != NULL); |
1762 GotoInstr* goto_join = new GotoInstr(join); | 1765 GotoInstr* goto_join = |
1766 new GotoInstr(join, Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:02
kNoDeoptId because InheritDeoptTarget below.
| |
1763 goto_join->InheritDeoptTarget(zone(), join); | 1767 goto_join->InheritDeoptTarget(zone(), join); |
1764 cursor->LinkTo(goto_join); | 1768 cursor->LinkTo(goto_join); |
1765 current_block->set_last_instruction(goto_join); | 1769 current_block->set_last_instruction(goto_join); |
1766 } else { | 1770 } else { |
1767 // There is no possibility of a TargetEntry (the first entry to a | 1771 // There is no possibility of a TargetEntry (the first entry to a |
1768 // shared inlined body) because this is the last inlined entry. | 1772 // shared inlined body) because this is the last inlined entry. |
1769 UNREACHABLE(); | 1773 UNREACHABLE(); |
1770 } | 1774 } |
1771 cursor = NULL; | 1775 cursor = NULL; |
1772 } else { | 1776 } else { |
(...skipping 10 matching lines...) Expand all Loading... | |
1783 // special instruction that uses subtraction and unsigned comparison to | 1787 // special instruction that uses subtraction and unsigned comparison to |
1784 // do this with a single branch. | 1788 // do this with a single branch. |
1785 const Smi& cid_end = Smi::ZoneHandle(Smi::New(variant.cid_end)); | 1789 const Smi& cid_end = Smi::ZoneHandle(Smi::New(variant.cid_end)); |
1786 ConstantInstr* cid_constant_end = | 1790 ConstantInstr* cid_constant_end = |
1787 owner_->caller_graph()->GetConstant(cid_end); | 1791 owner_->caller_graph()->GetConstant(cid_end); |
1788 RelationalOpInstr* compare_top = new RelationalOpInstr( | 1792 RelationalOpInstr* compare_top = new RelationalOpInstr( |
1789 call_->instance_call()->token_pos(), Token::kLTE, | 1793 call_->instance_call()->token_pos(), Token::kLTE, |
1790 new Value(load_cid), new Value(cid_constant_end), kSmiCid, | 1794 new Value(load_cid), new Value(cid_constant_end), kSmiCid, |
1791 call_->deopt_id()); | 1795 call_->deopt_id()); |
1792 BranchInstr* branch_top = upper_limit_branch = | 1796 BranchInstr* branch_top = upper_limit_branch = |
1793 new BranchInstr(compare_top); | 1797 new BranchInstr(compare_top, Thread::Current()->GetNextDeoptId()); |
Vyacheslav Egorov (Google)
2017/05/23 12:00:03
kNoDeoptId because InheritDeoptTarget below.
| |
1794 branch_top->InheritDeoptTarget(zone(), call_); | 1798 branch_top->InheritDeoptTarget(zone(), call_); |
1795 cursor = AppendInstruction(cursor, branch_top); | 1799 cursor = AppendInstruction(cursor, branch_top); |
1796 current_block->set_last_instruction(branch_top); | 1800 current_block->set_last_instruction(branch_top); |
1797 | 1801 |
1798 TargetEntryInstr* below_target = | 1802 TargetEntryInstr* below_target = new TargetEntryInstr( |
1799 new TargetEntryInstr(AllocateBlockId(), try_idx); | 1803 AllocateBlockId(), try_idx, Thread::Current()->GetNextDeoptId()); |
Vyacheslav Egorov (Google)
2017/05/23 12:00:02
kNoDeoptId because InheritDeoptTarget below.
| |
1800 below_target->InheritDeoptTarget(zone(), call_); | 1804 below_target->InheritDeoptTarget(zone(), call_); |
1801 current_block->AddDominatedBlock(below_target); | 1805 current_block->AddDominatedBlock(below_target); |
1802 cursor = current_block = below_target; | 1806 cursor = current_block = below_target; |
1803 *branch_top->true_successor_address() = below_target; | 1807 *branch_top->true_successor_address() = below_target; |
1804 | 1808 |
1805 RelationalOpInstr* compare_bottom = new RelationalOpInstr( | 1809 RelationalOpInstr* compare_bottom = new RelationalOpInstr( |
1806 call_->instance_call()->token_pos(), Token::kGTE, | 1810 call_->instance_call()->token_pos(), Token::kGTE, |
1807 new Value(load_cid), new Value(cid_constant), kSmiCid, | 1811 new Value(load_cid), new Value(cid_constant), kSmiCid, |
1808 call_->deopt_id()); | 1812 call_->deopt_id()); |
1809 branch = new BranchInstr(compare_bottom); | 1813 branch = new BranchInstr(compare_bottom, |
1814 Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:02
kNoDeoptId because InheritDeoptTarget below.
| |
1810 } else { | 1815 } else { |
1811 StrictCompareInstr* compare = new StrictCompareInstr( | 1816 StrictCompareInstr* compare = new StrictCompareInstr( |
1812 call_->instance_call()->token_pos(), Token::kEQ_STRICT, | 1817 call_->instance_call()->token_pos(), Token::kEQ_STRICT, |
1813 new Value(load_cid), new Value(cid_constant), | 1818 new Value(load_cid), new Value(cid_constant), false, |
Vyacheslav Egorov (Google)
2017/05/23 12:00:02
/* number_check = */ false
because comment moved
| |
1814 false); // No number check. | 1819 Thread::Current()->GetNextDeoptId()); // No number check. |
Vyacheslav Egorov (Google)
2017/05/23 12:00:02
kNoDeoptId because StrictCompareInstr never deopts
| |
1815 branch = new BranchInstr(compare); | 1820 branch = new BranchInstr(compare, Thread::Current()->GetNextDeoptId()); |
Vyacheslav Egorov (Google)
2017/05/23 12:00:03
kNoDeoptId because InheritDeoptTarget below.
| |
1816 } | 1821 } |
1817 | 1822 |
1818 branch->InheritDeoptTarget(zone(), call_); | 1823 branch->InheritDeoptTarget(zone(), call_); |
1819 cursor = AppendInstruction(cursor, branch); | 1824 cursor = AppendInstruction(cursor, branch); |
1820 current_block->set_last_instruction(branch); | 1825 current_block->set_last_instruction(branch); |
1821 cursor = NULL; | 1826 cursor = NULL; |
1822 | 1827 |
1823 // 2. Handle a match by linking to the inlined body. There are three | 1828 // 2. Handle a match by linking to the inlined body. There are three |
1824 // cases (unshared, shared first predecessor, and shared subsequent | 1829 // cases (unshared, shared first predecessor, and shared subsequent |
1825 // predecessors). | 1830 // predecessors). |
(...skipping 10 matching lines...) Expand all Loading... | |
1836 true_target = callee_entry->AsTargetEntry(); | 1841 true_target = callee_entry->AsTargetEntry(); |
1837 BlockEntryInstr* join = true_target->last_instruction()->SuccessorAt(0); | 1842 BlockEntryInstr* join = true_target->last_instruction()->SuccessorAt(0); |
1838 current_block->AddDominatedBlock(join); | 1843 current_block->AddDominatedBlock(join); |
1839 } else { | 1844 } else { |
1840 // Shared inlined body and this is a subsequent entry. We have | 1845 // Shared inlined body and this is a subsequent entry. We have |
1841 // already constructed a join. We need a fresh target that jumps to | 1846 // already constructed a join. We need a fresh target that jumps to |
1842 // the join. | 1847 // the join. |
1843 JoinEntryInstr* join = callee_entry->AsJoinEntry(); | 1848 JoinEntryInstr* join = callee_entry->AsJoinEntry(); |
1844 ASSERT(join != NULL); | 1849 ASSERT(join != NULL); |
1845 ASSERT(join->dominator() != NULL); | 1850 ASSERT(join->dominator() != NULL); |
1846 true_target = new TargetEntryInstr(AllocateBlockId(), try_idx); | 1851 true_target = new TargetEntryInstr(AllocateBlockId(), try_idx, |
1852 Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:03
kNoDeoptId because InheritDeoptTarget below.
| |
1847 true_target->InheritDeoptTarget(zone(), join); | 1853 true_target->InheritDeoptTarget(zone(), join); |
1848 GotoInstr* goto_join = new GotoInstr(join); | 1854 GotoInstr* goto_join = |
1855 new GotoInstr(join, Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:02
kNoDeoptId because InheritDeoptTarget below.
| |
1849 goto_join->InheritDeoptTarget(zone(), join); | 1856 goto_join->InheritDeoptTarget(zone(), join); |
1850 true_target->LinkTo(goto_join); | 1857 true_target->LinkTo(goto_join); |
1851 true_target->set_last_instruction(goto_join); | 1858 true_target->set_last_instruction(goto_join); |
1852 } | 1859 } |
1853 *branch->true_successor_address() = true_target; | 1860 *branch->true_successor_address() = true_target; |
1854 current_block->AddDominatedBlock(true_target); | 1861 current_block->AddDominatedBlock(true_target); |
1855 | 1862 |
1856 // 3. Prepare to handle a match failure on the next iteration or the | 1863 // 3. Prepare to handle a match failure on the next iteration or the |
1857 // fall-through code below for non-inlined variants. | 1864 // fall-through code below for non-inlined variants. |
1858 | 1865 |
1859 TargetEntryInstr* false_target = | 1866 TargetEntryInstr* false_target = new TargetEntryInstr( |
1860 new TargetEntryInstr(AllocateBlockId(), try_idx); | 1867 AllocateBlockId(), try_idx, Thread::Current()->GetNextDeoptId()); |
Vyacheslav Egorov (Google)
2017/05/23 12:00:02
kNoDeoptId because InheritDeoptTarget below.
| |
1861 false_target->InheritDeoptTarget(zone(), call_); | 1868 false_target->InheritDeoptTarget(zone(), call_); |
1862 *branch->false_successor_address() = false_target; | 1869 *branch->false_successor_address() = false_target; |
1863 cid_test_entry_block->AddDominatedBlock(false_target); | 1870 cid_test_entry_block->AddDominatedBlock(false_target); |
1864 | 1871 |
1865 cursor = current_block = false_target; | 1872 cursor = current_block = false_target; |
1866 | 1873 |
1867 if (test_is_range) { | 1874 if (test_is_range) { |
1868 // If we tested against a range of Cids there are two different tests | 1875 // If we tested against a range of Cids there are two different tests |
1869 // that can go to the no-cid-match target. | 1876 // that can go to the no-cid-match target. |
1870 JoinEntryInstr* join = new JoinEntryInstr(AllocateBlockId(), try_idx); | 1877 JoinEntryInstr* join = new JoinEntryInstr( |
1871 TargetEntryInstr* false_target2 = | 1878 AllocateBlockId(), try_idx, Thread::Current()->GetNextDeoptId()); |
Vyacheslav Egorov (Google)
2017/05/23 12:00:02
kNoDeoptId because InheritDeoptTarget below.
| |
1872 new TargetEntryInstr(AllocateBlockId(), try_idx); | 1879 TargetEntryInstr* false_target2 = new TargetEntryInstr( |
1880 AllocateBlockId(), try_idx, Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:03
kNoDeoptId because InheritDeoptTarget below.
| |
1873 *upper_limit_branch->false_successor_address() = false_target2; | 1881 *upper_limit_branch->false_successor_address() = false_target2; |
1874 cid_test_entry_block->AddDominatedBlock(false_target2); | 1882 cid_test_entry_block->AddDominatedBlock(false_target2); |
1875 cid_test_entry_block->AddDominatedBlock(join); | 1883 cid_test_entry_block->AddDominatedBlock(join); |
1876 GotoInstr* goto_1 = new GotoInstr(join); | 1884 GotoInstr* goto_1 = |
1877 GotoInstr* goto_2 = new GotoInstr(join); | 1885 new GotoInstr(join, Thread::Current()->GetNextDeoptId()); |
Vyacheslav Egorov (Google)
2017/05/23 12:00:02
kNoDeoptId because InheritDeoptTarget below.
| |
1886 GotoInstr* goto_2 = | |
1887 new GotoInstr(join, Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:02
kNoDeoptId because InheritDeoptTarget below.
| |
1878 false_target->LinkTo(goto_1); | 1888 false_target->LinkTo(goto_1); |
1879 false_target2->LinkTo(goto_2); | 1889 false_target2->LinkTo(goto_2); |
1880 false_target->set_last_instruction(goto_1); | 1890 false_target->set_last_instruction(goto_1); |
1881 false_target2->set_last_instruction(goto_2); | 1891 false_target2->set_last_instruction(goto_2); |
1882 | 1892 |
1883 join->InheritDeoptTarget(zone(), call_); | 1893 join->InheritDeoptTarget(zone(), call_); |
1884 false_target2->InheritDeoptTarget(zone(), call_); | 1894 false_target2->InheritDeoptTarget(zone(), call_); |
1885 goto_1->InheritDeoptTarget(zone(), call_); | 1895 goto_1->InheritDeoptTarget(zone(), call_); |
1886 goto_2->InheritDeoptTarget(zone(), call_); | 1896 goto_2->InheritDeoptTarget(zone(), call_); |
1887 | 1897 |
(...skipping 14 matching lines...) Expand all Loading... | |
1902 } | 1912 } |
1903 PolymorphicInstanceCallInstr* fallback_call = | 1913 PolymorphicInstanceCallInstr* fallback_call = |
1904 new PolymorphicInstanceCallInstr( | 1914 new PolymorphicInstanceCallInstr( |
1905 call_->instance_call(), *non_inlined_variants_, | 1915 call_->instance_call(), *non_inlined_variants_, |
1906 /* with_checks = */ true, call_->complete()); | 1916 /* with_checks = */ true, call_->complete()); |
1907 fallback_call->set_ssa_temp_index( | 1917 fallback_call->set_ssa_temp_index( |
1908 owner_->caller_graph()->alloc_ssa_temp_index()); | 1918 owner_->caller_graph()->alloc_ssa_temp_index()); |
1909 fallback_call->InheritDeoptTarget(zone(), call_); | 1919 fallback_call->InheritDeoptTarget(zone(), call_); |
1910 fallback_call->set_total_call_count(call_->CallCount()); | 1920 fallback_call->set_total_call_count(call_->CallCount()); |
1911 ReturnInstr* fallback_return = new ReturnInstr( | 1921 ReturnInstr* fallback_return = new ReturnInstr( |
1912 call_->instance_call()->token_pos(), new Value(fallback_call)); | 1922 call_->instance_call()->token_pos(), new Value(fallback_call), |
1923 Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:02
kNoDeoptId because InheritDeoptTarget below.
| |
1913 fallback_return->InheritDeoptTargetAfter(owner_->caller_graph(), call_, | 1924 fallback_return->InheritDeoptTargetAfter(owner_->caller_graph(), call_, |
1914 fallback_call); | 1925 fallback_call); |
1915 AppendInstruction(AppendInstruction(cursor, fallback_call), | 1926 AppendInstruction(AppendInstruction(cursor, fallback_call), |
1916 fallback_return); | 1927 fallback_return); |
1917 exit_collector_->AddExit(fallback_return); | 1928 exit_collector_->AddExit(fallback_return); |
1918 cursor = NULL; | 1929 cursor = NULL; |
1919 } else { | 1930 } else { |
1920 if (follow_with_deopt) { | 1931 if (follow_with_deopt) { |
1921 DeoptimizeInstr* deopt = new DeoptimizeInstr( | 1932 DeoptimizeInstr* deopt = new DeoptimizeInstr( |
1922 ICData::kDeoptPolymorphicInstanceCallTestFail, call_->deopt_id()); | 1933 ICData::kDeoptPolymorphicInstanceCallTestFail, call_->deopt_id()); |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2287 MethodRecognizer::Kind kind, | 2298 MethodRecognizer::Kind kind, |
2288 Instruction* call, | 2299 Instruction* call, |
2289 Definition* receiver, | 2300 Definition* receiver, |
2290 TargetEntryInstr** entry, | 2301 TargetEntryInstr** entry, |
2291 Definition** last) { | 2302 Definition** last) { |
2292 intptr_t array_cid = MethodRecognizer::MethodKindToReceiverCid(kind); | 2303 intptr_t array_cid = MethodRecognizer::MethodKindToReceiverCid(kind); |
2293 | 2304 |
2294 Definition* array = receiver; | 2305 Definition* array = receiver; |
2295 Definition* index = call->ArgumentAt(1); | 2306 Definition* index = call->ArgumentAt(1); |
2296 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 2307 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
2297 call->GetBlock()->try_index()); | 2308 call->GetBlock()->try_index(), |
2309 Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:01
kNoDeoptId because InheritDeoptTarget below.
| |
2298 (*entry)->InheritDeoptTarget(Z, call); | 2310 (*entry)->InheritDeoptTarget(Z, call); |
2299 Instruction* cursor = *entry; | 2311 Instruction* cursor = *entry; |
2300 | 2312 |
2301 array_cid = PrepareInlineIndexedOp(flow_graph, call, array_cid, &array, index, | 2313 array_cid = PrepareInlineIndexedOp(flow_graph, call, array_cid, &array, index, |
2302 &cursor); | 2314 &cursor); |
2303 | 2315 |
2304 intptr_t deopt_id = Thread::kNoDeoptId; | 2316 intptr_t deopt_id = Thread::kNoDeoptId; |
2305 if ((array_cid == kTypedDataInt32ArrayCid) || | 2317 if ((array_cid == kTypedDataInt32ArrayCid) || |
2306 (array_cid == kTypedDataUint32ArrayCid)) { | 2318 (array_cid == kTypedDataUint32ArrayCid)) { |
2307 // Deoptimization may be needed if result does not always fit in a Smi. | 2319 // Deoptimization may be needed if result does not always fit in a Smi. |
(...skipping 28 matching lines...) Expand all Loading... | |
2336 const Cids* value_check, | 2348 const Cids* value_check, |
2337 TargetEntryInstr** entry, | 2349 TargetEntryInstr** entry, |
2338 Definition** last) { | 2350 Definition** last) { |
2339 intptr_t array_cid = MethodRecognizer::MethodKindToReceiverCid(kind); | 2351 intptr_t array_cid = MethodRecognizer::MethodKindToReceiverCid(kind); |
2340 | 2352 |
2341 Definition* array = receiver; | 2353 Definition* array = receiver; |
2342 Definition* index = call->ArgumentAt(1); | 2354 Definition* index = call->ArgumentAt(1); |
2343 Definition* stored_value = call->ArgumentAt(2); | 2355 Definition* stored_value = call->ArgumentAt(2); |
2344 | 2356 |
2345 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 2357 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
2346 call->GetBlock()->try_index()); | 2358 call->GetBlock()->try_index(), |
2359 Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:02
kNoDeoptId because InheritDeoptTarget below.
| |
2347 (*entry)->InheritDeoptTarget(Z, call); | 2360 (*entry)->InheritDeoptTarget(Z, call); |
2348 Instruction* cursor = *entry; | 2361 Instruction* cursor = *entry; |
2349 if (flow_graph->isolate()->type_checks()) { | 2362 if (flow_graph->isolate()->type_checks()) { |
2350 // Only type check for the value. A type check for the index is not | 2363 // Only type check for the value. A type check for the index is not |
2351 // needed here because we insert a deoptimizing smi-check for the case | 2364 // needed here because we insert a deoptimizing smi-check for the case |
2352 // the index is not a smi. | 2365 // the index is not a smi. |
2353 const AbstractType& value_type = | 2366 const AbstractType& value_type = |
2354 AbstractType::ZoneHandle(Z, target.ParameterTypeAt(2)); | 2367 AbstractType::ZoneHandle(Z, target.ParameterTypeAt(2)); |
2355 Definition* type_args = NULL; | 2368 Definition* type_args = NULL; |
2356 switch (array_cid) { | 2369 switch (array_cid) { |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2473 Definition* receiver, | 2486 Definition* receiver, |
2474 TargetEntryInstr** entry, | 2487 TargetEntryInstr** entry, |
2475 Definition** last) { | 2488 Definition** last) { |
2476 if (!CanUnboxDouble()) { | 2489 if (!CanUnboxDouble()) { |
2477 return false; | 2490 return false; |
2478 } | 2491 } |
2479 Definition* left = receiver; | 2492 Definition* left = receiver; |
2480 Definition* right = call->ArgumentAt(1); | 2493 Definition* right = call->ArgumentAt(1); |
2481 | 2494 |
2482 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 2495 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
2483 call->GetBlock()->try_index()); | 2496 call->GetBlock()->try_index(), |
2497 Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:02
kNoDeoptId because InheritDeoptTarget below.
| |
2484 (*entry)->InheritDeoptTarget(Z, call); | 2498 (*entry)->InheritDeoptTarget(Z, call); |
2485 // Arguments are checked. No need for class check. | 2499 // Arguments are checked. No need for class check. |
2486 BinaryDoubleOpInstr* double_bin_op = new (Z) | 2500 BinaryDoubleOpInstr* double_bin_op = new (Z) |
2487 BinaryDoubleOpInstr(op_kind, new (Z) Value(left), new (Z) Value(right), | 2501 BinaryDoubleOpInstr(op_kind, new (Z) Value(left), new (Z) Value(right), |
2488 call->deopt_id(), call->token_pos()); | 2502 call->deopt_id(), call->token_pos()); |
2489 flow_graph->AppendTo(*entry, double_bin_op, call->env(), FlowGraph::kValue); | 2503 flow_graph->AppendTo(*entry, double_bin_op, call->env(), FlowGraph::kValue); |
2490 *last = double_bin_op; | 2504 *last = double_bin_op; |
2491 | 2505 |
2492 return true; | 2506 return true; |
2493 } | 2507 } |
2494 | 2508 |
2495 | 2509 |
2496 static bool InlineDoubleTestOp(FlowGraph* flow_graph, | 2510 static bool InlineDoubleTestOp(FlowGraph* flow_graph, |
2497 Instruction* call, | 2511 Instruction* call, |
2498 Definition* receiver, | 2512 Definition* receiver, |
2499 MethodRecognizer::Kind kind, | 2513 MethodRecognizer::Kind kind, |
2500 TargetEntryInstr** entry, | 2514 TargetEntryInstr** entry, |
2501 Definition** last) { | 2515 Definition** last) { |
2502 if (!CanUnboxDouble()) { | 2516 if (!CanUnboxDouble()) { |
2503 return false; | 2517 return false; |
2504 } | 2518 } |
2505 | 2519 |
2506 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 2520 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
2507 call->GetBlock()->try_index()); | 2521 call->GetBlock()->try_index(), |
2522 Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:03
kNoDeoptId because InheritDeoptTarget below.
| |
2508 (*entry)->InheritDeoptTarget(Z, call); | 2523 (*entry)->InheritDeoptTarget(Z, call); |
2509 // Arguments are checked. No need for class check. | 2524 // Arguments are checked. No need for class check. |
2510 | 2525 |
2511 DoubleTestOpInstr* double_test_op = new (Z) DoubleTestOpInstr( | 2526 DoubleTestOpInstr* double_test_op = new (Z) DoubleTestOpInstr( |
2512 kind, new (Z) Value(receiver), call->deopt_id(), call->token_pos()); | 2527 kind, new (Z) Value(receiver), call->deopt_id(), call->token_pos()); |
2513 flow_graph->AppendTo(*entry, double_test_op, call->env(), FlowGraph::kValue); | 2528 flow_graph->AppendTo(*entry, double_test_op, call->env(), FlowGraph::kValue); |
2514 *last = double_test_op; | 2529 *last = double_test_op; |
2515 | 2530 |
2516 return true; | 2531 return true; |
2517 } | 2532 } |
2518 | 2533 |
2519 | 2534 |
2520 static bool InlineSmiBitAndFromSmi(FlowGraph* flow_graph, | 2535 static bool InlineSmiBitAndFromSmi(FlowGraph* flow_graph, |
2521 Instruction* call, | 2536 Instruction* call, |
2522 Definition* receiver, | 2537 Definition* receiver, |
2523 TargetEntryInstr** entry, | 2538 TargetEntryInstr** entry, |
2524 Definition** last) { | 2539 Definition** last) { |
2525 Definition* left = receiver; | 2540 Definition* left = receiver; |
2526 Definition* right = call->ArgumentAt(1); | 2541 Definition* right = call->ArgumentAt(1); |
2527 | 2542 |
2528 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 2543 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
2529 call->GetBlock()->try_index()); | 2544 call->GetBlock()->try_index(), |
2545 Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:01
kNoDeoptId because InheritDeoptTarget below.
| |
2530 (*entry)->InheritDeoptTarget(Z, call); | 2546 (*entry)->InheritDeoptTarget(Z, call); |
2531 // Right arguments is known to be smi: other._bitAndFromSmi(this); | 2547 // Right arguments is known to be smi: other._bitAndFromSmi(this); |
2532 BinarySmiOpInstr* smi_op = | 2548 BinarySmiOpInstr* smi_op = |
2533 new (Z) BinarySmiOpInstr(Token::kBIT_AND, new (Z) Value(left), | 2549 new (Z) BinarySmiOpInstr(Token::kBIT_AND, new (Z) Value(left), |
2534 new (Z) Value(right), call->deopt_id()); | 2550 new (Z) Value(right), call->deopt_id()); |
2535 flow_graph->AppendTo(*entry, smi_op, call->env(), FlowGraph::kValue); | 2551 flow_graph->AppendTo(*entry, smi_op, call->env(), FlowGraph::kValue); |
2536 *last = smi_op; | 2552 *last = smi_op; |
2537 | 2553 |
2538 return true; | 2554 return true; |
2539 } | 2555 } |
2540 | 2556 |
2541 | 2557 |
2542 static bool InlineGrowableArraySetter(FlowGraph* flow_graph, | 2558 static bool InlineGrowableArraySetter(FlowGraph* flow_graph, |
2543 intptr_t offset, | 2559 intptr_t offset, |
2544 StoreBarrierType store_barrier_type, | 2560 StoreBarrierType store_barrier_type, |
2545 Instruction* call, | 2561 Instruction* call, |
2546 Definition* receiver, | 2562 Definition* receiver, |
2547 TargetEntryInstr** entry, | 2563 TargetEntryInstr** entry, |
2548 Definition** last) { | 2564 Definition** last) { |
2549 Definition* array = receiver; | 2565 Definition* array = receiver; |
2550 Definition* value = call->ArgumentAt(1); | 2566 Definition* value = call->ArgumentAt(1); |
2551 | 2567 |
2552 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 2568 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
2553 call->GetBlock()->try_index()); | 2569 call->GetBlock()->try_index(), |
2570 Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:03
kNoDeoptId because InheritDeoptTarget below.
| |
2554 (*entry)->InheritDeoptTarget(Z, call); | 2571 (*entry)->InheritDeoptTarget(Z, call); |
2555 | 2572 |
2556 // This is an internal method, no need to check argument types. | 2573 // This is an internal method, no need to check argument types. |
2557 StoreInstanceFieldInstr* store = new (Z) StoreInstanceFieldInstr( | 2574 StoreInstanceFieldInstr* store = new (Z) StoreInstanceFieldInstr( |
2558 offset, new (Z) Value(array), new (Z) Value(value), store_barrier_type, | 2575 offset, new (Z) Value(array), new (Z) Value(value), store_barrier_type, |
2559 call->token_pos()); | 2576 call->token_pos()); |
2560 flow_graph->AppendTo(*entry, store, call->env(), FlowGraph::kEffect); | 2577 flow_graph->AppendTo(*entry, store, call->env(), FlowGraph::kEffect); |
2561 *last = store; | 2578 *last = store; |
2562 | 2579 |
2563 return true; | 2580 return true; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2629 Instruction* call, | 2646 Instruction* call, |
2630 Definition* receiver, | 2647 Definition* receiver, |
2631 intptr_t array_cid, | 2648 intptr_t array_cid, |
2632 intptr_t view_cid, | 2649 intptr_t view_cid, |
2633 TargetEntryInstr** entry, | 2650 TargetEntryInstr** entry, |
2634 Definition** last) { | 2651 Definition** last) { |
2635 ASSERT(array_cid != kIllegalCid); | 2652 ASSERT(array_cid != kIllegalCid); |
2636 Definition* array = receiver; | 2653 Definition* array = receiver; |
2637 Definition* index = call->ArgumentAt(1); | 2654 Definition* index = call->ArgumentAt(1); |
2638 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 2655 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
2639 call->GetBlock()->try_index()); | 2656 call->GetBlock()->try_index(), |
2657 Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:02
kNoDeoptId because InheritDeoptTarget below.
| |
2640 (*entry)->InheritDeoptTarget(Z, call); | 2658 (*entry)->InheritDeoptTarget(Z, call); |
2641 Instruction* cursor = *entry; | 2659 Instruction* cursor = *entry; |
2642 | 2660 |
2643 PrepareInlineByteArrayBaseOp(flow_graph, call, array_cid, view_cid, &array, | 2661 PrepareInlineByteArrayBaseOp(flow_graph, call, array_cid, view_cid, &array, |
2644 index, &cursor); | 2662 index, &cursor); |
2645 | 2663 |
2646 intptr_t deopt_id = Thread::kNoDeoptId; | 2664 intptr_t deopt_id = Thread::kNoDeoptId; |
2647 if ((array_cid == kTypedDataInt32ArrayCid) || | 2665 if ((array_cid == kTypedDataInt32ArrayCid) || |
2648 (array_cid == kTypedDataUint32ArrayCid)) { | 2666 (array_cid == kTypedDataUint32ArrayCid)) { |
2649 // Deoptimization may be needed if result does not always fit in a Smi. | 2667 // Deoptimization may be needed if result does not always fit in a Smi. |
(...skipping 22 matching lines...) Expand all Loading... | |
2672 Instruction* call, | 2690 Instruction* call, |
2673 Definition* receiver, | 2691 Definition* receiver, |
2674 intptr_t array_cid, | 2692 intptr_t array_cid, |
2675 intptr_t view_cid, | 2693 intptr_t view_cid, |
2676 TargetEntryInstr** entry, | 2694 TargetEntryInstr** entry, |
2677 Definition** last) { | 2695 Definition** last) { |
2678 ASSERT(array_cid != kIllegalCid); | 2696 ASSERT(array_cid != kIllegalCid); |
2679 Definition* array = receiver; | 2697 Definition* array = receiver; |
2680 Definition* index = call->ArgumentAt(1); | 2698 Definition* index = call->ArgumentAt(1); |
2681 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 2699 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
2682 call->GetBlock()->try_index()); | 2700 call->GetBlock()->try_index(), |
2701 Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:02
kNoDeoptId because InheritDeoptTarget below.
| |
2683 (*entry)->InheritDeoptTarget(Z, call); | 2702 (*entry)->InheritDeoptTarget(Z, call); |
2684 Instruction* cursor = *entry; | 2703 Instruction* cursor = *entry; |
2685 | 2704 |
2686 PrepareInlineByteArrayBaseOp(flow_graph, call, array_cid, view_cid, &array, | 2705 PrepareInlineByteArrayBaseOp(flow_graph, call, array_cid, view_cid, &array, |
2687 index, &cursor); | 2706 index, &cursor); |
2688 | 2707 |
2689 // Extract the instance call so we can use the function_name in the stored | 2708 // Extract the instance call so we can use the function_name in the stored |
2690 // value check ICData. | 2709 // value check ICData. |
2691 InstanceCallInstr* i_call = NULL; | 2710 InstanceCallInstr* i_call = NULL; |
2692 if (call->IsPolymorphicInstanceCall()) { | 2711 if (call->IsPolymorphicInstanceCall()) { |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2838 intptr_t cid, | 2857 intptr_t cid, |
2839 TargetEntryInstr** entry, | 2858 TargetEntryInstr** entry, |
2840 Definition** last) { | 2859 Definition** last) { |
2841 if ((cid != kOneByteStringCid) && (cid != kExternalOneByteStringCid)) { | 2860 if ((cid != kOneByteStringCid) && (cid != kExternalOneByteStringCid)) { |
2842 return false; | 2861 return false; |
2843 } | 2862 } |
2844 Definition* str = receiver; | 2863 Definition* str = receiver; |
2845 Definition* index = call->ArgumentAt(1); | 2864 Definition* index = call->ArgumentAt(1); |
2846 | 2865 |
2847 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 2866 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
2848 call->GetBlock()->try_index()); | 2867 call->GetBlock()->try_index(), |
2868 Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:01
kNoDeoptId because InheritDeoptTarget below.
| |
2849 (*entry)->InheritDeoptTarget(Z, call); | 2869 (*entry)->InheritDeoptTarget(Z, call); |
2850 | 2870 |
2851 *last = PrepareInlineStringIndexOp(flow_graph, call, cid, str, index, *entry); | 2871 *last = PrepareInlineStringIndexOp(flow_graph, call, cid, str, index, *entry); |
2852 | 2872 |
2853 OneByteStringFromCharCodeInstr* char_at = | 2873 OneByteStringFromCharCodeInstr* char_at = |
2854 new (Z) OneByteStringFromCharCodeInstr(new (Z) Value(*last)); | 2874 new (Z) OneByteStringFromCharCodeInstr(new (Z) Value(*last)); |
2855 | 2875 |
2856 flow_graph->AppendTo(*last, char_at, NULL, FlowGraph::kValue); | 2876 flow_graph->AppendTo(*last, char_at, NULL, FlowGraph::kValue); |
2857 *last = char_at; | 2877 *last = char_at; |
2858 | 2878 |
2859 return true; | 2879 return true; |
2860 } | 2880 } |
2861 | 2881 |
2862 | 2882 |
2863 static bool InlineStringCodeUnitAt(FlowGraph* flow_graph, | 2883 static bool InlineStringCodeUnitAt(FlowGraph* flow_graph, |
2864 Instruction* call, | 2884 Instruction* call, |
2865 Definition* receiver, | 2885 Definition* receiver, |
2866 intptr_t cid, | 2886 intptr_t cid, |
2867 TargetEntryInstr** entry, | 2887 TargetEntryInstr** entry, |
2868 Definition** last) { | 2888 Definition** last) { |
2869 ASSERT((cid == kOneByteStringCid) || (cid == kTwoByteStringCid) || | 2889 ASSERT((cid == kOneByteStringCid) || (cid == kTwoByteStringCid) || |
2870 (cid == kExternalOneByteStringCid) || | 2890 (cid == kExternalOneByteStringCid) || |
2871 (cid == kExternalTwoByteStringCid)); | 2891 (cid == kExternalTwoByteStringCid)); |
2872 Definition* str = receiver; | 2892 Definition* str = receiver; |
2873 Definition* index = call->ArgumentAt(1); | 2893 Definition* index = call->ArgumentAt(1); |
2874 | 2894 |
2875 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 2895 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
2876 call->GetBlock()->try_index()); | 2896 call->GetBlock()->try_index(), |
2897 Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:02
kNoDeoptId because InheritDeoptTarget below.
| |
2877 (*entry)->InheritDeoptTarget(Z, call); | 2898 (*entry)->InheritDeoptTarget(Z, call); |
2878 | 2899 |
2879 *last = PrepareInlineStringIndexOp(flow_graph, call, cid, str, index, *entry); | 2900 *last = PrepareInlineStringIndexOp(flow_graph, call, cid, str, index, *entry); |
2880 | 2901 |
2881 return true; | 2902 return true; |
2882 } | 2903 } |
2883 | 2904 |
2884 | 2905 |
2885 // Only used for monomorphic calls. | 2906 // Only used for monomorphic calls. |
2886 bool FlowGraphInliner::TryReplaceInstanceCallWithInline( | 2907 bool FlowGraphInliner::TryReplaceInstanceCallWithInline( |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2979 Instruction* call, | 3000 Instruction* call, |
2980 Definition* receiver, | 3001 Definition* receiver, |
2981 MethodRecognizer::Kind kind, | 3002 MethodRecognizer::Kind kind, |
2982 TargetEntryInstr** entry, | 3003 TargetEntryInstr** entry, |
2983 Definition** last) { | 3004 Definition** last) { |
2984 if (!ShouldInlineSimd()) { | 3005 if (!ShouldInlineSimd()) { |
2985 return false; | 3006 return false; |
2986 } | 3007 } |
2987 | 3008 |
2988 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 3009 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
2989 call->GetBlock()->try_index()); | 3010 call->GetBlock()->try_index(), |
3011 Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:03
kNoDeoptId because InheritDeoptTarget below.
| |
2990 (*entry)->InheritDeoptTarget(Z, call); | 3012 (*entry)->InheritDeoptTarget(Z, call); |
2991 Instruction* cursor = *entry; | 3013 Instruction* cursor = *entry; |
2992 switch (kind) { | 3014 switch (kind) { |
2993 case MethodRecognizer::kFloat32x4ShuffleX: | 3015 case MethodRecognizer::kFloat32x4ShuffleX: |
2994 case MethodRecognizer::kFloat32x4ShuffleY: | 3016 case MethodRecognizer::kFloat32x4ShuffleY: |
2995 case MethodRecognizer::kFloat32x4ShuffleZ: | 3017 case MethodRecognizer::kFloat32x4ShuffleZ: |
2996 case MethodRecognizer::kFloat32x4ShuffleW: { | 3018 case MethodRecognizer::kFloat32x4ShuffleW: { |
2997 *last = new (Z) Simd32x4ShuffleInstr(kind, new (Z) Value(receiver), | 3019 *last = new (Z) Simd32x4ShuffleInstr(kind, new (Z) Value(receiver), |
2998 0, // mask ignored. | 3020 0, // mask ignored. |
2999 call->deopt_id()); | 3021 call->deopt_id()); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3097 static bool InlineSimdShuffleMethod(FlowGraph* flow_graph, | 3119 static bool InlineSimdShuffleMethod(FlowGraph* flow_graph, |
3098 Instruction* call, | 3120 Instruction* call, |
3099 Definition* receiver, | 3121 Definition* receiver, |
3100 MethodRecognizer::Kind kind, | 3122 MethodRecognizer::Kind kind, |
3101 TargetEntryInstr** entry, | 3123 TargetEntryInstr** entry, |
3102 Definition** last) { | 3124 Definition** last) { |
3103 if (!ShouldInlineSimd()) { | 3125 if (!ShouldInlineSimd()) { |
3104 return false; | 3126 return false; |
3105 } | 3127 } |
3106 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 3128 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
3107 call->GetBlock()->try_index()); | 3129 call->GetBlock()->try_index(), |
3130 Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:03
kNoDeoptId because InheritDeoptTarget below.
| |
3108 (*entry)->InheritDeoptTarget(Z, call); | 3131 (*entry)->InheritDeoptTarget(Z, call); |
3109 Instruction* cursor = *entry; | 3132 Instruction* cursor = *entry; |
3110 Definition* mask_definition = call->ArgumentAt(1); | 3133 Definition* mask_definition = call->ArgumentAt(1); |
3111 intptr_t mask = 0; | 3134 intptr_t mask = 0; |
3112 if (!CheckMask(mask_definition, &mask)) { | 3135 if (!CheckMask(mask_definition, &mask)) { |
3113 return false; | 3136 return false; |
3114 } | 3137 } |
3115 *last = new (Z) Simd32x4ShuffleInstr(kind, new (Z) Value(call->ArgumentAt(0)), | 3138 *last = new (Z) Simd32x4ShuffleInstr(kind, new (Z) Value(call->ArgumentAt(0)), |
3116 mask, call->deopt_id()); | 3139 mask, call->deopt_id()); |
3117 flow_graph->AppendTo( | 3140 flow_graph->AppendTo( |
3118 cursor, *last, | 3141 cursor, *last, |
3119 call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL, | 3142 call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL, |
3120 FlowGraph::kValue); | 3143 FlowGraph::kValue); |
3121 return true; | 3144 return true; |
3122 } | 3145 } |
3123 | 3146 |
3124 | 3147 |
3125 static bool InlineSimdShuffleMixMethod(FlowGraph* flow_graph, | 3148 static bool InlineSimdShuffleMixMethod(FlowGraph* flow_graph, |
3126 Instruction* call, | 3149 Instruction* call, |
3127 Definition* receiver, | 3150 Definition* receiver, |
3128 MethodRecognizer::Kind kind, | 3151 MethodRecognizer::Kind kind, |
3129 TargetEntryInstr** entry, | 3152 TargetEntryInstr** entry, |
3130 Definition** last) { | 3153 Definition** last) { |
3131 if (!ShouldInlineSimd()) { | 3154 if (!ShouldInlineSimd()) { |
3132 return false; | 3155 return false; |
3133 } | 3156 } |
3134 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 3157 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
3135 call->GetBlock()->try_index()); | 3158 call->GetBlock()->try_index(), |
3159 Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:01
kNoDeoptId because InheritDeoptTarget below.
| |
3136 (*entry)->InheritDeoptTarget(Z, call); | 3160 (*entry)->InheritDeoptTarget(Z, call); |
3137 Instruction* cursor = *entry; | 3161 Instruction* cursor = *entry; |
3138 Definition* mask_definition = call->ArgumentAt(2); | 3162 Definition* mask_definition = call->ArgumentAt(2); |
3139 intptr_t mask = 0; | 3163 intptr_t mask = 0; |
3140 if (!CheckMask(mask_definition, &mask)) { | 3164 if (!CheckMask(mask_definition, &mask)) { |
3141 return false; | 3165 return false; |
3142 } | 3166 } |
3143 *last = new (Z) Simd32x4ShuffleMixInstr(kind, new (Z) Value(receiver), | 3167 *last = new (Z) Simd32x4ShuffleMixInstr(kind, new (Z) Value(receiver), |
3144 new (Z) Value(call->ArgumentAt(1)), | 3168 new (Z) Value(call->ArgumentAt(1)), |
3145 mask, call->deopt_id()); | 3169 mask, call->deopt_id()); |
3146 flow_graph->AppendTo( | 3170 flow_graph->AppendTo( |
3147 cursor, *last, | 3171 cursor, *last, |
3148 call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL, | 3172 call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL, |
3149 FlowGraph::kValue); | 3173 FlowGraph::kValue); |
3150 return true; | 3174 return true; |
3151 } | 3175 } |
3152 | 3176 |
3153 | 3177 |
3154 static bool InlineInt32x4Method(FlowGraph* flow_graph, | 3178 static bool InlineInt32x4Method(FlowGraph* flow_graph, |
3155 Instruction* call, | 3179 Instruction* call, |
3156 Definition* receiver, | 3180 Definition* receiver, |
3157 MethodRecognizer::Kind kind, | 3181 MethodRecognizer::Kind kind, |
3158 TargetEntryInstr** entry, | 3182 TargetEntryInstr** entry, |
3159 Definition** last) { | 3183 Definition** last) { |
3160 if (!ShouldInlineSimd()) { | 3184 if (!ShouldInlineSimd()) { |
3161 return false; | 3185 return false; |
3162 } | 3186 } |
3163 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 3187 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
3164 call->GetBlock()->try_index()); | 3188 call->GetBlock()->try_index(), |
3189 Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:01
kNoDeoptId because InheritDeoptTarget below.
| |
3165 (*entry)->InheritDeoptTarget(Z, call); | 3190 (*entry)->InheritDeoptTarget(Z, call); |
3166 Instruction* cursor = *entry; | 3191 Instruction* cursor = *entry; |
3167 switch (kind) { | 3192 switch (kind) { |
3168 case MethodRecognizer::kInt32x4GetFlagX: | 3193 case MethodRecognizer::kInt32x4GetFlagX: |
3169 case MethodRecognizer::kInt32x4GetFlagY: | 3194 case MethodRecognizer::kInt32x4GetFlagY: |
3170 case MethodRecognizer::kInt32x4GetFlagZ: | 3195 case MethodRecognizer::kInt32x4GetFlagZ: |
3171 case MethodRecognizer::kInt32x4GetFlagW: { | 3196 case MethodRecognizer::kInt32x4GetFlagW: { |
3172 *last = new (Z) | 3197 *last = new (Z) |
3173 Int32x4GetFlagInstr(kind, new (Z) Value(receiver), call->deopt_id()); | 3198 Int32x4GetFlagInstr(kind, new (Z) Value(receiver), call->deopt_id()); |
3174 break; | 3199 break; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3210 static bool InlineFloat64x2Method(FlowGraph* flow_graph, | 3235 static bool InlineFloat64x2Method(FlowGraph* flow_graph, |
3211 Instruction* call, | 3236 Instruction* call, |
3212 Definition* receiver, | 3237 Definition* receiver, |
3213 MethodRecognizer::Kind kind, | 3238 MethodRecognizer::Kind kind, |
3214 TargetEntryInstr** entry, | 3239 TargetEntryInstr** entry, |
3215 Definition** last) { | 3240 Definition** last) { |
3216 if (!ShouldInlineSimd()) { | 3241 if (!ShouldInlineSimd()) { |
3217 return false; | 3242 return false; |
3218 } | 3243 } |
3219 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 3244 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
3220 call->GetBlock()->try_index()); | 3245 call->GetBlock()->try_index(), |
3246 Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:03
kNoDeoptId because InheritDeoptTarget below.
| |
3221 (*entry)->InheritDeoptTarget(Z, call); | 3247 (*entry)->InheritDeoptTarget(Z, call); |
3222 Instruction* cursor = *entry; | 3248 Instruction* cursor = *entry; |
3223 switch (kind) { | 3249 switch (kind) { |
3224 case MethodRecognizer::kFloat64x2GetX: | 3250 case MethodRecognizer::kFloat64x2GetX: |
3225 case MethodRecognizer::kFloat64x2GetY: { | 3251 case MethodRecognizer::kFloat64x2GetY: { |
3226 *last = new (Z) Simd64x2ShuffleInstr(kind, new (Z) Value(receiver), | 3252 *last = new (Z) Simd64x2ShuffleInstr(kind, new (Z) Value(receiver), |
3227 0, // mask is ignored. | 3253 0, // mask is ignored. |
3228 call->deopt_id()); | 3254 call->deopt_id()); |
3229 break; | 3255 break; |
3230 } | 3256 } |
(...skipping 30 matching lines...) Expand all Loading... | |
3261 | 3287 |
3262 static bool InlineSimdConstructor(FlowGraph* flow_graph, | 3288 static bool InlineSimdConstructor(FlowGraph* flow_graph, |
3263 Instruction* call, | 3289 Instruction* call, |
3264 MethodRecognizer::Kind kind, | 3290 MethodRecognizer::Kind kind, |
3265 TargetEntryInstr** entry, | 3291 TargetEntryInstr** entry, |
3266 Definition** last) { | 3292 Definition** last) { |
3267 if (!ShouldInlineSimd()) { | 3293 if (!ShouldInlineSimd()) { |
3268 return false; | 3294 return false; |
3269 } | 3295 } |
3270 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 3296 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
3271 call->GetBlock()->try_index()); | 3297 call->GetBlock()->try_index(), |
3298 Thread::Current()->GetNextDeoptId()); | |
Vyacheslav Egorov (Google)
2017/05/23 12:00:02
kNoDeoptId because InheritDeoptTarget below.
same
| |
3272 (*entry)->InheritDeoptTarget(Z, call); | 3299 (*entry)->InheritDeoptTarget(Z, call); |
3273 Instruction* cursor = *entry; | 3300 Instruction* cursor = *entry; |
3274 switch (kind) { | 3301 switch (kind) { |
3275 case MethodRecognizer::kFloat32x4Zero: | 3302 case MethodRecognizer::kFloat32x4Zero: |
3276 *last = new (Z) Float32x4ZeroInstr(); | 3303 *last = new (Z) Float32x4ZeroInstr(); |
3277 break; | 3304 break; |
3278 case MethodRecognizer::kFloat32x4Splat: | 3305 case MethodRecognizer::kFloat32x4Splat: |
3279 *last = new (Z) Float32x4SplatInstr(new (Z) Value(call->ArgumentAt(1)), | 3306 *last = new (Z) Float32x4SplatInstr(new (Z) Value(call->ArgumentAt(1)), |
3280 call->deopt_id()); | 3307 call->deopt_id()); |
3281 break; | 3308 break; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3342 | 3369 |
3343 static bool InlineMathCFunction(FlowGraph* flow_graph, | 3370 static bool InlineMathCFunction(FlowGraph* flow_graph, |
3344 Instruction* call, | 3371 Instruction* call, |
3345 MethodRecognizer::Kind kind, | 3372 MethodRecognizer::Kind kind, |
3346 TargetEntryInstr** entry, | 3373 TargetEntryInstr** entry, |
3347 Definition** last) { | 3374 Definition** last) { |
3348 if (!CanUnboxDouble()) { | 3375 if (!CanUnboxDouble()) { |
3349 return false; | 3376 return false; |
3350 } | 3377 } |
3351 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 3378 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
3352 call->GetBlock()->try_index()); | 3379 call->GetBlock()->try_index(), |
3380 Thread::Current()->GetNextDeoptId()); | |
3353 (*entry)->InheritDeoptTarget(Z, call); | 3381 (*entry)->InheritDeoptTarget(Z, call); |
3354 Instruction* cursor = *entry; | 3382 Instruction* cursor = *entry; |
3355 | 3383 |
3356 switch (kind) { | 3384 switch (kind) { |
3357 case MethodRecognizer::kMathSqrt: { | 3385 case MethodRecognizer::kMathSqrt: { |
3358 *last = new (Z) | 3386 *last = new (Z) |
3359 MathUnaryInstr(MathUnaryInstr::kSqrt, | 3387 MathUnaryInstr(MathUnaryInstr::kSqrt, |
3360 new (Z) Value(call->ArgumentAt(0)), call->deopt_id()); | 3388 new (Z) Value(call->ArgumentAt(0)), call->deopt_id()); |
3361 break; | 3389 break; |
3362 } | 3390 } |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3704 case MethodRecognizer::kMathCos: | 3732 case MethodRecognizer::kMathCos: |
3705 case MethodRecognizer::kMathTan: | 3733 case MethodRecognizer::kMathTan: |
3706 case MethodRecognizer::kMathAsin: | 3734 case MethodRecognizer::kMathAsin: |
3707 case MethodRecognizer::kMathAcos: | 3735 case MethodRecognizer::kMathAcos: |
3708 case MethodRecognizer::kMathAtan: | 3736 case MethodRecognizer::kMathAtan: |
3709 case MethodRecognizer::kMathAtan2: | 3737 case MethodRecognizer::kMathAtan2: |
3710 return InlineMathCFunction(flow_graph, call, kind, entry, last); | 3738 return InlineMathCFunction(flow_graph, call, kind, entry, last); |
3711 | 3739 |
3712 case MethodRecognizer::kObjectConstructor: { | 3740 case MethodRecognizer::kObjectConstructor: { |
3713 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 3741 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
3714 call->GetBlock()->try_index()); | 3742 call->GetBlock()->try_index(), |
3743 Thread::Current()->GetNextDeoptId()); | |
3715 (*entry)->InheritDeoptTarget(Z, call); | 3744 (*entry)->InheritDeoptTarget(Z, call); |
3716 ASSERT(!call->HasUses()); | 3745 ASSERT(!call->HasUses()); |
3717 *last = NULL; // Empty body. | 3746 *last = NULL; // Empty body. |
3718 return true; | 3747 return true; |
3719 } | 3748 } |
3720 | 3749 |
3721 case MethodRecognizer::kObjectArrayAllocate: { | 3750 case MethodRecognizer::kObjectArrayAllocate: { |
3722 Value* num_elements = new (Z) Value(call->ArgumentAt(1)); | 3751 Value* num_elements = new (Z) Value(call->ArgumentAt(1)); |
3723 if (num_elements->BindsToConstant() && | 3752 if (num_elements->BindsToConstant() && |
3724 num_elements->BoundConstant().IsSmi()) { | 3753 num_elements->BoundConstant().IsSmi()) { |
3725 intptr_t length = Smi::Cast(num_elements->BoundConstant()).Value(); | 3754 intptr_t length = Smi::Cast(num_elements->BoundConstant()).Value(); |
3726 if (length >= 0 && length <= Array::kMaxElements) { | 3755 if (length >= 0 && length <= Array::kMaxElements) { |
3727 Value* type = new (Z) Value(call->ArgumentAt(0)); | 3756 Value* type = new (Z) Value(call->ArgumentAt(0)); |
3728 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 3757 *entry = new (Z) TargetEntryInstr( |
3729 call->GetBlock()->try_index()); | 3758 flow_graph->allocate_block_id(), call->GetBlock()->try_index(), |
3759 Thread::Current()->GetNextDeoptId()); | |
3730 (*entry)->InheritDeoptTarget(Z, call); | 3760 (*entry)->InheritDeoptTarget(Z, call); |
3731 *last = | 3761 *last = |
3732 new (Z) CreateArrayInstr(call->token_pos(), type, num_elements); | 3762 new (Z) CreateArrayInstr(call->token_pos(), type, num_elements, |
3763 Thread::Current()->GetNextDeoptId()); | |
3733 flow_graph->AppendTo( | 3764 flow_graph->AppendTo( |
3734 *entry, *last, | 3765 *entry, *last, |
3735 call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL, | 3766 call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL, |
3736 FlowGraph::kValue); | 3767 FlowGraph::kValue); |
3737 return true; | 3768 return true; |
3738 } | 3769 } |
3739 } | 3770 } |
3740 return false; | 3771 return false; |
3741 } | 3772 } |
3742 | 3773 |
3743 case MethodRecognizer::kObjectRuntimeType: { | 3774 case MethodRecognizer::kObjectRuntimeType: { |
3744 Type& type = Type::ZoneHandle(Z); | 3775 Type& type = Type::ZoneHandle(Z); |
3745 if (RawObject::IsStringClassId(receiver_cid)) { | 3776 if (RawObject::IsStringClassId(receiver_cid)) { |
3746 type = Type::StringType(); | 3777 type = Type::StringType(); |
3747 } else if (receiver_cid == kDoubleCid) { | 3778 } else if (receiver_cid == kDoubleCid) { |
3748 type = Type::Double(); | 3779 type = Type::Double(); |
3749 } else if (RawObject::IsIntegerClassId(receiver_cid)) { | 3780 } else if (RawObject::IsIntegerClassId(receiver_cid)) { |
3750 type = Type::IntType(); | 3781 type = Type::IntType(); |
3751 } else if (receiver_cid != kClosureCid) { | 3782 } else if (receiver_cid != kClosureCid) { |
3752 const Class& cls = Class::Handle( | 3783 const Class& cls = Class::Handle( |
3753 Z, flow_graph->isolate()->class_table()->At(receiver_cid)); | 3784 Z, flow_graph->isolate()->class_table()->At(receiver_cid)); |
3754 if (!cls.IsGeneric()) { | 3785 if (!cls.IsGeneric()) { |
3755 type = cls.CanonicalType(); | 3786 type = cls.CanonicalType(); |
3756 } | 3787 } |
3757 } | 3788 } |
3758 | 3789 |
3759 if (!type.IsNull()) { | 3790 if (!type.IsNull()) { |
3760 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 3791 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
3761 call->GetBlock()->try_index()); | 3792 call->GetBlock()->try_index(), |
3793 Thread::Current()->GetNextDeoptId()); | |
3762 (*entry)->InheritDeoptTarget(Z, call); | 3794 (*entry)->InheritDeoptTarget(Z, call); |
3763 *last = new (Z) ConstantInstr(type); | 3795 *last = new (Z) ConstantInstr(type); |
3764 flow_graph->AppendTo( | 3796 flow_graph->AppendTo( |
3765 *entry, *last, | 3797 *entry, *last, |
3766 call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL, | 3798 call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL, |
3767 FlowGraph::kValue); | 3799 FlowGraph::kValue); |
3768 return true; | 3800 return true; |
3769 } | 3801 } |
3770 return false; | 3802 return false; |
3771 } | 3803 } |
3772 | 3804 |
3773 case MethodRecognizer::kOneByteStringSetAt: { | 3805 case MethodRecognizer::kOneByteStringSetAt: { |
3774 // This is an internal method, no need to check argument types nor | 3806 // This is an internal method, no need to check argument types nor |
3775 // range. | 3807 // range. |
3776 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 3808 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
3777 call->GetBlock()->try_index()); | 3809 call->GetBlock()->try_index(), |
3810 Thread::Current()->GetNextDeoptId()); | |
3778 (*entry)->InheritDeoptTarget(Z, call); | 3811 (*entry)->InheritDeoptTarget(Z, call); |
3779 Definition* str = call->ArgumentAt(0); | 3812 Definition* str = call->ArgumentAt(0); |
3780 Definition* index = call->ArgumentAt(1); | 3813 Definition* index = call->ArgumentAt(1); |
3781 Definition* value = call->ArgumentAt(2); | 3814 Definition* value = call->ArgumentAt(2); |
3782 *last = | 3815 *last = |
3783 new (Z) StoreIndexedInstr(new (Z) Value(str), new (Z) Value(index), | 3816 new (Z) StoreIndexedInstr(new (Z) Value(str), new (Z) Value(index), |
3784 new (Z) Value(value), kNoStoreBarrier, | 3817 new (Z) Value(value), kNoStoreBarrier, |
3785 1, // Index scale | 3818 1, // Index scale |
3786 kOneByteStringCid, kAlignedAccess, | 3819 kOneByteStringCid, kAlignedAccess, |
3787 call->deopt_id(), call->token_pos()); | 3820 call->deopt_id(), call->token_pos()); |
3788 flow_graph->AppendTo( | 3821 flow_graph->AppendTo( |
3789 *entry, *last, | 3822 *entry, *last, |
3790 call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL, | 3823 call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL, |
3791 FlowGraph::kEffect); | 3824 FlowGraph::kEffect); |
3792 return true; | 3825 return true; |
3793 } | 3826 } |
3794 | 3827 |
3795 default: | 3828 default: |
3796 return false; | 3829 return false; |
3797 } | 3830 } |
3798 } | 3831 } |
3799 | 3832 |
3800 | 3833 |
3801 } // namespace dart | 3834 } // namespace dart |
3802 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 3835 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
OLD | NEW |