| 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 | 4 |
| 5 #include "vm/jit_optimizer.h" | 5 #include "vm/jit_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/branch_optimizer.h" | 8 #include "vm/branch_optimizer.h" |
| 9 #include "vm/cha.h" | 9 #include "vm/cha.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 1662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1673 default: | 1673 default: |
| 1674 return false; | 1674 return false; |
| 1675 } | 1675 } |
| 1676 } | 1676 } |
| 1677 | 1677 |
| 1678 | 1678 |
| 1679 // Inline only simple, frequently called core library methods. | 1679 // Inline only simple, frequently called core library methods. |
| 1680 bool JitOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { | 1680 bool JitOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { |
| 1681 ASSERT(call->HasICData()); | 1681 ASSERT(call->HasICData()); |
| 1682 const ICData& ic_data = *call->ic_data(); | 1682 const ICData& ic_data = *call->ic_data(); |
| 1683 if ((ic_data.NumberOfUsedChecks() == 0) || !ic_data.HasOneTarget()) { | 1683 if (ic_data.NumberOfUsedChecks() != 1) { |
| 1684 // No type feedback collected or multiple targets found. | 1684 // No type feedback collected or multiple targets found. |
| 1685 return false; | 1685 return false; |
| 1686 } | 1686 } |
| 1687 | 1687 |
| 1688 Function& target = Function::Handle(Z); | 1688 Function& target = Function::Handle(Z); |
| 1689 GrowableArray<intptr_t> class_ids; | 1689 GrowableArray<intptr_t> class_ids; |
| 1690 ic_data.GetCheckAt(0, &class_ids, &target); | 1690 ic_data.GetCheckAt(0, &class_ids, &target); |
| 1691 MethodRecognizer::Kind recognized_kind = | 1691 MethodRecognizer::Kind recognized_kind = |
| 1692 MethodRecognizer::RecognizeKind(target); | 1692 MethodRecognizer::RecognizeKind(target); |
| 1693 | 1693 |
| 1694 if ((recognized_kind == MethodRecognizer::kOneByteStringCodeUnitAt) || | 1694 if ((recognized_kind == MethodRecognizer::kOneByteStringCodeUnitAt) || |
| 1695 (recognized_kind == MethodRecognizer::kTwoByteStringCodeUnitAt) || | 1695 (recognized_kind == MethodRecognizer::kTwoByteStringCodeUnitAt) || |
| 1696 (recognized_kind == MethodRecognizer::kExternalOneByteStringCodeUnitAt) || | 1696 (recognized_kind == MethodRecognizer::kExternalOneByteStringCodeUnitAt) || |
| 1697 (recognized_kind == MethodRecognizer::kExternalTwoByteStringCodeUnitAt) || | 1697 (recognized_kind == MethodRecognizer::kExternalTwoByteStringCodeUnitAt) || |
| 1698 (recognized_kind == MethodRecognizer::kGrowableArraySetData) || | 1698 (recognized_kind == MethodRecognizer::kGrowableArraySetData) || |
| 1699 (recognized_kind == MethodRecognizer::kGrowableArraySetLength)) { | 1699 (recognized_kind == MethodRecognizer::kGrowableArraySetLength) || |
| 1700 ASSERT(ic_data.NumberOfChecks() == 1); | 1700 (recognized_kind == MethodRecognizer::kSmi_bitAndFromSmi)) { |
| 1701 return FlowGraphInliner::TryReplaceInstanceCallWithInline( | 1701 return FlowGraphInliner::TryReplaceInstanceCallWithInline( |
| 1702 flow_graph_, current_iterator(), call); | 1702 flow_graph_, current_iterator(), call); |
| 1703 } | 1703 } |
| 1704 | 1704 |
| 1705 if ((recognized_kind == MethodRecognizer::kStringBaseCharAt) && | 1705 if (recognized_kind == MethodRecognizer::kStringBaseCharAt) { |
| 1706 (ic_data.NumberOfChecks() == 1)) { | |
| 1707 ASSERT((class_ids[0] == kOneByteStringCid) || | 1706 ASSERT((class_ids[0] == kOneByteStringCid) || |
| 1708 (class_ids[0] == kTwoByteStringCid) || | 1707 (class_ids[0] == kTwoByteStringCid) || |
| 1709 (class_ids[0] == kExternalOneByteStringCid) || | 1708 (class_ids[0] == kExternalOneByteStringCid) || |
| 1710 (class_ids[0] == kExternalTwoByteStringCid)); | 1709 (class_ids[0] == kExternalTwoByteStringCid)); |
| 1711 return FlowGraphInliner::TryReplaceInstanceCallWithInline( | 1710 return FlowGraphInliner::TryReplaceInstanceCallWithInline( |
| 1712 flow_graph_, current_iterator(), call); | 1711 flow_graph_, current_iterator(), call); |
| 1713 } | 1712 } |
| 1714 | 1713 |
| 1715 if ((class_ids[0] == kOneByteStringCid) && (ic_data.NumberOfChecks() == 1)) { | 1714 if (class_ids[0] == kOneByteStringCid) { |
| 1716 if (recognized_kind == MethodRecognizer::kOneByteStringSetAt) { | 1715 if (recognized_kind == MethodRecognizer::kOneByteStringSetAt) { |
| 1717 // This is an internal method, no need to check argument types nor | 1716 // This is an internal method, no need to check argument types nor |
| 1718 // range. | 1717 // range. |
| 1719 Definition* str = call->ArgumentAt(0); | 1718 Definition* str = call->ArgumentAt(0); |
| 1720 Definition* index = call->ArgumentAt(1); | 1719 Definition* index = call->ArgumentAt(1); |
| 1721 Definition* value = call->ArgumentAt(2); | 1720 Definition* value = call->ArgumentAt(2); |
| 1722 StoreIndexedInstr* store_op = new(Z) StoreIndexedInstr( | 1721 StoreIndexedInstr* store_op = new(Z) StoreIndexedInstr( |
| 1723 new(Z) Value(str), | 1722 new(Z) Value(str), |
| 1724 new(Z) Value(index), | 1723 new(Z) Value(index), |
| 1725 new(Z) Value(value), | 1724 new(Z) Value(value), |
| 1726 kNoStoreBarrier, | 1725 kNoStoreBarrier, |
| 1727 1, // Index scale | 1726 1, // Index scale |
| 1728 kOneByteStringCid, | 1727 kOneByteStringCid, |
| 1729 call->deopt_id(), | 1728 call->deopt_id(), |
| 1730 call->token_pos()); | 1729 call->token_pos()); |
| 1731 ReplaceCall(call, store_op); | 1730 ReplaceCall(call, store_op); |
| 1732 return true; | 1731 return true; |
| 1733 } | 1732 } |
| 1734 return false; | 1733 return false; |
| 1735 } | 1734 } |
| 1736 | 1735 |
| 1737 if (CanUnboxDouble() && | 1736 if (CanUnboxDouble() && |
| 1738 (recognized_kind == MethodRecognizer::kIntegerToDouble) && | 1737 (recognized_kind == MethodRecognizer::kIntegerToDouble)) { |
| 1739 (ic_data.NumberOfChecks() == 1)) { | |
| 1740 if (class_ids[0] == kSmiCid) { | 1738 if (class_ids[0] == kSmiCid) { |
| 1741 AddReceiverCheck(call); | 1739 AddReceiverCheck(call); |
| 1742 ReplaceCall(call, | 1740 ReplaceCall(call, |
| 1743 new(Z) SmiToDoubleInstr( | 1741 new(Z) SmiToDoubleInstr( |
| 1744 new(Z) Value(call->ArgumentAt(0)), | 1742 new(Z) Value(call->ArgumentAt(0)), |
| 1745 call->token_pos())); | 1743 call->token_pos())); |
| 1746 return true; | 1744 return true; |
| 1747 } else if ((class_ids[0] == kMintCid) && CanConvertUnboxedMintToDouble()) { | 1745 } else if ((class_ids[0] == kMintCid) && CanConvertUnboxedMintToDouble()) { |
| 1748 AddReceiverCheck(call); | 1746 AddReceiverCheck(call); |
| 1749 ReplaceCall(call, | 1747 ReplaceCall(call, |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1798 case MethodRecognizer::kDoubleMul: | 1796 case MethodRecognizer::kDoubleMul: |
| 1799 case MethodRecognizer::kDoubleDiv: | 1797 case MethodRecognizer::kDoubleDiv: |
| 1800 return FlowGraphInliner::TryReplaceInstanceCallWithInline( | 1798 return FlowGraphInliner::TryReplaceInstanceCallWithInline( |
| 1801 flow_graph_, current_iterator(), call); | 1799 flow_graph_, current_iterator(), call); |
| 1802 default: | 1800 default: |
| 1803 // Unsupported method. | 1801 // Unsupported method. |
| 1804 return false; | 1802 return false; |
| 1805 } | 1803 } |
| 1806 } | 1804 } |
| 1807 | 1805 |
| 1808 if (IsSupportedByteArrayViewCid(class_ids[0]) && | 1806 if (IsSupportedByteArrayViewCid(class_ids[0])) { |
| 1809 (ic_data.NumberOfChecks() == 1)) { | |
| 1810 return FlowGraphInliner::TryReplaceInstanceCallWithInline( | 1807 return FlowGraphInliner::TryReplaceInstanceCallWithInline( |
| 1811 flow_graph_, current_iterator(), call); | 1808 flow_graph_, current_iterator(), call); |
| 1812 } | 1809 } |
| 1813 | 1810 |
| 1814 if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) { | 1811 if (class_ids[0] == kFloat32x4Cid) { |
| 1815 return TryInlineFloat32x4Method(call, recognized_kind); | 1812 return TryInlineFloat32x4Method(call, recognized_kind); |
| 1816 } | 1813 } |
| 1817 | 1814 |
| 1818 if ((class_ids[0] == kInt32x4Cid) && (ic_data.NumberOfChecks() == 1)) { | 1815 if (class_ids[0] == kInt32x4Cid) { |
| 1819 return TryInlineInt32x4Method(call, recognized_kind); | 1816 return TryInlineInt32x4Method(call, recognized_kind); |
| 1820 } | 1817 } |
| 1821 | 1818 |
| 1822 if ((class_ids[0] == kFloat64x2Cid) && (ic_data.NumberOfChecks() == 1)) { | 1819 if (class_ids[0] == kFloat64x2Cid) { |
| 1823 return TryInlineFloat64x2Method(call, recognized_kind); | 1820 return TryInlineFloat64x2Method(call, recognized_kind); |
| 1824 } | 1821 } |
| 1825 | 1822 |
| 1826 if (recognized_kind == MethodRecognizer::kSmi_bitAndFromSmi) { | |
| 1827 AddReceiverCheck(call); | |
| 1828 BinarySmiOpInstr* op = | |
| 1829 new(Z) BinarySmiOpInstr( | |
| 1830 Token::kBIT_AND, | |
| 1831 new(Z) Value(call->ArgumentAt(0)), | |
| 1832 new(Z) Value(call->ArgumentAt(1)), | |
| 1833 call->deopt_id()); | |
| 1834 ReplaceCall(call, op); | |
| 1835 return true; | |
| 1836 } | |
| 1837 | |
| 1838 return false; | 1823 return false; |
| 1839 } | 1824 } |
| 1840 | 1825 |
| 1841 | 1826 |
| 1842 bool JitOptimizer::TryInlineFloat32x4Constructor( | 1827 bool JitOptimizer::TryInlineFloat32x4Constructor( |
| 1843 StaticCallInstr* call, | 1828 StaticCallInstr* call, |
| 1844 MethodRecognizer::Kind recognized_kind) { | 1829 MethodRecognizer::Kind recognized_kind) { |
| 1845 if (!ShouldInlineSimd()) { | 1830 if (!ShouldInlineSimd()) { |
| 1846 return false; | 1831 return false; |
| 1847 } | 1832 } |
| (...skipping 1109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2957 | 2942 |
| 2958 // Discard the environment from the original instruction because the store | 2943 // Discard the environment from the original instruction because the store |
| 2959 // can't deoptimize. | 2944 // can't deoptimize. |
| 2960 instr->RemoveEnvironment(); | 2945 instr->RemoveEnvironment(); |
| 2961 ReplaceCall(instr, store); | 2946 ReplaceCall(instr, store); |
| 2962 return true; | 2947 return true; |
| 2963 } | 2948 } |
| 2964 | 2949 |
| 2965 | 2950 |
| 2966 } // namespace dart | 2951 } // namespace dart |
| OLD | NEW |