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

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

Issue 2232063002: [builtins] WIP: Array indexOf in TurboFan/Runtime (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Move fast path FastElements -> FastSmiOrObjectElements Created 4 years, 4 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 | « src/builtins/builtins.h ('k') | src/elements.h » ('j') | 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/elements.h" 9 #include "src/elements.h"
10 10
(...skipping 1721 matching lines...) Expand 10 before | Expand all | Expand 10 after
1732 1732
1733 assembler->Bind(&return_false); 1733 assembler->Bind(&return_false);
1734 assembler->Return(assembler->BooleanConstant(false)); 1734 assembler->Return(assembler->BooleanConstant(false));
1735 1735
1736 assembler->Bind(&call_runtime); 1736 assembler->Bind(&call_runtime);
1737 assembler->Return(assembler->CallRuntime(Runtime::kArrayIncludes_Slow, 1737 assembler->Return(assembler->CallRuntime(Runtime::kArrayIncludes_Slow,
1738 context, array, search_element, 1738 context, array, search_element,
1739 start_from)); 1739 start_from));
1740 } 1740 }
1741 1741
1742 void Builtins::Generate_ArrayIndexOf(CodeStubAssembler* assembler) {
1743 typedef compiler::Node Node;
1744 typedef CodeStubAssembler::Label Label;
1745 typedef CodeStubAssembler::Variable Variable;
1746
1747 Node* array = assembler->Parameter(0);
1748 Node* search_element = assembler->Parameter(1);
1749 Node* start_from = assembler->Parameter(2);
1750 Node* context = assembler->Parameter(3 + 2);
1751
1752 Node* int32_zero = assembler->Int32Constant(0);
1753 Node* int32_one = assembler->Int32Constant(1);
1754
1755 Node* undefined = assembler->UndefinedConstant();
1756 Node* heap_number_map = assembler->HeapNumberMapConstant();
1757
1758 Variable len_var(assembler, MachineRepresentation::kWord32),
1759 index_var(assembler, MachineRepresentation::kWord32),
1760 start_from_var(assembler, MachineRepresentation::kWord32);
1761
1762 Label init_k(assembler), return_found(assembler), return_not_found(assembler),
1763 call_runtime(assembler);
1764
1765 Label init_len(assembler);
1766
1767 index_var.Bind(int32_zero);
1768 len_var.Bind(int32_zero);
1769
1770 // Take slow path if not a JSArray, if retrieving elements requires
1771 // traversing prototype, or if access checks are required.
1772 assembler->BranchIfFastJSArray(array, context, &init_len, &call_runtime);
1773
1774 assembler->Bind(&init_len);
1775 {
1776 // Handle case where JSArray length is not an Smi in the runtime
1777 Node* len = assembler->LoadObjectField(array, JSArray::kLengthOffset);
1778 assembler->GotoUnless(assembler->WordIsSmi(len), &call_runtime);
1779
1780 len_var.Bind(assembler->SmiToWord(len));
1781 assembler->Branch(assembler->Word32Equal(len_var.value(), int32_zero),
1782 &return_not_found, &init_k);
1783 }
1784
1785 assembler->Bind(&init_k);
1786 {
1787 Label done(assembler), init_k_smi(assembler), init_k_heap_num(assembler),
1788 init_k_zero(assembler), init_k_n(assembler);
1789 Callable call_to_integer = CodeFactory::ToInteger(assembler->isolate());
1790 Node* tagged_n = assembler->CallStub(call_to_integer, context, start_from);
1791
1792 assembler->Branch(assembler->WordIsSmi(tagged_n), &init_k_smi,
1793 &init_k_heap_num);
1794
1795 assembler->Bind(&init_k_smi);
1796 {
1797 start_from_var.Bind(assembler->SmiToWord32(tagged_n));
1798 assembler->Goto(&init_k_n);
1799 }
1800
1801 assembler->Bind(&init_k_heap_num);
1802 {
1803 Label do_return_not_found(assembler);
1804 Node* fp_len = assembler->ChangeInt32ToFloat64(len_var.value());
1805 Node* fp_n = assembler->LoadHeapNumberValue(tagged_n);
1806 assembler->GotoIf(assembler->Float64GreaterThanOrEqual(fp_n, fp_len),
1807 &do_return_not_found);
1808 start_from_var.Bind(assembler->TruncateFloat64ToWord32(fp_n));
1809 assembler->Goto(&init_k_n);
1810
1811 assembler->Bind(&do_return_not_found);
1812 {
1813 index_var.Bind(int32_zero);
1814 assembler->Goto(&return_not_found);
1815 }
1816 }
1817
1818 assembler->Bind(&init_k_n);
1819 {
1820 Label if_positive(assembler), if_negative(assembler), done(assembler);
1821 assembler->Branch(
1822 assembler->Int32LessThan(start_from_var.value(), int32_zero),
1823 &if_negative, &if_positive);
1824
1825 assembler->Bind(&if_positive);
1826 {
1827 index_var.Bind(start_from_var.value());
1828 assembler->Goto(&done);
1829 }
1830
1831 assembler->Bind(&if_negative);
1832 {
1833 index_var.Bind(
1834 assembler->Int32Add(len_var.value(), start_from_var.value()));
1835 assembler->Branch(
1836 assembler->Int32LessThan(index_var.value(), int32_zero),
1837 &init_k_zero, &done);
1838 }
1839
1840 assembler->Bind(&init_k_zero);
1841 {
1842 index_var.Bind(int32_zero);
1843 assembler->Goto(&done);
1844 }
1845
1846 assembler->Bind(&done);
1847 }
1848 }
1849
1850 static int32_t kElementsKind[] = {
1851 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS,
1852 FAST_HOLEY_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS,
1853 };
1854
1855 Label if_smiorobjects(assembler), if_packed_doubles(assembler),
1856 if_holey_doubles(assembler);
1857 Label* element_kind_handlers[] = {&if_smiorobjects, &if_smiorobjects,
1858 &if_smiorobjects, &if_smiorobjects,
1859 &if_packed_doubles, &if_holey_doubles};
1860
1861 Node* map = assembler->LoadMap(array);
1862 Node* bit_field2 = assembler->LoadMapBitField2(map);
1863 Node* elements_kind =
1864 assembler->BitFieldDecode<Map::ElementsKindBits>(bit_field2);
1865 Node* elements = assembler->LoadElements(array);
1866 assembler->Switch(elements_kind, &return_not_found, kElementsKind,
1867 element_kind_handlers, arraysize(kElementsKind));
1868
1869 assembler->Bind(&if_smiorobjects);
1870 {
1871 Variable search_num(assembler, MachineRepresentation::kFloat64);
1872 Label ident_loop(assembler, &index_var),
1873 heap_num_loop(assembler, &search_num),
1874 string_loop(assembler, &index_var), simd_loop(assembler),
1875 undef_loop(assembler, &index_var), not_smi(assembler),
1876 not_heap_num(assembler);
1877
1878 assembler->GotoUnless(assembler->WordIsSmi(search_element), &not_smi);
1879 search_num.Bind(assembler->SmiToFloat64(search_element));
1880 assembler->Goto(&heap_num_loop);
1881
1882 assembler->Bind(&not_smi);
1883 assembler->GotoIf(assembler->WordEqual(search_element, undefined),
1884 &undef_loop);
1885 Node* map = assembler->LoadMap(search_element);
1886 assembler->GotoIf(assembler->WordNotEqual(map, heap_number_map),
1887 &not_heap_num);
1888 search_num.Bind(assembler->LoadHeapNumberValue(search_element));
1889 assembler->Goto(&heap_num_loop);
1890
1891 assembler->Bind(&not_heap_num);
1892 Node* search_type = assembler->LoadMapInstanceType(map);
1893 assembler->GotoIf(
1894 assembler->Int32LessThan(
1895 search_type, assembler->Int32Constant(FIRST_NONSTRING_TYPE)),
1896 &string_loop);
1897 assembler->GotoIf(
1898 assembler->WordEqual(search_type,
1899 assembler->Int32Constant(SIMD128_VALUE_TYPE)),
1900 &simd_loop);
1901 assembler->Goto(&ident_loop);
1902
1903 assembler->Bind(&ident_loop);
1904 {
1905 assembler->GotoUnless(
1906 assembler->Int32LessThan(index_var.value(), len_var.value()),
1907 &return_not_found);
1908 Node* element_k =
1909 assembler->LoadFixedArrayElement(elements, index_var.value());
1910 assembler->GotoIf(assembler->WordEqual(element_k, search_element),
1911 &return_found);
1912
1913 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one));
1914 assembler->Goto(&ident_loop);
1915 }
1916
1917 assembler->Bind(&undef_loop);
1918 {
1919 assembler->GotoUnless(
1920 assembler->Int32LessThan(index_var.value(), len_var.value()),
1921 &return_not_found);
1922 Node* element_k =
1923 assembler->LoadFixedArrayElement(elements, index_var.value());
1924 assembler->GotoIf(assembler->WordEqual(element_k, undefined),
1925 &return_found);
1926
1927 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one));
1928 assembler->Goto(&undef_loop);
1929 }
1930
1931 assembler->Bind(&heap_num_loop);
1932 {
1933 Label not_nan_loop(assembler, &index_var);
1934 assembler->BranchIfFloat64IsNaN(search_num.value(), &return_not_found,
1935 &not_nan_loop);
1936
1937 assembler->Bind(&not_nan_loop);
1938 {
1939 Label continue_loop(assembler), not_smi(assembler);
1940 assembler->GotoUnless(
1941 assembler->Int32LessThan(index_var.value(), len_var.value()),
1942 &return_not_found);
1943 Node* element_k =
1944 assembler->LoadFixedArrayElement(elements, index_var.value());
1945 assembler->GotoUnless(assembler->WordIsSmi(element_k), &not_smi);
1946 assembler->Branch(
1947 assembler->Float64Equal(search_num.value(),
1948 assembler->SmiToFloat64(element_k)),
1949 &return_found, &continue_loop);
1950
1951 assembler->Bind(&not_smi);
1952 assembler->GotoIf(assembler->WordNotEqual(assembler->LoadMap(element_k),
1953 heap_number_map),
1954 &continue_loop);
1955 assembler->BranchIfFloat64Equal(
1956 search_num.value(), assembler->LoadHeapNumberValue(element_k),
1957 &return_found, &continue_loop);
1958
1959 assembler->Bind(&continue_loop);
1960 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one));
1961 assembler->Goto(&not_nan_loop);
1962 }
1963 }
1964
1965 assembler->Bind(&string_loop);
1966 {
1967 Label continue_loop(assembler);
1968 assembler->GotoUnless(
1969 assembler->Int32LessThan(index_var.value(), len_var.value()),
1970 &return_not_found);
1971 Node* element_k =
1972 assembler->LoadFixedArrayElement(elements, index_var.value());
1973 assembler->GotoIf(assembler->WordIsSmi(element_k), &continue_loop);
1974 assembler->GotoUnless(assembler->Int32LessThan(
1975 assembler->LoadInstanceType(element_k),
1976 assembler->Int32Constant(FIRST_NONSTRING_TYPE)),
1977 &continue_loop);
1978
1979 // TODO(bmeurer): Consider inlining the StringEqual logic here.
1980 Callable callable = CodeFactory::StringEqual(assembler->isolate());
1981 Node* result =
1982 assembler->CallStub(callable, context, search_element, element_k);
1983 assembler->Branch(
1984 assembler->WordEqual(assembler->BooleanConstant(true), result),
1985 &return_found, &continue_loop);
1986
1987 assembler->Bind(&continue_loop);
1988 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one));
1989 assembler->Goto(&string_loop);
1990 }
1991
1992 assembler->Bind(&simd_loop);
1993 {
1994 Label continue_loop(assembler, &index_var),
1995 loop_body(assembler, &index_var);
1996 Node* map = assembler->LoadMap(search_element);
1997
1998 assembler->Goto(&loop_body);
1999 assembler->Bind(&loop_body);
2000 assembler->GotoUnless(
2001 assembler->Int32LessThan(index_var.value(), len_var.value()),
2002 &return_not_found);
2003
2004 Node* element_k =
2005 assembler->LoadFixedArrayElement(elements, index_var.value());
2006 assembler->GotoIf(assembler->WordIsSmi(element_k), &continue_loop);
2007
2008 Node* map_k = assembler->LoadMap(element_k);
2009 assembler->BranchIfSimd128Equal(search_element, map, element_k, map_k,
2010 &return_found, &continue_loop);
2011
2012 assembler->Bind(&continue_loop);
2013 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one));
2014 assembler->Goto(&loop_body);
2015 }
2016 }
2017
2018 assembler->Bind(&if_packed_doubles);
2019 {
2020 Label not_nan_loop(assembler, &index_var), search_notnan(assembler);
2021 Variable search_num(assembler, MachineRepresentation::kFloat64);
2022
2023 assembler->GotoUnless(assembler->WordIsSmi(search_element), &search_notnan);
2024 search_num.Bind(assembler->SmiToFloat64(search_element));
2025 assembler->Goto(&not_nan_loop);
2026
2027 assembler->Bind(&search_notnan);
2028 assembler->GotoIf(assembler->WordNotEqual(
2029 assembler->LoadMap(search_element), heap_number_map),
2030 &return_not_found);
2031
2032 search_num.Bind(assembler->LoadHeapNumberValue(search_element));
2033
2034 assembler->BranchIfFloat64IsNaN(search_num.value(), &return_not_found,
2035 &not_nan_loop);
2036
2037 // Search for HeapNumber
2038 assembler->Bind(&not_nan_loop);
2039 {
2040 Label continue_loop(assembler);
2041 assembler->GotoUnless(
2042 assembler->Int32LessThan(index_var.value(), len_var.value()),
2043 &return_not_found);
2044 Node* element_k = assembler->LoadFixedDoubleArrayElement(
2045 elements, index_var.value(), MachineType::Float64());
2046 assembler->BranchIfFloat64Equal(element_k, search_num.value(),
2047 &return_found, &continue_loop);
2048 assembler->Bind(&continue_loop);
2049 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one));
2050 assembler->Goto(&not_nan_loop);
2051 }
2052 }
2053
2054 assembler->Bind(&if_holey_doubles);
2055 {
2056 Label not_nan_loop(assembler, &index_var), search_notnan(assembler);
2057 Variable search_num(assembler, MachineRepresentation::kFloat64);
2058
2059 assembler->GotoUnless(assembler->WordIsSmi(search_element), &search_notnan);
2060 search_num.Bind(assembler->SmiToFloat64(search_element));
2061 assembler->Goto(&not_nan_loop);
2062
2063 assembler->Bind(&search_notnan);
2064 assembler->GotoIf(assembler->WordNotEqual(
2065 assembler->LoadMap(search_element), heap_number_map),
2066 &return_not_found);
2067
2068 search_num.Bind(assembler->LoadHeapNumberValue(search_element));
2069
2070 assembler->BranchIfFloat64IsNaN(search_num.value(), &return_not_found,
2071 &not_nan_loop);
2072
2073 // Search for HeapNumber
2074 assembler->Bind(&not_nan_loop);
2075 {
2076 Label continue_loop(assembler);
2077 assembler->GotoUnless(
2078 assembler->Int32LessThan(index_var.value(), len_var.value()),
2079 &return_not_found);
2080
2081 if (kPointerSize == kDoubleSize) {
2082 Node* element = assembler->LoadFixedDoubleArrayElement(
2083 elements, index_var.value(), MachineType::Uint64());
2084 Node* the_hole = assembler->Int64Constant(kHoleNanInt64);
2085 assembler->GotoIf(assembler->Word64Equal(element, the_hole),
2086 &continue_loop);
2087 } else {
2088 Node* element_upper = assembler->LoadFixedDoubleArrayElement(
2089 elements, index_var.value(), MachineType::Uint32(),
2090 kIeeeDoubleExponentWordOffset);
2091 assembler->GotoIf(
2092 assembler->Word32Equal(element_upper,
2093 assembler->Int32Constant(kHoleNanUpper32)),
2094 &continue_loop);
2095 }
2096
2097 Node* element_k = assembler->LoadFixedDoubleArrayElement(
2098 elements, index_var.value(), MachineType::Float64());
2099 assembler->BranchIfFloat64Equal(element_k, search_num.value(),
2100 &return_found, &continue_loop);
2101 assembler->Bind(&continue_loop);
2102 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one));
2103 assembler->Goto(&not_nan_loop);
2104 }
2105 }
2106
2107 assembler->Bind(&return_found);
2108 assembler->Return(assembler->ChangeInt32ToTagged(index_var.value()));
2109
2110 assembler->Bind(&return_not_found);
2111 assembler->Return(assembler->NumberConstant(-1));
2112
2113 assembler->Bind(&call_runtime);
2114 assembler->Return(assembler->CallRuntime(Runtime::kArrayIndexOf, context,
2115 array, search_element, start_from));
2116 }
2117
1742 } // namespace internal 2118 } // namespace internal
1743 } // namespace v8 2119 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins.h ('k') | src/elements.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698