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

Side by Side Diff: test/cctest/interpreter/test-interpreter.cc

Issue 2286273002: [interpreter] Make the comparison bytecode handlers collect type feedback. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix. Created 4 years, 3 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
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/execution.h" 7 #include "src/execution.h"
8 #include "src/handles.h" 8 #include "src/handles.h"
9 #include "src/interpreter/bytecode-array-builder.h" 9 #include "src/interpreter/bytecode-array-builder.h"
10 #include "src/interpreter/bytecode-array-iterator.h" 10 #include "src/interpreter/bytecode-array-iterator.h"
(...skipping 1653 matching lines...) Expand 10 before | Expand all | Expand 10 after
1664 12345678, 1664 12345678,
1665 v8::internal::kMaxInt / 4, 1665 v8::internal::kMaxInt / 4,
1666 v8::internal::kMaxInt / 2}; 1666 v8::internal::kMaxInt / 2};
1667 1667
1668 for (size_t c = 0; c < arraysize(kComparisonTypes); c++) { 1668 for (size_t c = 0; c < arraysize(kComparisonTypes); c++) {
1669 Token::Value comparison = kComparisonTypes[c]; 1669 Token::Value comparison = kComparisonTypes[c];
1670 for (size_t i = 0; i < arraysize(inputs); i++) { 1670 for (size_t i = 0; i < arraysize(inputs); i++) {
1671 for (size_t j = 0; j < arraysize(inputs); j++) { 1671 for (size_t j = 0; j < arraysize(inputs); j++) {
1672 HandleAndZoneScope handles; 1672 HandleAndZoneScope handles;
1673 Isolate* isolate = handles.main_isolate(); 1673 Isolate* isolate = handles.main_isolate();
1674 Zone zone(isolate->allocator());
1674 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 1); 1675 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 1);
1675 1676
1677 FeedbackVectorSpec feedback_spec(&zone);
1678 FeedbackVectorSlot slot = feedback_spec.AddGeneralSlot();
1679 Handle<i::TypeFeedbackVector> vector =
1680 NewTypeFeedbackVector(isolate, &feedback_spec);
1681
1676 Register r0(0); 1682 Register r0(0);
1677 builder.LoadLiteral(Smi::FromInt(inputs[i])) 1683 builder.LoadLiteral(Smi::FromInt(inputs[i]))
1678 .StoreAccumulatorInRegister(r0) 1684 .StoreAccumulatorInRegister(r0)
1679 .LoadLiteral(Smi::FromInt(inputs[j])) 1685 .LoadLiteral(Smi::FromInt(inputs[j]))
1680 .CompareOperation(comparison, r0) 1686 .CompareOperation(comparison, r0, vector->GetIndex(slot))
1681 .Return(); 1687 .Return();
1682 1688
1683 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); 1689 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
1684 InterpreterTester tester(isolate, bytecode_array); 1690 InterpreterTester tester(isolate, bytecode_array, vector);
1685 auto callable = tester.GetCallable<>(); 1691 auto callable = tester.GetCallable<>();
1686 Handle<Object> return_value = callable().ToHandleChecked(); 1692 Handle<Object> return_value = callable().ToHandleChecked();
1687 CHECK(return_value->IsBoolean()); 1693 CHECK(return_value->IsBoolean());
1688 CHECK_EQ(return_value->BooleanValue(), 1694 CHECK_EQ(return_value->BooleanValue(),
1689 CompareC(comparison, inputs[i], inputs[j])); 1695 CompareC(comparison, inputs[i], inputs[j]));
1696 Object* feedback = vector->Get(slot);
1697 CHECK(feedback->IsSmi());
1698 CHECK_EQ(BinaryOperationFeedback::kSignedSmall,
1699 static_cast<Smi*>(feedback)->value());
1690 } 1700 }
1691 } 1701 }
1692 } 1702 }
1693 } 1703 }
1694 1704
1695 1705
1696 TEST(InterpreterHeapNumberComparisons) { 1706 TEST(InterpreterHeapNumberComparisons) {
1697 double inputs[] = {std::numeric_limits<double>::min(), 1707 double inputs[] = {std::numeric_limits<double>::min(),
1698 std::numeric_limits<double>::max(), 1708 std::numeric_limits<double>::max(),
1699 -0.001, 1709 -0.001,
1700 0.01, 1710 0.01,
1701 0.1000001, 1711 0.1000001,
1702 1e99, 1712 1e99,
1703 -1e-99}; 1713 -1e-99};
1704 for (size_t c = 0; c < arraysize(kComparisonTypes); c++) { 1714 for (size_t c = 0; c < arraysize(kComparisonTypes); c++) {
1705 Token::Value comparison = kComparisonTypes[c]; 1715 Token::Value comparison = kComparisonTypes[c];
1706 for (size_t i = 0; i < arraysize(inputs); i++) { 1716 for (size_t i = 0; i < arraysize(inputs); i++) {
1707 for (size_t j = 0; j < arraysize(inputs); j++) { 1717 for (size_t j = 0; j < arraysize(inputs); j++) {
1708 HandleAndZoneScope handles; 1718 HandleAndZoneScope handles;
1709 Isolate* isolate = handles.main_isolate(); 1719 Isolate* isolate = handles.main_isolate();
1710 Factory* factory = isolate->factory(); 1720 Factory* factory = isolate->factory();
1721 Zone zone(isolate->allocator());
1711 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 1); 1722 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 1);
1712 1723
1724 FeedbackVectorSpec feedback_spec(&zone);
1725 FeedbackVectorSlot slot = feedback_spec.AddGeneralSlot();
1726 Handle<i::TypeFeedbackVector> vector =
1727 NewTypeFeedbackVector(isolate, &feedback_spec);
1728
1713 Register r0(0); 1729 Register r0(0);
1714 builder.LoadLiteral(factory->NewHeapNumber(inputs[i])) 1730 builder.LoadLiteral(factory->NewHeapNumber(inputs[i]))
1715 .StoreAccumulatorInRegister(r0) 1731 .StoreAccumulatorInRegister(r0)
1716 .LoadLiteral(factory->NewHeapNumber(inputs[j])) 1732 .LoadLiteral(factory->NewHeapNumber(inputs[j]))
1717 .CompareOperation(comparison, r0) 1733 .CompareOperation(comparison, r0, vector->GetIndex(slot))
1718 .Return(); 1734 .Return();
1719 1735
1720 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); 1736 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
1721 InterpreterTester tester(isolate, bytecode_array); 1737 InterpreterTester tester(isolate, bytecode_array, vector);
1722 auto callable = tester.GetCallable<>(); 1738 auto callable = tester.GetCallable<>();
1723 Handle<Object> return_value = callable().ToHandleChecked(); 1739 Handle<Object> return_value = callable().ToHandleChecked();
1724 CHECK(return_value->IsBoolean()); 1740 CHECK(return_value->IsBoolean());
1725 CHECK_EQ(return_value->BooleanValue(), 1741 CHECK_EQ(return_value->BooleanValue(),
1726 CompareC(comparison, inputs[i], inputs[j])); 1742 CompareC(comparison, inputs[i], inputs[j]));
1743 Object* feedback = vector->Get(slot);
1744 CHECK(feedback->IsSmi());
1745 CHECK_EQ(BinaryOperationFeedback::kNumber,
1746 static_cast<Smi*>(feedback)->value());
1727 } 1747 }
1728 } 1748 }
1729 } 1749 }
1730 } 1750 }
1731 1751
1732 1752
1733 TEST(InterpreterStringComparisons) { 1753 TEST(InterpreterStringComparisons) {
1734 HandleAndZoneScope handles; 1754 HandleAndZoneScope handles;
1735 Isolate* isolate = handles.main_isolate(); 1755 Isolate* isolate = handles.main_isolate();
1736 Factory* factory = isolate->factory(); 1756 Factory* factory = isolate->factory();
1757 Zone zone(isolate->allocator());
1737 1758
1738 std::string inputs[] = {"A", "abc", "z", "", "Foo!", "Foo"}; 1759 std::string inputs[] = {"A", "abc", "z", "", "Foo!", "Foo"};
1739 1760
1740 for (size_t c = 0; c < arraysize(kComparisonTypes); c++) { 1761 for (size_t c = 0; c < arraysize(kComparisonTypes); c++) {
1741 Token::Value comparison = kComparisonTypes[c]; 1762 Token::Value comparison = kComparisonTypes[c];
1742 for (size_t i = 0; i < arraysize(inputs); i++) { 1763 for (size_t i = 0; i < arraysize(inputs); i++) {
1743 for (size_t j = 0; j < arraysize(inputs); j++) { 1764 for (size_t j = 0; j < arraysize(inputs); j++) {
1744 CanonicalHandleScope canonical(isolate); 1765 CanonicalHandleScope canonical(isolate);
1745 const char* lhs = inputs[i].c_str(); 1766 const char* lhs = inputs[i].c_str();
1746 const char* rhs = inputs[j].c_str(); 1767 const char* rhs = inputs[j].c_str();
1768
1769 FeedbackVectorSpec feedback_spec(&zone);
1770 FeedbackVectorSlot slot = feedback_spec.AddGeneralSlot();
1771 Handle<i::TypeFeedbackVector> vector =
1772 NewTypeFeedbackVector(isolate, &feedback_spec);
1773
1747 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 1); 1774 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 1);
1748 Register r0(0); 1775 Register r0(0);
1749 builder.LoadLiteral(factory->NewStringFromAsciiChecked(lhs)) 1776 builder.LoadLiteral(factory->NewStringFromAsciiChecked(lhs))
1750 .StoreAccumulatorInRegister(r0) 1777 .StoreAccumulatorInRegister(r0)
1751 .LoadLiteral(factory->NewStringFromAsciiChecked(rhs)) 1778 .LoadLiteral(factory->NewStringFromAsciiChecked(rhs))
1752 .CompareOperation(comparison, r0) 1779 .CompareOperation(comparison, r0, vector->GetIndex(slot))
1753 .Return(); 1780 .Return();
1754 1781
1755 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); 1782 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
1756 InterpreterTester tester(isolate, bytecode_array); 1783 InterpreterTester tester(isolate, bytecode_array, vector);
1757 auto callable = tester.GetCallable<>(); 1784 auto callable = tester.GetCallable<>();
1758 Handle<Object> return_value = callable().ToHandleChecked(); 1785 Handle<Object> return_value = callable().ToHandleChecked();
1759 CHECK(return_value->IsBoolean()); 1786 CHECK(return_value->IsBoolean());
1760 CHECK_EQ(return_value->BooleanValue(), 1787 CHECK_EQ(return_value->BooleanValue(),
1761 CompareC(comparison, inputs[i], inputs[j])); 1788 CompareC(comparison, inputs[i], inputs[j]));
1789 Object* feedback = vector->Get(slot);
1790 CHECK(feedback->IsSmi());
1791 CHECK_EQ(BinaryOperationFeedback::kAny,
1792 static_cast<Smi*>(feedback)->value());
1762 } 1793 }
1763 } 1794 }
1764 } 1795 }
1765 } 1796 }
1766 1797
1767 1798
1768 TEST(InterpreterMixedComparisons) { 1799 TEST(InterpreterMixedComparisons) {
1769 // This test compares a HeapNumber with a String. The latter is 1800 // This test compares a HeapNumber with a String. The latter is
1770 // convertible to a HeapNumber so comparison will be between numeric 1801 // convertible to a HeapNumber so comparison will be between numeric
1771 // values except for the strict comparisons where no conversion is 1802 // values except for the strict comparisons where no conversion is
(...skipping 10 matching lines...) Expand all
1782 const char* lhs_cstr = inputs[i]; 1813 const char* lhs_cstr = inputs[i];
1783 const char* rhs_cstr = inputs[j]; 1814 const char* rhs_cstr = inputs[j];
1784 double lhs = StringToDouble(&unicode_cache, lhs_cstr, 1815 double lhs = StringToDouble(&unicode_cache, lhs_cstr,
1785 ConversionFlags::NO_FLAGS); 1816 ConversionFlags::NO_FLAGS);
1786 double rhs = StringToDouble(&unicode_cache, rhs_cstr, 1817 double rhs = StringToDouble(&unicode_cache, rhs_cstr,
1787 ConversionFlags::NO_FLAGS); 1818 ConversionFlags::NO_FLAGS);
1788 HandleAndZoneScope handles; 1819 HandleAndZoneScope handles;
1789 Isolate* isolate = handles.main_isolate(); 1820 Isolate* isolate = handles.main_isolate();
1790 Factory* factory = isolate->factory(); 1821 Factory* factory = isolate->factory();
1791 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 1); 1822 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 1);
1823 Zone zone(isolate->allocator());
1824
1825 FeedbackVectorSpec feedback_spec(&zone);
1826 FeedbackVectorSlot slot = feedback_spec.AddGeneralSlot();
1827 Handle<i::TypeFeedbackVector> vector =
1828 NewTypeFeedbackVector(isolate, &feedback_spec);
1792 1829
1793 Register r0(0); 1830 Register r0(0);
1794 if (pass == 0) { 1831 if (pass == 0) {
1795 // Comparison with HeapNumber on the lhs and String on the rhs 1832 // Comparison with HeapNumber on the lhs and String on the rhs
1796 builder.LoadLiteral(factory->NewNumber(lhs)) 1833 builder.LoadLiteral(factory->NewNumber(lhs))
1797 .StoreAccumulatorInRegister(r0) 1834 .StoreAccumulatorInRegister(r0)
1798 .LoadLiteral(factory->NewStringFromAsciiChecked(rhs_cstr)) 1835 .LoadLiteral(factory->NewStringFromAsciiChecked(rhs_cstr))
1799 .CompareOperation(comparison, r0) 1836 .CompareOperation(comparison, r0, vector->GetIndex(slot))
1800 .Return(); 1837 .Return();
1801 } else { 1838 } else {
1802 // Comparison with HeapNumber on the rhs and String on the lhs 1839 // Comparison with HeapNumber on the rhs and String on the lhs
1803 builder.LoadLiteral(factory->NewStringFromAsciiChecked(lhs_cstr)) 1840 builder.LoadLiteral(factory->NewStringFromAsciiChecked(lhs_cstr))
1804 .StoreAccumulatorInRegister(r0) 1841 .StoreAccumulatorInRegister(r0)
1805 .LoadLiteral(factory->NewNumber(rhs)) 1842 .LoadLiteral(factory->NewNumber(rhs))
1806 .CompareOperation(comparison, r0) 1843 .CompareOperation(comparison, r0, vector->GetIndex(slot))
1807 .Return(); 1844 .Return();
1808 } 1845 }
1809 1846
1810 Handle<BytecodeArray> bytecode_array = 1847 Handle<BytecodeArray> bytecode_array =
1811 builder.ToBytecodeArray(isolate); 1848 builder.ToBytecodeArray(isolate);
1812 InterpreterTester tester(isolate, bytecode_array); 1849 InterpreterTester tester(isolate, bytecode_array, vector);
1813 auto callable = tester.GetCallable<>(); 1850 auto callable = tester.GetCallable<>();
1814 Handle<Object> return_value = callable().ToHandleChecked(); 1851 Handle<Object> return_value = callable().ToHandleChecked();
1815 CHECK(return_value->IsBoolean()); 1852 CHECK(return_value->IsBoolean());
1816 CHECK_EQ(return_value->BooleanValue(), 1853 CHECK_EQ(return_value->BooleanValue(),
1817 CompareC(comparison, lhs, rhs, true)); 1854 CompareC(comparison, lhs, rhs, true));
1855 Object* feedback = vector->Get(slot);
1856 CHECK(feedback->IsSmi());
1857 CHECK_EQ(BinaryOperationFeedback::kAny,
1858 static_cast<Smi*>(feedback)->value());
1818 } 1859 }
1819 } 1860 }
1820 } 1861 }
1821 } 1862 }
1822 } 1863 }
1823 1864
1824 TEST(InterpreterStrictNotEqual) { 1865 TEST(InterpreterStrictNotEqual) {
1825 HandleAndZoneScope handles; 1866 HandleAndZoneScope handles;
1826 Isolate* isolate = handles.main_isolate(); 1867 Isolate* isolate = handles.main_isolate();
1827 Factory* factory = isolate->factory(); 1868 Factory* factory = isolate->factory();
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1903 Handle<i::Object> other = factory->NewNumber(3.3333); 1944 Handle<i::Object> other = factory->NewNumber(3.3333);
1904 Handle<i::Object> cases[] = {Handle<i::Object>::cast(instance), other}; 1945 Handle<i::Object> cases[] = {Handle<i::Object>::cast(instance), other};
1905 for (size_t i = 0; i < arraysize(cases); i++) { 1946 for (size_t i = 0; i < arraysize(cases); i++) {
1906 bool expected_value = (i == 0); 1947 bool expected_value = (i == 0);
1907 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 1); 1948 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 1);
1908 1949
1909 Register r0(0); 1950 Register r0(0);
1910 builder.LoadLiteral(cases[i]); 1951 builder.LoadLiteral(cases[i]);
1911 builder.StoreAccumulatorInRegister(r0) 1952 builder.StoreAccumulatorInRegister(r0)
1912 .LoadLiteral(func) 1953 .LoadLiteral(func)
1913 .CompareOperation(Token::Value::INSTANCEOF, r0) 1954 .CompareOperation(Token::Value::INSTANCEOF, r0, 0)
1914 .Return(); 1955 .Return();
1915 1956
1916 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); 1957 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
1917 InterpreterTester tester(isolate, bytecode_array); 1958 InterpreterTester tester(isolate, bytecode_array);
1918 auto callable = tester.GetCallable<>(); 1959 auto callable = tester.GetCallable<>();
1919 Handle<Object> return_value = callable().ToHandleChecked(); 1960 Handle<Object> return_value = callable().ToHandleChecked();
1920 CHECK(return_value->IsBoolean()); 1961 CHECK(return_value->IsBoolean());
1921 CHECK_EQ(return_value->BooleanValue(), expected_value); 1962 CHECK_EQ(return_value->BooleanValue(), expected_value);
1922 } 1963 }
1923 } 1964 }
1924 1965
1925 1966
1926 TEST(InterpreterTestIn) { 1967 TEST(InterpreterTestIn) {
1927 HandleAndZoneScope handles; 1968 HandleAndZoneScope handles;
1928 Isolate* isolate = handles.main_isolate(); 1969 Isolate* isolate = handles.main_isolate();
1929 Factory* factory = isolate->factory(); 1970 Factory* factory = isolate->factory();
1930 // Allocate an array 1971 // Allocate an array
1931 Handle<i::JSArray> array = 1972 Handle<i::JSArray> array =
1932 factory->NewJSArray(0, i::ElementsKind::FAST_SMI_ELEMENTS); 1973 factory->NewJSArray(0, i::ElementsKind::FAST_SMI_ELEMENTS);
1933 // Check for these properties on the array object 1974 // Check for these properties on the array object
1934 const char* properties[] = {"length", "fuzzle", "x", "0"}; 1975 const char* properties[] = {"length", "fuzzle", "x", "0"};
1935 for (size_t i = 0; i < arraysize(properties); i++) { 1976 for (size_t i = 0; i < arraysize(properties); i++) {
1936 bool expected_value = (i == 0); 1977 bool expected_value = (i == 0);
1937 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 1); 1978 BytecodeArrayBuilder builder(isolate, handles.main_zone(), 0, 0, 1);
1938 1979
1939 Register r0(0); 1980 Register r0(0);
1940 builder.LoadLiteral(factory->NewStringFromAsciiChecked(properties[i])) 1981 builder.LoadLiteral(factory->NewStringFromAsciiChecked(properties[i]))
1941 .StoreAccumulatorInRegister(r0) 1982 .StoreAccumulatorInRegister(r0)
1942 .LoadLiteral(Handle<Object>::cast(array)) 1983 .LoadLiteral(Handle<Object>::cast(array))
1943 .CompareOperation(Token::Value::IN, r0) 1984 .CompareOperation(Token::Value::IN, r0, 0)
1944 .Return(); 1985 .Return();
1945 1986
1946 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate); 1987 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(isolate);
1947 InterpreterTester tester(isolate, bytecode_array); 1988 InterpreterTester tester(isolate, bytecode_array);
1948 auto callable = tester.GetCallable<>(); 1989 auto callable = tester.GetCallable<>();
1949 Handle<Object> return_value = callable().ToHandleChecked(); 1990 Handle<Object> return_value = callable().ToHandleChecked();
1950 CHECK(return_value->IsBoolean()); 1991 CHECK(return_value->IsBoolean());
1951 CHECK_EQ(return_value->BooleanValue(), expected_value); 1992 CHECK_EQ(return_value->BooleanValue(), expected_value);
1952 } 1993 }
1953 } 1994 }
(...skipping 2726 matching lines...) Expand 10 before | Expand all | Expand 10 after
4680 auto callable = tester.GetCallable<>(); 4721 auto callable = tester.GetCallable<>();
4681 4722
4682 Handle<i::Object> return_value = callable().ToHandleChecked(); 4723 Handle<i::Object> return_value = callable().ToHandleChecked();
4683 CHECK(return_value->SameValue(*tests[i].second)); 4724 CHECK(return_value->SameValue(*tests[i].second));
4684 } 4725 }
4685 } 4726 }
4686 4727
4687 } // namespace interpreter 4728 } // namespace interpreter
4688 } // namespace internal 4729 } // namespace internal
4689 } // namespace v8 4730 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698