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

Side by Side Diff: src/mips/lithium-mips.cc

Issue 213733003: MIPS: Only assign environments when they are actually needed. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 8 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 | Annotate | Revision Log
« 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after
932 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { 932 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
933 return new(zone()) LGoto(instr->FirstSuccessor()); 933 return new(zone()) LGoto(instr->FirstSuccessor());
934 } 934 }
935 935
936 936
937 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { 937 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
938 LInstruction* goto_instr = CheckElideControlInstruction(instr); 938 LInstruction* goto_instr = CheckElideControlInstruction(instr);
939 if (goto_instr != NULL) return goto_instr; 939 if (goto_instr != NULL) return goto_instr;
940 940
941 HValue* value = instr->value(); 941 HValue* value = instr->value();
942 LBranch* result = new(zone()) LBranch(UseRegister(value)); 942 Representation r = value->representation();
943 // Tagged values that are not known smis or booleans require a
944 // deoptimization environment. If the instruction is generic no
945 // environment is needed since all cases are handled.
946 Representation rep = value->representation();
947 HType type = value->type(); 943 HType type = value->type();
948 ToBooleanStub::Types expected = instr->expected_input_types(); 944 ToBooleanStub::Types expected = instr->expected_input_types();
949 if (rep.IsTagged() && !type.IsSmi() && !type.IsBoolean() && 945 if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic();
950 !expected.IsGeneric()) { 946
951 return AssignEnvironment(result); 947 bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() ||
948 type.IsJSArray() || type.IsHeapNumber() || type.IsString();
949 LInstruction* branch = new(zone()) LBranch(UseRegister(value));
950 if (!easy_case &&
951 ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) ||
952 !expected.IsGeneric())) {
953 branch = AssignEnvironment(branch);
952 } 954 }
953 return result; 955 return branch;
954 } 956 }
955 957
956 958
957 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { 959 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) {
958 LInstruction* goto_instr = CheckElideControlInstruction(instr); 960 LInstruction* goto_instr = CheckElideControlInstruction(instr);
959 if (goto_instr != NULL) return goto_instr; 961 if (goto_instr != NULL) return goto_instr;
960 962
961 ASSERT(instr->value()->representation().IsTagged()); 963 ASSERT(instr->value()->representation().IsTagged());
962 LOperand* value = UseRegisterAtStart(instr->value()); 964 LOperand* value = UseRegisterAtStart(instr->value());
963 LOperand* temp = TempRegister(); 965 LOperand* temp = TempRegister();
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 return DefineFixedDouble(result, f4); 1157 return DefineFixedDouble(result, f4);
1156 } 1158 }
1157 1159
1158 1160
1159 LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) { 1161 LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) {
1160 Representation r = instr->value()->representation(); 1162 Representation r = instr->value()->representation();
1161 LOperand* context = (r.IsDouble() || r.IsSmiOrInteger32()) 1163 LOperand* context = (r.IsDouble() || r.IsSmiOrInteger32())
1162 ? NULL 1164 ? NULL
1163 : UseFixed(instr->context(), cp); 1165 : UseFixed(instr->context(), cp);
1164 LOperand* input = UseRegister(instr->value()); 1166 LOperand* input = UseRegister(instr->value());
1165 LMathAbs* result = new(zone()) LMathAbs(context, input); 1167 LInstruction* result =
1166 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); 1168 DefineAsRegister(new(zone()) LMathAbs(context, input));
1169 if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result);
1170 if (!r.IsDouble()) result = AssignEnvironment(result);
1171 return result;
1167 } 1172 }
1168 1173
1169 1174
1170 LInstruction* LChunkBuilder::DoMathFloor(HUnaryMathOperation* instr) { 1175 LInstruction* LChunkBuilder::DoMathFloor(HUnaryMathOperation* instr) {
1171 LOperand* input = UseRegister(instr->value()); 1176 LOperand* input = UseRegister(instr->value());
1172 LOperand* temp = TempRegister(); 1177 LOperand* temp = TempRegister();
1173 LMathFloor* result = new(zone()) LMathFloor(input, temp); 1178 LMathFloor* result = new(zone()) LMathFloor(input, temp);
1174 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); 1179 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
1175 } 1180 }
1176 1181
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1289 return result; 1294 return result;
1290 } 1295 }
1291 1296
1292 1297
1293 LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) { 1298 LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) {
1294 ASSERT(instr->representation().IsSmiOrInteger32()); 1299 ASSERT(instr->representation().IsSmiOrInteger32());
1295 ASSERT(instr->left()->representation().Equals(instr->representation())); 1300 ASSERT(instr->left()->representation().Equals(instr->representation()));
1296 ASSERT(instr->right()->representation().Equals(instr->representation())); 1301 ASSERT(instr->right()->representation().Equals(instr->representation()));
1297 LOperand* dividend = UseRegister(instr->left()); 1302 LOperand* dividend = UseRegister(instr->left());
1298 LOperand* divisor = UseRegister(instr->right()); 1303 LOperand* divisor = UseRegister(instr->right());
1299 LDivI* div = new(zone()) LDivI(dividend, divisor); 1304 LInstruction* result =
1300 return AssignEnvironment(DefineAsRegister(div)); 1305 DefineAsRegister(new(zone()) LDivI(dividend, divisor));
1306 if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1307 instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
1308 (instr->CheckFlag(HValue::kCanOverflow) &&
1309 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) ||
1310 (!instr->IsMathFloorOfDiv() &&
1311 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
1312 result = AssignEnvironment(result);
1313 }
1314 return result;
1301 } 1315 }
1302 1316
1303 1317
1304 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { 1318 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1305 if (instr->representation().IsSmiOrInteger32()) { 1319 if (instr->representation().IsSmiOrInteger32()) {
1306 if (instr->RightIsPowerOf2()) { 1320 if (instr->RightIsPowerOf2()) {
1307 return DoDivByPowerOf2I(instr); 1321 return DoDivByPowerOf2I(instr);
1308 } else if (instr->right()->IsConstant()) { 1322 } else if (instr->right()->IsConstant()) {
1309 return DoDivByConstI(instr); 1323 return DoDivByConstI(instr);
1310 } else { 1324 } else {
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after
1782 // All HForceRepresentation instructions should be eliminated in the 1796 // All HForceRepresentation instructions should be eliminated in the
1783 // representation change phase of Hydrogen. 1797 // representation change phase of Hydrogen.
1784 UNREACHABLE(); 1798 UNREACHABLE();
1785 return NULL; 1799 return NULL;
1786 } 1800 }
1787 1801
1788 1802
1789 LInstruction* LChunkBuilder::DoChange(HChange* instr) { 1803 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1790 Representation from = instr->from(); 1804 Representation from = instr->from();
1791 Representation to = instr->to(); 1805 Representation to = instr->to();
1806 HValue* val = instr->value();
1792 if (from.IsSmi()) { 1807 if (from.IsSmi()) {
1793 if (to.IsTagged()) { 1808 if (to.IsTagged()) {
1794 LOperand* value = UseRegister(instr->value()); 1809 LOperand* value = UseRegister(val);
1795 return DefineSameAsFirst(new(zone()) LDummyUse(value)); 1810 return DefineSameAsFirst(new(zone()) LDummyUse(value));
1796 } 1811 }
1797 from = Representation::Tagged(); 1812 from = Representation::Tagged();
1798 } 1813 }
1799 if (from.IsTagged()) { 1814 if (from.IsTagged()) {
1800 if (to.IsDouble()) { 1815 if (to.IsDouble()) {
1801 LOperand* value = UseRegister(instr->value()); 1816 LOperand* value = UseRegister(val);
1802 LNumberUntagD* res = new(zone()) LNumberUntagD(value); 1817 LInstruction* result = DefineAsRegister(new(zone()) LNumberUntagD(value));
1803 return AssignEnvironment(DefineAsRegister(res)); 1818 if (!val->representation().IsSmi()) result = AssignEnvironment(result);
1819 return result;
1804 } else if (to.IsSmi()) { 1820 } else if (to.IsSmi()) {
1805 HValue* val = instr->value();
1806 LOperand* value = UseRegister(val); 1821 LOperand* value = UseRegister(val);
1807 if (val->type().IsSmi()) { 1822 if (val->type().IsSmi()) {
1808 return DefineSameAsFirst(new(zone()) LDummyUse(value)); 1823 return DefineSameAsFirst(new(zone()) LDummyUse(value));
1809 } 1824 }
1810 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); 1825 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
1811 } else { 1826 } else {
1812 ASSERT(to.IsInteger32()); 1827 ASSERT(to.IsInteger32());
1813 LOperand* value = NULL;
1814 LInstruction* res = NULL;
1815 HValue* val = instr->value();
1816 if (val->type().IsSmi() || val->representation().IsSmi()) { 1828 if (val->type().IsSmi() || val->representation().IsSmi()) {
1817 value = UseRegisterAtStart(val); 1829 LOperand* value = UseRegisterAtStart(val);
1818 res = DefineAsRegister(new(zone()) LSmiUntag(value, false)); 1830 return DefineAsRegister(new(zone()) LSmiUntag(value, false));
1819 } else { 1831 } else {
1820 value = UseRegister(val); 1832 LOperand* value = UseRegister(val);
1821 LOperand* temp1 = TempRegister(); 1833 LOperand* temp1 = TempRegister();
1822 LOperand* temp2 = FixedTemp(f22); 1834 LOperand* temp2 = FixedTemp(f22);
1823 res = DefineSameAsFirst(new(zone()) LTaggedToI(value, 1835 LInstruction* result =
1824 temp1, 1836 DefineSameAsFirst(new(zone()) LTaggedToI(value, temp1, temp2));
1825 temp2)); 1837 if (!val->representation().IsSmi()) {
1826 res = AssignEnvironment(res); 1838 // Note: Only deopts in deferred code.
1839 result = AssignEnvironment(result);
1840 }
1841 return result;
1827 } 1842 }
1828 return res;
1829 } 1843 }
1830 } else if (from.IsDouble()) { 1844 } else if (from.IsDouble()) {
1831 if (to.IsTagged()) { 1845 if (to.IsTagged()) {
1832 info()->MarkAsDeferredCalling(); 1846 info()->MarkAsDeferredCalling();
1833 LOperand* value = UseRegister(instr->value()); 1847 LOperand* value = UseRegister(val);
1834 LOperand* temp1 = TempRegister(); 1848 LOperand* temp1 = TempRegister();
1835 LOperand* temp2 = TempRegister(); 1849 LOperand* temp2 = TempRegister();
1836
1837 // Make sure that the temp and result_temp registers are
1838 // different.
1839 LUnallocated* result_temp = TempRegister(); 1850 LUnallocated* result_temp = TempRegister();
1840 LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2); 1851 LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2);
1841 Define(result, result_temp); 1852 return AssignPointerMap(Define(result, result_temp));
1842 return AssignPointerMap(result);
1843 } else if (to.IsSmi()) { 1853 } else if (to.IsSmi()) {
1844 LOperand* value = UseRegister(instr->value()); 1854 LOperand* value = UseRegister(val);
1845 return AssignEnvironment( 1855 return AssignEnvironment(
1846 DefineAsRegister(new(zone()) LDoubleToSmi(value))); 1856 DefineAsRegister(new(zone()) LDoubleToSmi(value)));
1847 } else { 1857 } else {
1848 ASSERT(to.IsInteger32()); 1858 ASSERT(to.IsInteger32());
1849 LOperand* value = UseRegister(instr->value()); 1859 LOperand* value = UseRegister(val);
1850 LDoubleToI* res = new(zone()) LDoubleToI(value); 1860 LInstruction* result = DefineAsRegister(new(zone()) LDoubleToI(value));
1851 return AssignEnvironment(DefineAsRegister(res)); 1861 if (!instr->CanTruncateToInt32()) result = AssignEnvironment(result);
1862 return result;
1852 } 1863 }
1853 } else if (from.IsInteger32()) { 1864 } else if (from.IsInteger32()) {
1854 info()->MarkAsDeferredCalling(); 1865 info()->MarkAsDeferredCalling();
1855 if (to.IsTagged()) { 1866 if (to.IsTagged()) {
1856 HValue* val = instr->value();
1857 LOperand* value = UseRegisterAtStart(val);
1858 if (!instr->CheckFlag(HValue::kCanOverflow)) { 1867 if (!instr->CheckFlag(HValue::kCanOverflow)) {
1868 LOperand* value = UseRegisterAtStart(val);
1859 return DefineAsRegister(new(zone()) LSmiTag(value)); 1869 return DefineAsRegister(new(zone()) LSmiTag(value));
1860 } else if (val->CheckFlag(HInstruction::kUint32)) { 1870 } else if (val->CheckFlag(HInstruction::kUint32)) {
1871 LOperand* value = UseRegisterAtStart(val);
1861 LOperand* temp1 = TempRegister(); 1872 LOperand* temp1 = TempRegister();
1862 LOperand* temp2 = TempRegister(); 1873 LOperand* temp2 = TempRegister();
1863 LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2); 1874 LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2);
1864 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); 1875 return AssignPointerMap(DefineAsRegister(result));
1865 } else { 1876 } else {
1877 LOperand* value = UseRegisterAtStart(val);
1866 LOperand* temp1 = TempRegister(); 1878 LOperand* temp1 = TempRegister();
1867 LOperand* temp2 = TempRegister(); 1879 LOperand* temp2 = TempRegister();
1868 LNumberTagI* result = new(zone()) LNumberTagI(value, temp1, temp2); 1880 LNumberTagI* result = new(zone()) LNumberTagI(value, temp1, temp2);
1869 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); 1881 return AssignPointerMap(DefineAsRegister(result));
1870 } 1882 }
1871 } else if (to.IsSmi()) { 1883 } else if (to.IsSmi()) {
1872 HValue* val = instr->value();
1873 LOperand* value = UseRegister(val); 1884 LOperand* value = UseRegister(val);
1874 LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value)); 1885 LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value));
1875 if (instr->CheckFlag(HValue::kCanOverflow)) { 1886 if (instr->CheckFlag(HValue::kCanOverflow)) {
1876 result = AssignEnvironment(result); 1887 result = AssignEnvironment(result);
1877 } 1888 }
1878 return result; 1889 return result;
1879 } else { 1890 } else {
1880 ASSERT(to.IsDouble()); 1891 ASSERT(to.IsDouble());
1881 if (instr->value()->CheckFlag(HInstruction::kUint32)) { 1892 if (val->CheckFlag(HInstruction::kUint32)) {
1882 return DefineAsRegister( 1893 return DefineAsRegister(new(zone()) LUint32ToDouble(UseRegister(val)));
1883 new(zone()) LUint32ToDouble(UseRegister(instr->value())));
1884 } else { 1894 } else {
1885 return DefineAsRegister( 1895 return DefineAsRegister(new(zone()) LInteger32ToDouble(Use(val)));
1886 new(zone()) LInteger32ToDouble(Use(instr->value())));
1887 } 1896 }
1888 } 1897 }
1889 } 1898 }
1890 UNREACHABLE(); 1899 UNREACHABLE();
1891 return NULL; 1900 return NULL;
1892 } 1901 }
1893 1902
1894 1903
1895 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) { 1904 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
1896 LOperand* value = UseRegisterAtStart(instr->value()); 1905 LOperand* value = UseRegisterAtStart(instr->value());
(...skipping 21 matching lines...) Expand all
1918 1927
1919 1928
1920 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) { 1929 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
1921 LOperand* value = NULL; 1930 LOperand* value = NULL;
1922 if (!instr->CanOmitMapChecks()) { 1931 if (!instr->CanOmitMapChecks()) {
1923 value = UseRegisterAtStart(instr->value()); 1932 value = UseRegisterAtStart(instr->value());
1924 if (instr->has_migration_target()) info()->MarkAsDeferredCalling(); 1933 if (instr->has_migration_target()) info()->MarkAsDeferredCalling();
1925 } 1934 }
1926 LCheckMaps* result = new(zone()) LCheckMaps(value); 1935 LCheckMaps* result = new(zone()) LCheckMaps(value);
1927 if (!instr->CanOmitMapChecks()) { 1936 if (!instr->CanOmitMapChecks()) {
1937 // Note: Only deopts in deferred code.
1928 AssignEnvironment(result); 1938 AssignEnvironment(result);
1929 if (instr->has_migration_target()) return AssignPointerMap(result); 1939 if (instr->has_migration_target()) return AssignPointerMap(result);
1930 } 1940 }
1931 return result; 1941 return result;
1932 } 1942 }
1933 1943
1934 1944
1935 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { 1945 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
1936 HValue* value = instr->value(); 1946 HValue* value = instr->value();
1937 Representation input_rep = value->representation(); 1947 Representation input_rep = value->representation();
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
2018 return instr->RequiresHoleCheck() 2028 return instr->RequiresHoleCheck()
2019 ? AssignEnvironment(new(zone()) LStoreGlobalCell(value, TempRegister())) 2029 ? AssignEnvironment(new(zone()) LStoreGlobalCell(value, TempRegister()))
2020 : new(zone()) LStoreGlobalCell(value, NULL); 2030 : new(zone()) LStoreGlobalCell(value, NULL);
2021 } 2031 }
2022 2032
2023 2033
2024 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { 2034 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
2025 LOperand* context = UseRegisterAtStart(instr->value()); 2035 LOperand* context = UseRegisterAtStart(instr->value());
2026 LInstruction* result = 2036 LInstruction* result =
2027 DefineAsRegister(new(zone()) LLoadContextSlot(context)); 2037 DefineAsRegister(new(zone()) LLoadContextSlot(context));
2028 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result; 2038 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
2039 result = AssignEnvironment(result);
2040 }
2041 return result;
2029 } 2042 }
2030 2043
2031 2044
2032 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) { 2045 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
2033 LOperand* context; 2046 LOperand* context;
2034 LOperand* value; 2047 LOperand* value;
2035 if (instr->NeedsWriteBarrier()) { 2048 if (instr->NeedsWriteBarrier()) {
2036 context = UseTempRegister(instr->context()); 2049 context = UseTempRegister(instr->context());
2037 value = UseTempRegister(instr->value()); 2050 value = UseTempRegister(instr->value());
2038 } else { 2051 } else {
2039 context = UseRegister(instr->context()); 2052 context = UseRegister(instr->context());
2040 value = UseRegister(instr->value()); 2053 value = UseRegister(instr->value());
2041 } 2054 }
2042 LInstruction* result = new(zone()) LStoreContextSlot(context, value); 2055 LInstruction* result = new(zone()) LStoreContextSlot(context, value);
2043 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result; 2056 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
2057 result = AssignEnvironment(result);
2058 }
2059 return result;
2044 } 2060 }
2045 2061
2046 2062
2047 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { 2063 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
2048 LOperand* obj = UseRegisterAtStart(instr->object()); 2064 LOperand* obj = UseRegisterAtStart(instr->object());
2049 return DefineAsRegister(new(zone()) LLoadNamedField(obj)); 2065 return DefineAsRegister(new(zone()) LLoadNamedField(obj));
2050 } 2066 }
2051 2067
2052 2068
2053 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { 2069 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
(...skipping 14 matching lines...) Expand all
2068 2084
2069 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) { 2085 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) {
2070 return DefineAsRegister(new(zone()) LLoadRoot); 2086 return DefineAsRegister(new(zone()) LLoadRoot);
2071 } 2087 }
2072 2088
2073 2089
2074 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { 2090 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
2075 ASSERT(instr->key()->representation().IsSmiOrInteger32()); 2091 ASSERT(instr->key()->representation().IsSmiOrInteger32());
2076 ElementsKind elements_kind = instr->elements_kind(); 2092 ElementsKind elements_kind = instr->elements_kind();
2077 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); 2093 LOperand* key = UseRegisterOrConstantAtStart(instr->key());
2078 LLoadKeyed* result = NULL; 2094 LInstruction* result = NULL;
2079 2095
2080 if (!instr->is_typed_elements()) { 2096 if (!instr->is_typed_elements()) {
2081 LOperand* obj = NULL; 2097 LOperand* obj = NULL;
2082 if (instr->representation().IsDouble()) { 2098 if (instr->representation().IsDouble()) {
2083 obj = UseRegister(instr->elements()); 2099 obj = UseRegister(instr->elements());
2084 } else { 2100 } else {
2085 ASSERT(instr->representation().IsSmiOrTagged()); 2101 ASSERT(instr->representation().IsSmiOrTagged());
2086 obj = UseRegisterAtStart(instr->elements()); 2102 obj = UseRegisterAtStart(instr->elements());
2087 } 2103 }
2088 result = new(zone()) LLoadKeyed(obj, key); 2104 result = DefineAsRegister(new(zone()) LLoadKeyed(obj, key));
2089 } else { 2105 } else {
2090 ASSERT( 2106 ASSERT(
2091 (instr->representation().IsInteger32() && 2107 (instr->representation().IsInteger32() &&
2092 !IsDoubleOrFloatElementsKind(instr->elements_kind())) || 2108 !IsDoubleOrFloatElementsKind(elements_kind)) ||
2093 (instr->representation().IsDouble() && 2109 (instr->representation().IsDouble() &&
2094 IsDoubleOrFloatElementsKind(instr->elements_kind()))); 2110 IsDoubleOrFloatElementsKind(elements_kind)));
2095 LOperand* backing_store = UseRegister(instr->elements()); 2111 LOperand* backing_store = UseRegister(instr->elements());
2096 result = new(zone()) LLoadKeyed(backing_store, key); 2112 result = DefineAsRegister(new(zone()) LLoadKeyed(backing_store, key));
2097 } 2113 }
2098 2114
2099 DefineAsRegister(result); 2115 if ((instr->is_external() || instr->is_fixed_typed_array()) ?
2100 // An unsigned int array load might overflow and cause a deopt, make sure it 2116 // see LCodeGen::DoLoadKeyedExternalArray
2101 // has an environment. 2117 ((elements_kind == EXTERNAL_UINT32_ELEMENTS ||
2102 bool can_deoptimize = instr->RequiresHoleCheck() || 2118 elements_kind == UINT32_ELEMENTS) &&
2103 elements_kind == EXTERNAL_UINT32_ELEMENTS || 2119 !instr->CheckFlag(HInstruction::kUint32)) :
2104 elements_kind == UINT32_ELEMENTS; 2120 // see LCodeGen::DoLoadKeyedFixedDoubleArray and
2105 return can_deoptimize ? AssignEnvironment(result) : result; 2121 // LCodeGen::DoLoadKeyedFixedArray
2122 instr->RequiresHoleCheck()) {
2123 result = AssignEnvironment(result);
2124 }
2125 return result;
2106 } 2126 }
2107 2127
2108 2128
2109 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { 2129 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
2110 LOperand* context = UseFixed(instr->context(), cp); 2130 LOperand* context = UseFixed(instr->context(), cp);
2111 LOperand* object = UseFixed(instr->object(), a1); 2131 LOperand* object = UseFixed(instr->object(), a1);
2112 LOperand* key = UseFixed(instr->key(), a0); 2132 LOperand* key = UseFixed(instr->key(), a0);
2113 2133
2114 LInstruction* result = 2134 LInstruction* result =
2115 DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key), v0); 2135 DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key), v0);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
2226 val = UseTempRegister(instr->value()); 2246 val = UseTempRegister(instr->value());
2227 } else if (instr->field_representation().IsDouble()) { 2247 } else if (instr->field_representation().IsDouble()) {
2228 val = UseRegisterAtStart(instr->value()); 2248 val = UseRegisterAtStart(instr->value());
2229 } else { 2249 } else {
2230 val = UseRegister(instr->value()); 2250 val = UseRegister(instr->value());
2231 } 2251 }
2232 2252
2233 // We need a temporary register for write barrier of the map field. 2253 // We need a temporary register for write barrier of the map field.
2234 LOperand* temp = needs_write_barrier_for_map ? TempRegister() : NULL; 2254 LOperand* temp = needs_write_barrier_for_map ? TempRegister() : NULL;
2235 2255
2236 LStoreNamedField* result = new(zone()) LStoreNamedField(obj, val, temp); 2256 LInstruction* result = new(zone()) LStoreNamedField(obj, val, temp);
2237 if (instr->field_representation().IsHeapObject()) { 2257 if (!instr->access().IsExternalMemory() &&
2238 if (!instr->value()->type().IsHeapObject()) { 2258 instr->field_representation().IsHeapObject() &&
2239 return AssignEnvironment(result); 2259 !instr->value()->type().IsHeapObject()) {
2240 } 2260 result = AssignEnvironment(result);
2241 } 2261 }
2242 return result; 2262 return result;
2243 } 2263 }
2244 2264
2245 2265
2246 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { 2266 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
2247 LOperand* context = UseFixed(instr->context(), cp); 2267 LOperand* context = UseFixed(instr->context(), cp);
2248 LOperand* obj = UseFixed(instr->object(), a1); 2268 LOperand* obj = UseFixed(instr->object(), a1);
2249 LOperand* val = UseFixed(instr->value(), a0); 2269 LOperand* val = UseFixed(instr->value(), a0);
2250 2270
(...skipping 11 matching lines...) Expand all
2262 instr); 2282 instr);
2263 } 2283 }
2264 2284
2265 2285
2266 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { 2286 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
2267 LOperand* string = UseTempRegister(instr->string()); 2287 LOperand* string = UseTempRegister(instr->string());
2268 LOperand* index = UseTempRegister(instr->index()); 2288 LOperand* index = UseTempRegister(instr->index());
2269 LOperand* context = UseAny(instr->context()); 2289 LOperand* context = UseAny(instr->context());
2270 LStringCharCodeAt* result = 2290 LStringCharCodeAt* result =
2271 new(zone()) LStringCharCodeAt(context, string, index); 2291 new(zone()) LStringCharCodeAt(context, string, index);
2272 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); 2292 return AssignPointerMap(DefineAsRegister(result));
2273 } 2293 }
2274 2294
2275 2295
2276 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) { 2296 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
2277 LOperand* char_code = UseRegister(instr->value()); 2297 LOperand* char_code = UseRegister(instr->value());
2278 LOperand* context = UseAny(instr->context()); 2298 LOperand* context = UseAny(instr->context());
2279 LStringCharFromCode* result = 2299 LStringCharFromCode* result =
2280 new(zone()) LStringCharFromCode(context, char_code); 2300 new(zone()) LStringCharFromCode(context, char_code);
2281 return AssignPointerMap(DefineAsRegister(result)); 2301 return AssignPointerMap(DefineAsRegister(result));
2282 } 2302 }
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
2492 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { 2512 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2493 LOperand* object = UseRegister(instr->object()); 2513 LOperand* object = UseRegister(instr->object());
2494 LOperand* index = UseRegister(instr->index()); 2514 LOperand* index = UseRegister(instr->index());
2495 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index); 2515 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index);
2496 LInstruction* result = DefineSameAsFirst(load); 2516 LInstruction* result = DefineSameAsFirst(load);
2497 return AssignPointerMap(result); 2517 return AssignPointerMap(result);
2498 } 2518 }
2499 2519
2500 2520
2501 } } // namespace v8::internal 2521 } } // namespace v8::internal
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