Chromium Code Reviews| 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 |