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

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

Issue 214613004: Only assign environments when they are actually needed. (ARM and ARM64 only) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased. 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 | src/arm64/lithium-arm64.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 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 913 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { 924 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
925 return new(zone()) LGoto(instr->FirstSuccessor()); 925 return new(zone()) LGoto(instr->FirstSuccessor());
926 } 926 }
927 927
928 928
929 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { 929 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
930 LInstruction* goto_instr = CheckElideControlInstruction(instr); 930 LInstruction* goto_instr = CheckElideControlInstruction(instr);
931 if (goto_instr != NULL) return goto_instr; 931 if (goto_instr != NULL) return goto_instr;
932 932
933 HValue* value = instr->value(); 933 HValue* value = instr->value();
934 LBranch* result = new(zone()) LBranch(UseRegister(value)); 934 Representation r = value->representation();
935 // Tagged values that are not known smis or booleans require a
936 // deoptimization environment. If the instruction is generic no
937 // environment is needed since all cases are handled.
938 Representation rep = value->representation();
939 HType type = value->type(); 935 HType type = value->type();
940 ToBooleanStub::Types expected = instr->expected_input_types(); 936 ToBooleanStub::Types expected = instr->expected_input_types();
941 if (rep.IsTagged() && !type.IsSmi() && !type.IsBoolean() && 937 if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic();
942 !expected.IsGeneric()) { 938
943 return AssignEnvironment(result); 939 bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() ||
940 type.IsJSArray() || type.IsHeapNumber() || type.IsString();
941 LInstruction* branch = new(zone()) LBranch(UseRegister(value));
942 if (!easy_case &&
943 ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) ||
944 !expected.IsGeneric())) {
945 branch = AssignEnvironment(branch);
944 } 946 }
945 return result; 947 return branch;
946 } 948 }
947 949
948 950
949 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) { 951 LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) {
950 return new(zone()) LDebugBreak(); 952 return new(zone()) LDebugBreak();
951 } 953 }
952 954
953 955
954 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { 956 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) {
955 LInstruction* goto_instr = CheckElideControlInstruction(instr); 957 LInstruction* goto_instr = CheckElideControlInstruction(instr);
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
1131 return AssignEnvironment(DefineAsRegister(result)); 1133 return AssignEnvironment(DefineAsRegister(result));
1132 } 1134 }
1133 1135
1134 1136
1135 LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) { 1137 LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) {
1136 Representation r = instr->value()->representation(); 1138 Representation r = instr->value()->representation();
1137 LOperand* context = (r.IsDouble() || r.IsSmiOrInteger32()) 1139 LOperand* context = (r.IsDouble() || r.IsSmiOrInteger32())
1138 ? NULL 1140 ? NULL
1139 : UseFixed(instr->context(), cp); 1141 : UseFixed(instr->context(), cp);
1140 LOperand* input = UseRegister(instr->value()); 1142 LOperand* input = UseRegister(instr->value());
1141 LMathAbs* result = new(zone()) LMathAbs(context, input); 1143 LInstruction* result =
1142 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); 1144 DefineAsRegister(new(zone()) LMathAbs(context, input));
1145 if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result);
1146 if (!r.IsDouble()) result = AssignEnvironment(result);
1147 return result;
1143 } 1148 }
1144 1149
1145 1150
1146 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) { 1151 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) {
1147 ASSERT(instr->representation().IsDouble()); 1152 ASSERT(instr->representation().IsDouble());
1148 ASSERT(instr->value()->representation().IsDouble()); 1153 ASSERT(instr->value()->representation().IsDouble());
1149 LOperand* input = UseFixedDouble(instr->value(), d0); 1154 LOperand* input = UseFixedDouble(instr->value(), d0);
1150 return MarkAsCall(DefineFixedDouble(new(zone()) LMathLog(input), d0), instr); 1155 return MarkAsCall(DefineFixedDouble(new(zone()) LMathLog(input), d0), instr);
1151 } 1156 }
1152 1157
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1284 } 1289 }
1285 1290
1286 1291
1287 LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) { 1292 LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) {
1288 ASSERT(instr->representation().IsSmiOrInteger32()); 1293 ASSERT(instr->representation().IsSmiOrInteger32());
1289 ASSERT(instr->left()->representation().Equals(instr->representation())); 1294 ASSERT(instr->left()->representation().Equals(instr->representation()));
1290 ASSERT(instr->right()->representation().Equals(instr->representation())); 1295 ASSERT(instr->right()->representation().Equals(instr->representation()));
1291 LOperand* dividend = UseRegister(instr->left()); 1296 LOperand* dividend = UseRegister(instr->left());
1292 LOperand* divisor = UseRegister(instr->right()); 1297 LOperand* divisor = UseRegister(instr->right());
1293 LOperand* temp = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d4); 1298 LOperand* temp = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d4);
1294 LDivI* div = new(zone()) LDivI(dividend, divisor, temp); 1299 LInstruction* result =
1295 return AssignEnvironment(DefineAsRegister(div)); 1300 DefineAsRegister(new(zone()) LDivI(dividend, divisor, temp));
1301 if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
1302 instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
1303 (instr->CheckFlag(HValue::kCanOverflow) &&
1304 (!CpuFeatures::IsSupported(SUDIV) ||
1305 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) ||
1306 (!instr->IsMathFloorOfDiv() &&
1307 !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
1308 result = AssignEnvironment(result);
1309 }
1310 return result;
1296 } 1311 }
1297 1312
1298 1313
1299 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { 1314 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1300 if (instr->representation().IsSmiOrInteger32()) { 1315 if (instr->representation().IsSmiOrInteger32()) {
1301 if (instr->RightIsPowerOf2()) { 1316 if (instr->RightIsPowerOf2()) {
1302 return DoDivByPowerOf2I(instr); 1317 return DoDivByPowerOf2I(instr);
1303 } else if (instr->right()->IsConstant()) { 1318 } else if (instr->right()->IsConstant()) {
1304 return DoDivByConstI(instr); 1319 return DoDivByConstI(instr);
1305 } else { 1320 } else {
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
1830 // All HForceRepresentation instructions should be eliminated in the 1845 // All HForceRepresentation instructions should be eliminated in the
1831 // representation change phase of Hydrogen. 1846 // representation change phase of Hydrogen.
1832 UNREACHABLE(); 1847 UNREACHABLE();
1833 return NULL; 1848 return NULL;
1834 } 1849 }
1835 1850
1836 1851
1837 LInstruction* LChunkBuilder::DoChange(HChange* instr) { 1852 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1838 Representation from = instr->from(); 1853 Representation from = instr->from();
1839 Representation to = instr->to(); 1854 Representation to = instr->to();
1855 HValue* val = instr->value();
1840 if (from.IsSmi()) { 1856 if (from.IsSmi()) {
1841 if (to.IsTagged()) { 1857 if (to.IsTagged()) {
1842 LOperand* value = UseRegister(instr->value()); 1858 LOperand* value = UseRegister(val);
1843 return DefineSameAsFirst(new(zone()) LDummyUse(value)); 1859 return DefineSameAsFirst(new(zone()) LDummyUse(value));
1844 } 1860 }
1845 from = Representation::Tagged(); 1861 from = Representation::Tagged();
1846 } 1862 }
1847 if (from.IsTagged()) { 1863 if (from.IsTagged()) {
1848 if (to.IsDouble()) { 1864 if (to.IsDouble()) {
1849 LOperand* value = UseRegister(instr->value()); 1865 LOperand* value = UseRegister(val);
1850 LNumberUntagD* res = new(zone()) LNumberUntagD(value); 1866 LInstruction* result = DefineAsRegister(new(zone()) LNumberUntagD(value));
1851 return AssignEnvironment(DefineAsRegister(res)); 1867 if (!val->representation().IsSmi()) result = AssignEnvironment(result);
1868 return result;
1852 } else if (to.IsSmi()) { 1869 } else if (to.IsSmi()) {
1853 HValue* val = instr->value();
1854 LOperand* value = UseRegister(val); 1870 LOperand* value = UseRegister(val);
1855 if (val->type().IsSmi()) { 1871 if (val->type().IsSmi()) {
1856 return DefineSameAsFirst(new(zone()) LDummyUse(value)); 1872 return DefineSameAsFirst(new(zone()) LDummyUse(value));
1857 } 1873 }
1858 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); 1874 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
1859 } else { 1875 } else {
1860 ASSERT(to.IsInteger32()); 1876 ASSERT(to.IsInteger32());
1861 LOperand* value = NULL;
1862 LInstruction* res = NULL;
1863 HValue* val = instr->value();
1864 if (val->type().IsSmi() || val->representation().IsSmi()) { 1877 if (val->type().IsSmi() || val->representation().IsSmi()) {
1865 value = UseRegisterAtStart(val); 1878 LOperand* value = UseRegisterAtStart(val);
1866 res = DefineAsRegister(new(zone()) LSmiUntag(value, false)); 1879 return DefineAsRegister(new(zone()) LSmiUntag(value, false));
1867 } else { 1880 } else {
1868 value = UseRegister(val); 1881 LOperand* value = UseRegister(val);
1869 LOperand* temp1 = TempRegister(); 1882 LOperand* temp1 = TempRegister();
1870 LOperand* temp2 = FixedTemp(d11); 1883 LOperand* temp2 = FixedTemp(d11);
1871 res = DefineSameAsFirst(new(zone()) LTaggedToI(value, 1884 LInstruction* result =
1872 temp1, 1885 DefineSameAsFirst(new(zone()) LTaggedToI(value, temp1, temp2));
1873 temp2)); 1886 if (!val->representation().IsSmi()) {
1874 res = AssignEnvironment(res); 1887 // Note: Only deopts in deferred code.
1888 result = AssignEnvironment(result);
1889 }
1890 return result;
1875 } 1891 }
1876 return res;
1877 } 1892 }
1878 } else if (from.IsDouble()) { 1893 } else if (from.IsDouble()) {
1879 if (to.IsTagged()) { 1894 if (to.IsTagged()) {
1880 info()->MarkAsDeferredCalling(); 1895 info()->MarkAsDeferredCalling();
1881 LOperand* value = UseRegister(instr->value()); 1896 LOperand* value = UseRegister(val);
1882 LOperand* temp1 = TempRegister(); 1897 LOperand* temp1 = TempRegister();
1883 LOperand* temp2 = TempRegister(); 1898 LOperand* temp2 = TempRegister();
1884
1885 // Make sure that the temp and result_temp registers are
1886 // different.
1887 LUnallocated* result_temp = TempRegister(); 1899 LUnallocated* result_temp = TempRegister();
1888 LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2); 1900 LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2);
1889 Define(result, result_temp); 1901 return AssignPointerMap(Define(result, result_temp));
1890 return AssignPointerMap(result);
1891 } else if (to.IsSmi()) { 1902 } else if (to.IsSmi()) {
1892 LOperand* value = UseRegister(instr->value()); 1903 LOperand* value = UseRegister(val);
1893 return AssignEnvironment( 1904 return AssignEnvironment(
1894 DefineAsRegister(new(zone()) LDoubleToSmi(value))); 1905 DefineAsRegister(new(zone()) LDoubleToSmi(value)));
1895 } else { 1906 } else {
1896 ASSERT(to.IsInteger32()); 1907 ASSERT(to.IsInteger32());
1897 LOperand* value = UseRegister(instr->value()); 1908 LOperand* value = UseRegister(val);
1898 LDoubleToI* res = new(zone()) LDoubleToI(value); 1909 LInstruction* result = DefineAsRegister(new(zone()) LDoubleToI(value));
1899 return AssignEnvironment(DefineAsRegister(res)); 1910 if (!instr->CanTruncateToInt32()) result = AssignEnvironment(result);
1911 return result;
1900 } 1912 }
1901 } else if (from.IsInteger32()) { 1913 } else if (from.IsInteger32()) {
1902 info()->MarkAsDeferredCalling(); 1914 info()->MarkAsDeferredCalling();
1903 if (to.IsTagged()) { 1915 if (to.IsTagged()) {
1904 HValue* val = instr->value();
1905 LOperand* value = UseRegisterAtStart(val);
1906 if (!instr->CheckFlag(HValue::kCanOverflow)) { 1916 if (!instr->CheckFlag(HValue::kCanOverflow)) {
1917 LOperand* value = UseRegisterAtStart(val);
1907 return DefineAsRegister(new(zone()) LSmiTag(value)); 1918 return DefineAsRegister(new(zone()) LSmiTag(value));
1908 } else if (val->CheckFlag(HInstruction::kUint32)) { 1919 } else if (val->CheckFlag(HInstruction::kUint32)) {
1920 LOperand* value = UseRegisterAtStart(val);
1909 LOperand* temp1 = TempRegister(); 1921 LOperand* temp1 = TempRegister();
1910 LOperand* temp2 = TempRegister(); 1922 LOperand* temp2 = TempRegister();
1911 LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2); 1923 LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2);
1912 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); 1924 return AssignPointerMap(DefineAsRegister(result));
1913 } else { 1925 } else {
1926 LOperand* value = UseRegisterAtStart(val);
1914 LOperand* temp1 = TempRegister(); 1927 LOperand* temp1 = TempRegister();
1915 LOperand* temp2 = TempRegister(); 1928 LOperand* temp2 = TempRegister();
1916 LNumberTagI* result = new(zone()) LNumberTagI(value, temp1, temp2); 1929 LNumberTagI* result = new(zone()) LNumberTagI(value, temp1, temp2);
1917 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); 1930 return AssignPointerMap(DefineAsRegister(result));
1918 } 1931 }
1919 } else if (to.IsSmi()) { 1932 } else if (to.IsSmi()) {
1920 HValue* val = instr->value();
1921 LOperand* value = UseRegister(val); 1933 LOperand* value = UseRegister(val);
1922 LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value)); 1934 LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value));
1923 if (instr->CheckFlag(HValue::kCanOverflow)) { 1935 if (instr->CheckFlag(HValue::kCanOverflow)) {
1924 result = AssignEnvironment(result); 1936 result = AssignEnvironment(result);
1925 } 1937 }
1926 return result; 1938 return result;
1927 } else { 1939 } else {
1928 ASSERT(to.IsDouble()); 1940 ASSERT(to.IsDouble());
1929 if (instr->value()->CheckFlag(HInstruction::kUint32)) { 1941 if (val->CheckFlag(HInstruction::kUint32)) {
1930 return DefineAsRegister( 1942 return DefineAsRegister(new(zone()) LUint32ToDouble(UseRegister(val)));
1931 new(zone()) LUint32ToDouble(UseRegister(instr->value())));
1932 } else { 1943 } else {
1933 return DefineAsRegister( 1944 return DefineAsRegister(new(zone()) LInteger32ToDouble(Use(val)));
1934 new(zone()) LInteger32ToDouble(Use(instr->value())));
1935 } 1945 }
1936 } 1946 }
1937 } 1947 }
1938 UNREACHABLE(); 1948 UNREACHABLE();
1939 return NULL; 1949 return NULL;
1940 } 1950 }
1941 1951
1942 1952
1943 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) { 1953 LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
1944 LOperand* value = UseRegisterAtStart(instr->value()); 1954 LOperand* value = UseRegisterAtStart(instr->value());
(...skipping 21 matching lines...) Expand all
1966 1976
1967 1977
1968 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) { 1978 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
1969 LOperand* value = NULL; 1979 LOperand* value = NULL;
1970 if (!instr->CanOmitMapChecks()) { 1980 if (!instr->CanOmitMapChecks()) {
1971 value = UseRegisterAtStart(instr->value()); 1981 value = UseRegisterAtStart(instr->value());
1972 if (instr->has_migration_target()) info()->MarkAsDeferredCalling(); 1982 if (instr->has_migration_target()) info()->MarkAsDeferredCalling();
1973 } 1983 }
1974 LCheckMaps* result = new(zone()) LCheckMaps(value); 1984 LCheckMaps* result = new(zone()) LCheckMaps(value);
1975 if (!instr->CanOmitMapChecks()) { 1985 if (!instr->CanOmitMapChecks()) {
1986 // Note: Only deopts in deferred code.
1976 AssignEnvironment(result); 1987 AssignEnvironment(result);
1977 if (instr->has_migration_target()) return AssignPointerMap(result); 1988 if (instr->has_migration_target()) return AssignPointerMap(result);
1978 } 1989 }
1979 return result; 1990 return result;
1980 } 1991 }
1981 1992
1982 1993
1983 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { 1994 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
1984 HValue* value = instr->value(); 1995 HValue* value = instr->value();
1985 Representation input_rep = value->representation(); 1996 Representation input_rep = value->representation();
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
2065 return instr->RequiresHoleCheck() 2076 return instr->RequiresHoleCheck()
2066 ? AssignEnvironment(new(zone()) LStoreGlobalCell(value, TempRegister())) 2077 ? AssignEnvironment(new(zone()) LStoreGlobalCell(value, TempRegister()))
2067 : new(zone()) LStoreGlobalCell(value, NULL); 2078 : new(zone()) LStoreGlobalCell(value, NULL);
2068 } 2079 }
2069 2080
2070 2081
2071 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { 2082 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
2072 LOperand* context = UseRegisterAtStart(instr->value()); 2083 LOperand* context = UseRegisterAtStart(instr->value());
2073 LInstruction* result = 2084 LInstruction* result =
2074 DefineAsRegister(new(zone()) LLoadContextSlot(context)); 2085 DefineAsRegister(new(zone()) LLoadContextSlot(context));
2075 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result; 2086 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
2087 result = AssignEnvironment(result);
2088 }
2089 return result;
2076 } 2090 }
2077 2091
2078 2092
2079 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) { 2093 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
2080 LOperand* context; 2094 LOperand* context;
2081 LOperand* value; 2095 LOperand* value;
2082 if (instr->NeedsWriteBarrier()) { 2096 if (instr->NeedsWriteBarrier()) {
2083 context = UseTempRegister(instr->context()); 2097 context = UseTempRegister(instr->context());
2084 value = UseTempRegister(instr->value()); 2098 value = UseTempRegister(instr->value());
2085 } else { 2099 } else {
2086 context = UseRegister(instr->context()); 2100 context = UseRegister(instr->context());
2087 value = UseRegister(instr->value()); 2101 value = UseRegister(instr->value());
2088 } 2102 }
2089 LInstruction* result = new(zone()) LStoreContextSlot(context, value); 2103 LInstruction* result = new(zone()) LStoreContextSlot(context, value);
2090 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result; 2104 if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
2105 result = AssignEnvironment(result);
2106 }
2107 return result;
2091 } 2108 }
2092 2109
2093 2110
2094 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { 2111 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
2095 LOperand* obj = UseRegisterAtStart(instr->object()); 2112 LOperand* obj = UseRegisterAtStart(instr->object());
2096 return DefineAsRegister(new(zone()) LLoadNamedField(obj)); 2113 return DefineAsRegister(new(zone()) LLoadNamedField(obj));
2097 } 2114 }
2098 2115
2099 2116
2100 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { 2117 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
(...skipping 14 matching lines...) Expand all
2115 2132
2116 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) { 2133 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) {
2117 return DefineAsRegister(new(zone()) LLoadRoot); 2134 return DefineAsRegister(new(zone()) LLoadRoot);
2118 } 2135 }
2119 2136
2120 2137
2121 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { 2138 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
2122 ASSERT(instr->key()->representation().IsSmiOrInteger32()); 2139 ASSERT(instr->key()->representation().IsSmiOrInteger32());
2123 ElementsKind elements_kind = instr->elements_kind(); 2140 ElementsKind elements_kind = instr->elements_kind();
2124 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); 2141 LOperand* key = UseRegisterOrConstantAtStart(instr->key());
2125 LLoadKeyed* result = NULL; 2142 LInstruction* result = NULL;
2126 2143
2127 if (!instr->is_typed_elements()) { 2144 if (!instr->is_typed_elements()) {
2128 LOperand* obj = NULL; 2145 LOperand* obj = NULL;
2129 if (instr->representation().IsDouble()) { 2146 if (instr->representation().IsDouble()) {
2130 obj = UseRegister(instr->elements()); 2147 obj = UseRegister(instr->elements());
2131 } else { 2148 } else {
2132 ASSERT(instr->representation().IsSmiOrTagged()); 2149 ASSERT(instr->representation().IsSmiOrTagged());
2133 obj = UseRegisterAtStart(instr->elements()); 2150 obj = UseRegisterAtStart(instr->elements());
2134 } 2151 }
2135 result = new(zone()) LLoadKeyed(obj, key); 2152 result = DefineAsRegister(new(zone()) LLoadKeyed(obj, key));
2136 } else { 2153 } else {
2137 ASSERT( 2154 ASSERT(
2138 (instr->representation().IsInteger32() && 2155 (instr->representation().IsInteger32() &&
2139 !IsDoubleOrFloatElementsKind(instr->elements_kind())) || 2156 !IsDoubleOrFloatElementsKind(elements_kind)) ||
2140 (instr->representation().IsDouble() && 2157 (instr->representation().IsDouble() &&
2141 IsDoubleOrFloatElementsKind(instr->elements_kind()))); 2158 IsDoubleOrFloatElementsKind(elements_kind)));
2142 LOperand* backing_store = UseRegister(instr->elements()); 2159 LOperand* backing_store = UseRegister(instr->elements());
2143 result = new(zone()) LLoadKeyed(backing_store, key); 2160 result = DefineAsRegister(new(zone()) LLoadKeyed(backing_store, key));
2144 } 2161 }
2145 2162
2146 DefineAsRegister(result); 2163 if ((instr->is_external() || instr->is_fixed_typed_array()) ?
2147 // An unsigned int array load might overflow and cause a deopt, make sure it 2164 // see LCodeGen::DoLoadKeyedExternalArray
2148 // has an environment. 2165 ((elements_kind == EXTERNAL_UINT32_ELEMENTS ||
2149 bool can_deoptimize = instr->RequiresHoleCheck() || 2166 elements_kind == UINT32_ELEMENTS) &&
2150 elements_kind == EXTERNAL_UINT32_ELEMENTS || 2167 !instr->CheckFlag(HInstruction::kUint32)) :
2151 elements_kind == UINT32_ELEMENTS; 2168 // see LCodeGen::DoLoadKeyedFixedDoubleArray and
2152 return can_deoptimize ? AssignEnvironment(result) : result; 2169 // LCodeGen::DoLoadKeyedFixedArray
2170 instr->RequiresHoleCheck()) {
2171 result = AssignEnvironment(result);
2172 }
2173 return result;
2153 } 2174 }
2154 2175
2155 2176
2156 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { 2177 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
2157 LOperand* context = UseFixed(instr->context(), cp); 2178 LOperand* context = UseFixed(instr->context(), cp);
2158 LOperand* object = UseFixed(instr->object(), r1); 2179 LOperand* object = UseFixed(instr->object(), r1);
2159 LOperand* key = UseFixed(instr->key(), r0); 2180 LOperand* key = UseFixed(instr->key(), r0);
2160 2181
2161 LInstruction* result = 2182 LInstruction* result =
2162 DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key), r0); 2183 DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key), r0);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
2273 val = UseTempRegister(instr->value()); 2294 val = UseTempRegister(instr->value());
2274 } else if (instr->field_representation().IsDouble()) { 2295 } else if (instr->field_representation().IsDouble()) {
2275 val = UseRegisterAtStart(instr->value()); 2296 val = UseRegisterAtStart(instr->value());
2276 } else { 2297 } else {
2277 val = UseRegister(instr->value()); 2298 val = UseRegister(instr->value());
2278 } 2299 }
2279 2300
2280 // We need a temporary register for write barrier of the map field. 2301 // We need a temporary register for write barrier of the map field.
2281 LOperand* temp = needs_write_barrier_for_map ? TempRegister() : NULL; 2302 LOperand* temp = needs_write_barrier_for_map ? TempRegister() : NULL;
2282 2303
2283 LStoreNamedField* result = new(zone()) LStoreNamedField(obj, val, temp); 2304 LInstruction* result = new(zone()) LStoreNamedField(obj, val, temp);
2284 if (instr->field_representation().IsHeapObject()) { 2305 if (!instr->access().IsExternalMemory() &&
2285 if (!instr->value()->type().IsHeapObject()) { 2306 instr->field_representation().IsHeapObject() &&
2286 return AssignEnvironment(result); 2307 !instr->value()->type().IsHeapObject()) {
2287 } 2308 result = AssignEnvironment(result);
2288 } 2309 }
2289 return result; 2310 return result;
2290 } 2311 }
2291 2312
2292 2313
2293 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { 2314 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
2294 LOperand* context = UseFixed(instr->context(), cp); 2315 LOperand* context = UseFixed(instr->context(), cp);
2295 LOperand* obj = UseFixed(instr->object(), r1); 2316 LOperand* obj = UseFixed(instr->object(), r1);
2296 LOperand* val = UseFixed(instr->value(), r0); 2317 LOperand* val = UseFixed(instr->value(), r0);
2297 2318
(...skipping 11 matching lines...) Expand all
2309 instr); 2330 instr);
2310 } 2331 }
2311 2332
2312 2333
2313 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { 2334 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
2314 LOperand* string = UseTempRegister(instr->string()); 2335 LOperand* string = UseTempRegister(instr->string());
2315 LOperand* index = UseTempRegister(instr->index()); 2336 LOperand* index = UseTempRegister(instr->index());
2316 LOperand* context = UseAny(instr->context()); 2337 LOperand* context = UseAny(instr->context());
2317 LStringCharCodeAt* result = 2338 LStringCharCodeAt* result =
2318 new(zone()) LStringCharCodeAt(context, string, index); 2339 new(zone()) LStringCharCodeAt(context, string, index);
2319 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); 2340 return AssignPointerMap(DefineAsRegister(result));
2320 } 2341 }
2321 2342
2322 2343
2323 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) { 2344 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
2324 LOperand* char_code = UseRegister(instr->value()); 2345 LOperand* char_code = UseRegister(instr->value());
2325 LOperand* context = UseAny(instr->context()); 2346 LOperand* context = UseAny(instr->context());
2326 LStringCharFromCode* result = 2347 LStringCharFromCode* result =
2327 new(zone()) LStringCharFromCode(context, char_code); 2348 new(zone()) LStringCharFromCode(context, char_code);
2328 return AssignPointerMap(DefineAsRegister(result)); 2349 return AssignPointerMap(DefineAsRegister(result));
2329 } 2350 }
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
2538 2559
2539 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { 2560 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2540 LOperand* object = UseRegister(instr->object()); 2561 LOperand* object = UseRegister(instr->object());
2541 LOperand* index = UseRegister(instr->index()); 2562 LOperand* index = UseRegister(instr->index());
2542 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index); 2563 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index);
2543 LInstruction* result = DefineSameAsFirst(load); 2564 LInstruction* result = DefineSameAsFirst(load);
2544 return AssignPointerMap(result); 2565 return AssignPointerMap(result);
2545 } 2566 }
2546 2567
2547 } } // namespace v8::internal 2568 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/arm64/lithium-arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698