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

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

Issue 2714193002: Remove SMI length check from TF_BUILTIN(ArrayIncludes, CodeStubAssembler) (Closed)
Patch Set: Ensure RawMachineAssembler::AddNode does not complain about null current_block_ Created 3 years, 10 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
1701 Node* len = nullptr;
vabr (Chromium) 2017/02/25 21:25:55 I tried to initialize |len| with LoadAndUntagObjec
Benedikt Meurer 2017/02/26 18:34:27 Just remove the { and } in 1704, and declare the N
vabr (Chromium) 2017/02/26 20:30:24 Done.
1703 Bind(&init_len); 1702 Bind(&init_len);
1704 { 1703 {
1705 // Handle case where JSArray length is not an Smi in the runtime 1704 // JSArray length is always an Smi for fast arrays.
1706 Node* len = LoadObjectField(array, JSArray::kLengthOffset); 1705 CSA_ASSERT(this,
1707 GotoIfNot(TaggedIsSmi(len), &call_runtime); 1706 TaggedIsSmi(LoadObjectField(array, JSArray::kLengthOffset)));
1708 1707 len = LoadAndUntagObjectField(array, JSArray::kLengthOffset);
1709 len_var.Bind(SmiToWord(len));
1710 1708
1711 GotoIf(IsUndefined(start_from), &select_loop); 1709 GotoIf(IsUndefined(start_from), &select_loop);
1712 1710
1713 // Bailout to slow path if startIndex is not an Smi. 1711 // Bailout to slow path if startIndex is not an Smi.
1714 Branch(TaggedIsSmi(start_from), &init_k, &call_runtime); 1712 Branch(TaggedIsSmi(start_from), &init_k, &call_runtime);
1715 } 1713 }
1716 1714
1717 Bind(&init_k); 1715 Bind(&init_k);
1718 CSA_ASSERT(this, TaggedIsSmi(start_from)); 1716 CSA_ASSERT(this, TaggedIsSmi(start_from));
1719 Node* const untagged_start_from = SmiToWord(start_from); 1717 Node* const untagged_start_from = SmiToWord(start_from);
1720 index_var.Bind(Select( 1718 index_var.Bind(Select(
1721 IntPtrGreaterThanOrEqual(untagged_start_from, IntPtrConstant(0)), 1719 IntPtrGreaterThanOrEqual(untagged_start_from, IntPtrConstant(0)),
1722 [=]() { return untagged_start_from; }, 1720 [=]() { return untagged_start_from; },
1723 [=]() { 1721 [=]() {
1724 Node* const index = IntPtrAdd(len_var.value(), untagged_start_from); 1722 Node* const index = IntPtrAdd(len, untagged_start_from);
1725 return SelectConstant(IntPtrLessThan(index, IntPtrConstant(0)), 1723 return SelectConstant(IntPtrLessThan(index, IntPtrConstant(0)),
1726 IntPtrConstant(0), index, 1724 IntPtrConstant(0), index,
1727 MachineType::PointerRepresentation()); 1725 MachineType::PointerRepresentation());
1728 }, 1726 },
1729 MachineType::PointerRepresentation())); 1727 MachineType::PointerRepresentation()));
1730 1728
1731 Goto(&select_loop); 1729 Goto(&select_loop);
1732 Bind(&select_loop); 1730 Bind(&select_loop);
1733 static int32_t kElementsKind[] = { 1731 static int32_t kElementsKind[] = {
1734 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS, 1732 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS,
(...skipping 29 matching lines...) Expand all
1764 search_num.Bind(LoadHeapNumberValue(search_element)); 1762 search_num.Bind(LoadHeapNumberValue(search_element));
1765 Goto(&heap_num_loop); 1763 Goto(&heap_num_loop);
1766 1764
1767 Bind(&not_heap_num); 1765 Bind(&not_heap_num);
1768 Node* search_type = LoadMapInstanceType(map); 1766 Node* search_type = LoadMapInstanceType(map);
1769 GotoIf(IsStringInstanceType(search_type), &string_loop); 1767 GotoIf(IsStringInstanceType(search_type), &string_loop);
1770 Goto(&ident_loop); 1768 Goto(&ident_loop);
1771 1769
1772 Bind(&ident_loop); 1770 Bind(&ident_loop);
1773 { 1771 {
1774 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), 1772 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1775 &return_false);
1776 Node* element_k = LoadFixedArrayElement(elements, index_var.value()); 1773 Node* element_k = LoadFixedArrayElement(elements, index_var.value());
1777 GotoIf(WordEqual(element_k, search_element), &return_true); 1774 GotoIf(WordEqual(element_k, search_element), &return_true);
1778 1775
1779 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); 1776 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1)));
1780 Goto(&ident_loop); 1777 Goto(&ident_loop);
1781 } 1778 }
1782 1779
1783 Bind(&undef_loop); 1780 Bind(&undef_loop);
1784 { 1781 {
1785 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), 1782 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1786 &return_false);
1787 Node* element_k = LoadFixedArrayElement(elements, index_var.value()); 1783 Node* element_k = LoadFixedArrayElement(elements, index_var.value());
1788 GotoIf(WordEqual(element_k, UndefinedConstant()), &return_true); 1784 GotoIf(WordEqual(element_k, UndefinedConstant()), &return_true);
1789 GotoIf(WordEqual(element_k, TheHoleConstant()), &return_true); 1785 GotoIf(WordEqual(element_k, TheHoleConstant()), &return_true);
1790 1786
1791 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); 1787 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1)));
1792 Goto(&undef_loop); 1788 Goto(&undef_loop);
1793 } 1789 }
1794 1790
1795 Bind(&heap_num_loop); 1791 Bind(&heap_num_loop);
1796 { 1792 {
1797 Label nan_loop(this, &index_var), not_nan_loop(this, &index_var); 1793 Label nan_loop(this, &index_var), not_nan_loop(this, &index_var);
1798 BranchIfFloat64IsNaN(search_num.value(), &nan_loop, &not_nan_loop); 1794 BranchIfFloat64IsNaN(search_num.value(), &nan_loop, &not_nan_loop);
1799 1795
1800 Bind(&not_nan_loop); 1796 Bind(&not_nan_loop);
1801 { 1797 {
1802 Label continue_loop(this), not_smi(this); 1798 Label continue_loop(this), not_smi(this);
1803 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), 1799 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1804 &return_false);
1805 Node* element_k = LoadFixedArrayElement(elements, index_var.value()); 1800 Node* element_k = LoadFixedArrayElement(elements, index_var.value());
1806 GotoIfNot(TaggedIsSmi(element_k), &not_smi); 1801 GotoIfNot(TaggedIsSmi(element_k), &not_smi);
1807 Branch(Float64Equal(search_num.value(), SmiToFloat64(element_k)), 1802 Branch(Float64Equal(search_num.value(), SmiToFloat64(element_k)),
1808 &return_true, &continue_loop); 1803 &return_true, &continue_loop);
1809 1804
1810 Bind(&not_smi); 1805 Bind(&not_smi);
1811 GotoIfNot(IsHeapNumber(element_k), &continue_loop); 1806 GotoIfNot(IsHeapNumber(element_k), &continue_loop);
1812 Branch(Float64Equal(search_num.value(), LoadHeapNumberValue(element_k)), 1807 Branch(Float64Equal(search_num.value(), LoadHeapNumberValue(element_k)),
1813 &return_true, &continue_loop); 1808 &return_true, &continue_loop);
1814 1809
1815 Bind(&continue_loop); 1810 Bind(&continue_loop);
1816 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); 1811 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1)));
1817 Goto(&not_nan_loop); 1812 Goto(&not_nan_loop);
1818 } 1813 }
1819 1814
1820 Bind(&nan_loop); 1815 Bind(&nan_loop);
1821 { 1816 {
1822 Label continue_loop(this); 1817 Label continue_loop(this);
1823 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), 1818 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1824 &return_false);
1825 Node* element_k = LoadFixedArrayElement(elements, index_var.value()); 1819 Node* element_k = LoadFixedArrayElement(elements, index_var.value());
1826 GotoIf(TaggedIsSmi(element_k), &continue_loop); 1820 GotoIf(TaggedIsSmi(element_k), &continue_loop);
1827 GotoIfNot(IsHeapNumber(element_k), &continue_loop); 1821 GotoIfNot(IsHeapNumber(element_k), &continue_loop);
1828 BranchIfFloat64IsNaN(LoadHeapNumberValue(element_k), &return_true, 1822 BranchIfFloat64IsNaN(LoadHeapNumberValue(element_k), &return_true,
1829 &continue_loop); 1823 &continue_loop);
1830 1824
1831 Bind(&continue_loop); 1825 Bind(&continue_loop);
1832 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); 1826 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1)));
1833 Goto(&nan_loop); 1827 Goto(&nan_loop);
1834 } 1828 }
1835 } 1829 }
1836 1830
1837 Bind(&string_loop); 1831 Bind(&string_loop);
1838 { 1832 {
1839 Label continue_loop(this); 1833 Label continue_loop(this);
1840 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), 1834 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1841 &return_false);
1842 Node* element_k = LoadFixedArrayElement(elements, index_var.value()); 1835 Node* element_k = LoadFixedArrayElement(elements, index_var.value());
1843 GotoIf(TaggedIsSmi(element_k), &continue_loop); 1836 GotoIf(TaggedIsSmi(element_k), &continue_loop);
1844 GotoIfNot(IsStringInstanceType(LoadInstanceType(element_k)), 1837 GotoIfNot(IsStringInstanceType(LoadInstanceType(element_k)),
1845 &continue_loop); 1838 &continue_loop);
1846 1839
1847 // TODO(bmeurer): Consider inlining the StringEqual logic here. 1840 // TODO(bmeurer): Consider inlining the StringEqual logic here.
1848 Node* result = CallStub(CodeFactory::StringEqual(isolate()), context, 1841 Node* result = CallStub(CodeFactory::StringEqual(isolate()), context,
1849 search_element, element_k); 1842 search_element, element_k);
1850 Branch(WordEqual(BooleanConstant(true), result), &return_true, 1843 Branch(WordEqual(BooleanConstant(true), result), &return_true,
1851 &continue_loop); 1844 &continue_loop);
(...skipping 18 matching lines...) Expand all
1870 GotoIfNot(IsHeapNumber(search_element), &return_false); 1863 GotoIfNot(IsHeapNumber(search_element), &return_false);
1871 1864
1872 search_num.Bind(LoadHeapNumberValue(search_element)); 1865 search_num.Bind(LoadHeapNumberValue(search_element));
1873 1866
1874 BranchIfFloat64IsNaN(search_num.value(), &nan_loop, &not_nan_loop); 1867 BranchIfFloat64IsNaN(search_num.value(), &nan_loop, &not_nan_loop);
1875 1868
1876 // Search for HeapNumber 1869 // Search for HeapNumber
1877 Bind(&not_nan_loop); 1870 Bind(&not_nan_loop);
1878 { 1871 {
1879 Label continue_loop(this); 1872 Label continue_loop(this);
1880 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), 1873 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1881 &return_false);
1882 Node* element_k = LoadFixedDoubleArrayElement(elements, index_var.value(), 1874 Node* element_k = LoadFixedDoubleArrayElement(elements, index_var.value(),
1883 MachineType::Float64()); 1875 MachineType::Float64());
1884 Branch(Float64Equal(element_k, search_num.value()), &return_true, 1876 Branch(Float64Equal(element_k, search_num.value()), &return_true,
1885 &continue_loop); 1877 &continue_loop);
1886 Bind(&continue_loop); 1878 Bind(&continue_loop);
1887 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); 1879 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1)));
1888 Goto(&not_nan_loop); 1880 Goto(&not_nan_loop);
1889 } 1881 }
1890 1882
1891 // Search for NaN 1883 // Search for NaN
1892 Bind(&nan_loop); 1884 Bind(&nan_loop);
1893 { 1885 {
1894 Label continue_loop(this); 1886 Label continue_loop(this);
1895 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), 1887 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1896 &return_false);
1897 Node* element_k = LoadFixedDoubleArrayElement(elements, index_var.value(), 1888 Node* element_k = LoadFixedDoubleArrayElement(elements, index_var.value(),
1898 MachineType::Float64()); 1889 MachineType::Float64());
1899 BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop); 1890 BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop);
1900 Bind(&continue_loop); 1891 Bind(&continue_loop);
1901 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); 1892 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1)));
1902 Goto(&nan_loop); 1893 Goto(&nan_loop);
1903 } 1894 }
1904 } 1895 }
1905 1896
1906 Bind(&if_holey_doubles); 1897 Bind(&if_holey_doubles);
(...skipping 11 matching lines...) Expand all
1918 GotoIfNot(IsHeapNumber(search_element), &return_false); 1909 GotoIfNot(IsHeapNumber(search_element), &return_false);
1919 1910
1920 search_num.Bind(LoadHeapNumberValue(search_element)); 1911 search_num.Bind(LoadHeapNumberValue(search_element));
1921 1912
1922 BranchIfFloat64IsNaN(search_num.value(), &nan_loop, &not_nan_loop); 1913 BranchIfFloat64IsNaN(search_num.value(), &nan_loop, &not_nan_loop);
1923 1914
1924 // Search for HeapNumber 1915 // Search for HeapNumber
1925 Bind(&not_nan_loop); 1916 Bind(&not_nan_loop);
1926 { 1917 {
1927 Label continue_loop(this); 1918 Label continue_loop(this);
1928 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), 1919 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1929 &return_false);
1930 1920
1931 // Load double value or continue if it contains a double hole. 1921 // Load double value or continue if it contains a double hole.
1932 Node* element_k = LoadFixedDoubleArrayElement( 1922 Node* element_k = LoadFixedDoubleArrayElement(
1933 elements, index_var.value(), MachineType::Float64(), 0, 1923 elements, index_var.value(), MachineType::Float64(), 0,
1934 CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop); 1924 CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop);
1935 1925
1936 Branch(Float64Equal(element_k, search_num.value()), &return_true, 1926 Branch(Float64Equal(element_k, search_num.value()), &return_true,
1937 &continue_loop); 1927 &continue_loop);
1938 Bind(&continue_loop); 1928 Bind(&continue_loop);
1939 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); 1929 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1)));
1940 Goto(&not_nan_loop); 1930 Goto(&not_nan_loop);
1941 } 1931 }
1942 1932
1943 // Search for NaN 1933 // Search for NaN
1944 Bind(&nan_loop); 1934 Bind(&nan_loop);
1945 { 1935 {
1946 Label continue_loop(this); 1936 Label continue_loop(this);
1947 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), 1937 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1948 &return_false);
1949 1938
1950 // Load double value or continue if it contains a double hole. 1939 // Load double value or continue if it contains a double hole.
1951 Node* element_k = LoadFixedDoubleArrayElement( 1940 Node* element_k = LoadFixedDoubleArrayElement(
1952 elements, index_var.value(), MachineType::Float64(), 0, 1941 elements, index_var.value(), MachineType::Float64(), 0,
1953 CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop); 1942 CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop);
1954 1943
1955 BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop); 1944 BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop);
1956 Bind(&continue_loop); 1945 Bind(&continue_loop);
1957 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); 1946 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1)));
1958 Goto(&nan_loop); 1947 Goto(&nan_loop);
1959 } 1948 }
1960 1949
1961 // Search for the Hole 1950 // Search for the Hole
1962 Bind(&hole_loop); 1951 Bind(&hole_loop);
1963 { 1952 {
1964 GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), 1953 GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false);
1965 &return_false);
1966 1954
1967 // Check if the element is a double hole, but don't load it. 1955 // Check if the element is a double hole, but don't load it.
1968 LoadFixedDoubleArrayElement( 1956 LoadFixedDoubleArrayElement(
1969 elements, index_var.value(), MachineType::None(), 0, 1957 elements, index_var.value(), MachineType::None(), 0,
1970 CodeStubAssembler::INTPTR_PARAMETERS, &return_true); 1958 CodeStubAssembler::INTPTR_PARAMETERS, &return_true);
1971 1959
1972 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); 1960 index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1)));
1973 Goto(&hole_loop); 1961 Goto(&hole_loop);
1974 } 1962 }
1975 } 1963 }
(...skipping 875 matching lines...) Expand 10 before | Expand all | Expand 10 after
2851 { 2839 {
2852 Node* message = assembler.SmiConstant(MessageTemplate::kDetachedOperation); 2840 Node* message = assembler.SmiConstant(MessageTemplate::kDetachedOperation);
2853 assembler.CallRuntime(Runtime::kThrowTypeError, context, message, 2841 assembler.CallRuntime(Runtime::kThrowTypeError, context, message,
2854 assembler.HeapConstant(operation)); 2842 assembler.HeapConstant(operation));
2855 assembler.Unreachable(); 2843 assembler.Unreachable();
2856 } 2844 }
2857 } 2845 }
2858 2846
2859 } // namespace internal 2847 } // namespace internal
2860 } // namespace v8 2848 } // 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