Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(170)

Side by Side Diff: src/builtins/builtins-array.cc

Issue 2714193002: Remove SMI length check from TF_BUILTIN(ArrayIncludes, CodeStubAssembler) (Closed)
Patch Set: Add const Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/builtins/builtins.h" 5 #include "src/builtins/builtins.h"
6 #include "src/builtins/builtins-utils.h" 6 #include "src/builtins/builtins-utils.h"
7 7
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stub-assembler.h" 9 #include "src/code-stub-assembler.h"
10 #include "src/contexts.h" 10 #include "src/contexts.h"
(...skipping 1667 matching lines...) Expand 10 before | Expand all | Expand 10 after
1678 assembler.Return( 1678 assembler.Return(
1679 assembler.CallRuntime(Runtime::kArrayIsArray, context, object)); 1679 assembler.CallRuntime(Runtime::kArrayIsArray, context, object));
1680 } 1680 }
1681 1681
1682 TF_BUILTIN(ArrayIncludes, CodeStubAssembler) { 1682 TF_BUILTIN(ArrayIncludes, CodeStubAssembler) {
1683 Node* const array = Parameter(0); 1683 Node* const array = Parameter(0);
1684 Node* const search_element = Parameter(1); 1684 Node* const search_element = Parameter(1);
1685 Node* const start_from = Parameter(2); 1685 Node* const start_from = Parameter(2);
1686 Node* const context = Parameter(3 + 2); 1686 Node* const context = Parameter(3 + 2);
1687 1687
1688 Variable len_var(this, MachineType::PointerRepresentation()), 1688 Variable index_var(this, MachineType::PointerRepresentation());
1689 index_var(this, MachineType::PointerRepresentation());
1690 1689
1691 Label init_k(this), return_true(this), return_false(this), call_runtime(this); 1690 Label init_k(this), return_true(this), return_false(this), call_runtime(this);
1692 Label init_len(this), select_loop(this); 1691 Label init_len(this), select_loop(this);
1693 1692
1694 index_var.Bind(IntPtrConstant(0)); 1693 index_var.Bind(IntPtrConstant(0));
1695 len_var.Bind(IntPtrConstant(0));
1696 1694
1697 // Take slow path if not a JSArray, if retrieving elements requires 1695 // Take slow path if not a JSArray, if retrieving elements requires
1698 // traversing prototype, or if access checks are required. 1696 // traversing prototype, or if access checks are required.
1699 BranchIfFastJSArray(array, context, 1697 BranchIfFastJSArray(array, context,
1700 CodeStubAssembler::FastJSArrayAccessMode::INBOUNDS_READ, 1698 CodeStubAssembler::FastJSArrayAccessMode::INBOUNDS_READ,
1701 &init_len, &call_runtime); 1699 &init_len, &call_runtime);
1702 1700
1703 Bind(&init_len); 1701 Bind(&init_len);
1704 { 1702 // JSArray length is always an Smi for fast arrays.
1705 // Handle case where JSArray length is not an Smi in the runtime 1703 CSA_ASSERT(this, TaggedIsSmi(LoadObjectField(array, JSArray::kLengthOffset)));
1706 Node* len = LoadObjectField(array, JSArray::kLengthOffset); 1704 Node* const len = LoadAndUntagObjectField(array, JSArray::kLengthOffset);
1707 GotoIfNot(TaggedIsSmi(len), &call_runtime);
1708 1705
1709 len_var.Bind(SmiToWord(len)); 1706 GotoIf(IsUndefined(start_from), &select_loop);
1710 1707
1711 GotoIf(IsUndefined(start_from), &select_loop); 1708 // Bailout to slow path if startIndex is not an Smi.
1712 1709 Branch(TaggedIsSmi(start_from), &init_k, &call_runtime);
1713 // Bailout to slow path if startIndex is not an Smi.
1714 Branch(TaggedIsSmi(start_from), &init_k, &call_runtime);
1715 }
1716 1710
1717 Bind(&init_k); 1711 Bind(&init_k);
1718 CSA_ASSERT(this, TaggedIsSmi(start_from)); 1712 CSA_ASSERT(this, TaggedIsSmi(start_from));
1719 Node* const untagged_start_from = SmiToWord(start_from); 1713 Node* const untagged_start_from = SmiToWord(start_from);
1720 index_var.Bind(Select( 1714 index_var.Bind(Select(
1721 IntPtrGreaterThanOrEqual(untagged_start_from, IntPtrConstant(0)), 1715 IntPtrGreaterThanOrEqual(untagged_start_from, IntPtrConstant(0)),
1722 [=]() { return untagged_start_from; }, 1716 [=]() { return untagged_start_from; },
1723 [=]() { 1717 [=]() {
1724 Node* const index = IntPtrAdd(len_var.value(), untagged_start_from); 1718 Node* const index = IntPtrAdd(len, untagged_start_from);
1725 return SelectConstant(IntPtrLessThan(index, IntPtrConstant(0)), 1719 return SelectConstant(IntPtrLessThan(index, IntPtrConstant(0)),
1726 IntPtrConstant(0), index, 1720 IntPtrConstant(0), index,
1727 MachineType::PointerRepresentation()); 1721 MachineType::PointerRepresentation());
1728 }, 1722 },
1729 MachineType::PointerRepresentation())); 1723 MachineType::PointerRepresentation()));
1730 1724
1731 Goto(&select_loop); 1725 Goto(&select_loop);
1732 Bind(&select_loop); 1726 Bind(&select_loop);
1733 static int32_t kElementsKind[] = { 1727 static int32_t kElementsKind[] = {
1734 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS, 1728 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS,
(...skipping 29 matching lines...) Expand all
1764 search_num.Bind(LoadHeapNumberValue(search_element)); 1758 search_num.Bind(LoadHeapNumberValue(search_element));
1765 Goto(&heap_num_loop); 1759 Goto(&heap_num_loop);
1766 1760
1767 Bind(&not_heap_num); 1761 Bind(&not_heap_num);
1768 Node* search_type = LoadMapInstanceType(map); 1762 Node* search_type = LoadMapInstanceType(map);
1769 GotoIf(IsStringInstanceType(search_type), &string_loop); 1763 GotoIf(IsStringInstanceType(search_type), &string_loop);
1770 Goto(&ident_loop); 1764 Goto(&ident_loop);
1771 1765
1772 Bind(&ident_loop); 1766 Bind(&ident_loop);
1773 { 1767 {
1774 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), 1768 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1775 &return_false);
1776 Node* element_k = LoadFixedArrayElement(elements, index_var.value()); 1769 Node* element_k = LoadFixedArrayElement(elements, index_var.value());
1777 GotoIf(WordEqual(element_k, search_element), &return_true); 1770 GotoIf(WordEqual(element_k, search_element), &return_true);
1778 1771
1779 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); 1772 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1)));
1780 Goto(&ident_loop); 1773 Goto(&ident_loop);
1781 } 1774 }
1782 1775
1783 Bind(&undef_loop); 1776 Bind(&undef_loop);
1784 { 1777 {
1785 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), 1778 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1786 &return_false);
1787 Node* element_k = LoadFixedArrayElement(elements, index_var.value()); 1779 Node* element_k = LoadFixedArrayElement(elements, index_var.value());
1788 GotoIf(WordEqual(element_k, UndefinedConstant()), &return_true); 1780 GotoIf(WordEqual(element_k, UndefinedConstant()), &return_true);
1789 GotoIf(WordEqual(element_k, TheHoleConstant()), &return_true); 1781 GotoIf(WordEqual(element_k, TheHoleConstant()), &return_true);
1790 1782
1791 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); 1783 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1)));
1792 Goto(&undef_loop); 1784 Goto(&undef_loop);
1793 } 1785 }
1794 1786
1795 Bind(&heap_num_loop); 1787 Bind(&heap_num_loop);
1796 { 1788 {
1797 Label nan_loop(this, &index_var), not_nan_loop(this, &index_var); 1789 Label nan_loop(this, &index_var), not_nan_loop(this, &index_var);
1798 BranchIfFloat64IsNaN(search_num.value(), &nan_loop, &not_nan_loop); 1790 BranchIfFloat64IsNaN(search_num.value(), &nan_loop, &not_nan_loop);
1799 1791
1800 Bind(&not_nan_loop); 1792 Bind(&not_nan_loop);
1801 { 1793 {
1802 Label continue_loop(this), not_smi(this); 1794 Label continue_loop(this), not_smi(this);
1803 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), 1795 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1804 &return_false);
1805 Node* element_k = LoadFixedArrayElement(elements, index_var.value()); 1796 Node* element_k = LoadFixedArrayElement(elements, index_var.value());
1806 GotoIfNot(TaggedIsSmi(element_k), &not_smi); 1797 GotoIfNot(TaggedIsSmi(element_k), &not_smi);
1807 Branch(Float64Equal(search_num.value(), SmiToFloat64(element_k)), 1798 Branch(Float64Equal(search_num.value(), SmiToFloat64(element_k)),
1808 &return_true, &continue_loop); 1799 &return_true, &continue_loop);
1809 1800
1810 Bind(&not_smi); 1801 Bind(&not_smi);
1811 GotoIfNot(IsHeapNumber(element_k), &continue_loop); 1802 GotoIfNot(IsHeapNumber(element_k), &continue_loop);
1812 Branch(Float64Equal(search_num.value(), LoadHeapNumberValue(element_k)), 1803 Branch(Float64Equal(search_num.value(), LoadHeapNumberValue(element_k)),
1813 &return_true, &continue_loop); 1804 &return_true, &continue_loop);
1814 1805
1815 Bind(&continue_loop); 1806 Bind(&continue_loop);
1816 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); 1807 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1)));
1817 Goto(&not_nan_loop); 1808 Goto(&not_nan_loop);
1818 } 1809 }
1819 1810
1820 Bind(&nan_loop); 1811 Bind(&nan_loop);
1821 { 1812 {
1822 Label continue_loop(this); 1813 Label continue_loop(this);
1823 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), 1814 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1824 &return_false);
1825 Node* element_k = LoadFixedArrayElement(elements, index_var.value()); 1815 Node* element_k = LoadFixedArrayElement(elements, index_var.value());
1826 GotoIf(TaggedIsSmi(element_k), &continue_loop); 1816 GotoIf(TaggedIsSmi(element_k), &continue_loop);
1827 GotoIfNot(IsHeapNumber(element_k), &continue_loop); 1817 GotoIfNot(IsHeapNumber(element_k), &continue_loop);
1828 BranchIfFloat64IsNaN(LoadHeapNumberValue(element_k), &return_true, 1818 BranchIfFloat64IsNaN(LoadHeapNumberValue(element_k), &return_true,
1829 &continue_loop); 1819 &continue_loop);
1830 1820
1831 Bind(&continue_loop); 1821 Bind(&continue_loop);
1832 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); 1822 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1)));
1833 Goto(&nan_loop); 1823 Goto(&nan_loop);
1834 } 1824 }
1835 } 1825 }
1836 1826
1837 Bind(&string_loop); 1827 Bind(&string_loop);
1838 { 1828 {
1839 Label continue_loop(this); 1829 Label continue_loop(this);
1840 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), 1830 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1841 &return_false);
1842 Node* element_k = LoadFixedArrayElement(elements, index_var.value()); 1831 Node* element_k = LoadFixedArrayElement(elements, index_var.value());
1843 GotoIf(TaggedIsSmi(element_k), &continue_loop); 1832 GotoIf(TaggedIsSmi(element_k), &continue_loop);
1844 GotoIfNot(IsStringInstanceType(LoadInstanceType(element_k)), 1833 GotoIfNot(IsStringInstanceType(LoadInstanceType(element_k)),
1845 &continue_loop); 1834 &continue_loop);
1846 1835
1847 // TODO(bmeurer): Consider inlining the StringEqual logic here. 1836 // TODO(bmeurer): Consider inlining the StringEqual logic here.
1848 Node* result = CallStub(CodeFactory::StringEqual(isolate()), context, 1837 Node* result = CallStub(CodeFactory::StringEqual(isolate()), context,
1849 search_element, element_k); 1838 search_element, element_k);
1850 Branch(WordEqual(BooleanConstant(true), result), &return_true, 1839 Branch(WordEqual(BooleanConstant(true), result), &return_true,
1851 &continue_loop); 1840 &continue_loop);
(...skipping 18 matching lines...) Expand all
1870 GotoIfNot(IsHeapNumber(search_element), &return_false); 1859 GotoIfNot(IsHeapNumber(search_element), &return_false);
1871 1860
1872 search_num.Bind(LoadHeapNumberValue(search_element)); 1861 search_num.Bind(LoadHeapNumberValue(search_element));
1873 1862
1874 BranchIfFloat64IsNaN(search_num.value(), &nan_loop, &not_nan_loop); 1863 BranchIfFloat64IsNaN(search_num.value(), &nan_loop, &not_nan_loop);
1875 1864
1876 // Search for HeapNumber 1865 // Search for HeapNumber
1877 Bind(&not_nan_loop); 1866 Bind(&not_nan_loop);
1878 { 1867 {
1879 Label continue_loop(this); 1868 Label continue_loop(this);
1880 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), 1869 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1881 &return_false);
1882 Node* element_k = LoadFixedDoubleArrayElement(elements, index_var.value(), 1870 Node* element_k = LoadFixedDoubleArrayElement(elements, index_var.value(),
1883 MachineType::Float64()); 1871 MachineType::Float64());
1884 Branch(Float64Equal(element_k, search_num.value()), &return_true, 1872 Branch(Float64Equal(element_k, search_num.value()), &return_true,
1885 &continue_loop); 1873 &continue_loop);
1886 Bind(&continue_loop); 1874 Bind(&continue_loop);
1887 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); 1875 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1)));
1888 Goto(&not_nan_loop); 1876 Goto(&not_nan_loop);
1889 } 1877 }
1890 1878
1891 // Search for NaN 1879 // Search for NaN
1892 Bind(&nan_loop); 1880 Bind(&nan_loop);
1893 { 1881 {
1894 Label continue_loop(this); 1882 Label continue_loop(this);
1895 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), 1883 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1896 &return_false);
1897 Node* element_k = LoadFixedDoubleArrayElement(elements, index_var.value(), 1884 Node* element_k = LoadFixedDoubleArrayElement(elements, index_var.value(),
1898 MachineType::Float64()); 1885 MachineType::Float64());
1899 BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop); 1886 BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop);
1900 Bind(&continue_loop); 1887 Bind(&continue_loop);
1901 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); 1888 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1)));
1902 Goto(&nan_loop); 1889 Goto(&nan_loop);
1903 } 1890 }
1904 } 1891 }
1905 1892
1906 Bind(&if_holey_doubles); 1893 Bind(&if_holey_doubles);
(...skipping 11 matching lines...) Expand all
1918 GotoIfNot(IsHeapNumber(search_element), &return_false); 1905 GotoIfNot(IsHeapNumber(search_element), &return_false);
1919 1906
1920 search_num.Bind(LoadHeapNumberValue(search_element)); 1907 search_num.Bind(LoadHeapNumberValue(search_element));
1921 1908
1922 BranchIfFloat64IsNaN(search_num.value(), &nan_loop, &not_nan_loop); 1909 BranchIfFloat64IsNaN(search_num.value(), &nan_loop, &not_nan_loop);
1923 1910
1924 // Search for HeapNumber 1911 // Search for HeapNumber
1925 Bind(&not_nan_loop); 1912 Bind(&not_nan_loop);
1926 { 1913 {
1927 Label continue_loop(this); 1914 Label continue_loop(this);
1928 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), 1915 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1929 &return_false);
1930 1916
1931 // Load double value or continue if it contains a double hole. 1917 // Load double value or continue if it contains a double hole.
1932 Node* element_k = LoadFixedDoubleArrayElement( 1918 Node* element_k = LoadFixedDoubleArrayElement(
1933 elements, index_var.value(), MachineType::Float64(), 0, 1919 elements, index_var.value(), MachineType::Float64(), 0,
1934 CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop); 1920 CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop);
1935 1921
1936 Branch(Float64Equal(element_k, search_num.value()), &return_true, 1922 Branch(Float64Equal(element_k, search_num.value()), &return_true,
1937 &continue_loop); 1923 &continue_loop);
1938 Bind(&continue_loop); 1924 Bind(&continue_loop);
1939 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); 1925 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1)));
1940 Goto(&not_nan_loop); 1926 Goto(&not_nan_loop);
1941 } 1927 }
1942 1928
1943 // Search for NaN 1929 // Search for NaN
1944 Bind(&nan_loop); 1930 Bind(&nan_loop);
1945 { 1931 {
1946 Label continue_loop(this); 1932 Label continue_loop(this);
1947 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), 1933 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1948 &return_false);
1949 1934
1950 // Load double value or continue if it contains a double hole. 1935 // Load double value or continue if it contains a double hole.
1951 Node* element_k = LoadFixedDoubleArrayElement( 1936 Node* element_k = LoadFixedDoubleArrayElement(
1952 elements, index_var.value(), MachineType::Float64(), 0, 1937 elements, index_var.value(), MachineType::Float64(), 0,
1953 CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop); 1938 CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop);
1954 1939
1955 BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop); 1940 BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop);
1956 Bind(&continue_loop); 1941 Bind(&continue_loop);
1957 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); 1942 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1)));
1958 Goto(&nan_loop); 1943 Goto(&nan_loop);
1959 } 1944 }
1960 1945
1961 // Search for the Hole 1946 // Search for the Hole
1962 Bind(&hole_loop); 1947 Bind(&hole_loop);
1963 { 1948 {
1964 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), 1949 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1965 &return_false);
1966 1950
1967 // Check if the element is a double hole, but don't load it. 1951 // Check if the element is a double hole, but don't load it.
1968 LoadFixedDoubleArrayElement( 1952 LoadFixedDoubleArrayElement(
1969 elements, index_var.value(), MachineType::None(), 0, 1953 elements, index_var.value(), MachineType::None(), 0,
1970 CodeStubAssembler::INTPTR_PARAMETERS, &return_true); 1954 CodeStubAssembler::INTPTR_PARAMETERS, &return_true);
1971 1955
1972 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); 1956 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1)));
1973 Goto(&hole_loop); 1957 Goto(&hole_loop);
1974 } 1958 }
1975 } 1959 }
(...skipping 875 matching lines...) Expand 10 before | Expand all | Expand 10 after
2851 { 2835 {
2852 Node* message = assembler.SmiConstant(MessageTemplate::kDetachedOperation); 2836 Node* message = assembler.SmiConstant(MessageTemplate::kDetachedOperation);
2853 assembler.CallRuntime(Runtime::kThrowTypeError, context, message, 2837 assembler.CallRuntime(Runtime::kThrowTypeError, context, message,
2854 assembler.HeapConstant(operation)); 2838 assembler.HeapConstant(operation));
2855 assembler.Unreachable(); 2839 assembler.Unreachable();
2856 } 2840 }
2857 } 2841 }
2858 2842
2859 } // namespace internal 2843 } // namespace internal
2860 } // namespace v8 2844 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698