| OLD | NEW |
| 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 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 850 | 850 |
| 851 void LChunkBuilder::VisitInstruction(HInstruction* current) { | 851 void LChunkBuilder::VisitInstruction(HInstruction* current) { |
| 852 HInstruction* old_current = current_instruction_; | 852 HInstruction* old_current = current_instruction_; |
| 853 current_instruction_ = current; | 853 current_instruction_ = current; |
| 854 | 854 |
| 855 LInstruction* instr = NULL; | 855 LInstruction* instr = NULL; |
| 856 if (current->CanReplaceWithDummyUses()) { | 856 if (current->CanReplaceWithDummyUses()) { |
| 857 if (current->OperandCount() == 0) { | 857 if (current->OperandCount() == 0) { |
| 858 instr = DefineAsRegister(new(zone()) LDummy()); | 858 instr = DefineAsRegister(new(zone()) LDummy()); |
| 859 } else { | 859 } else { |
| 860 ASSERT(!current->OperandAt(0)->IsControlInstruction()); |
| 860 instr = DefineAsRegister(new(zone()) | 861 instr = DefineAsRegister(new(zone()) |
| 861 LDummyUse(UseAny(current->OperandAt(0)))); | 862 LDummyUse(UseAny(current->OperandAt(0)))); |
| 862 } | 863 } |
| 863 for (int i = 1; i < current->OperandCount(); ++i) { | 864 for (int i = 1; i < current->OperandCount(); ++i) { |
| 865 if (current->OperandAt(i)->IsControlInstruction()) continue; |
| 864 LInstruction* dummy = | 866 LInstruction* dummy = |
| 865 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); | 867 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); |
| 866 dummy->set_hydrogen_value(current); | 868 dummy->set_hydrogen_value(current); |
| 867 chunk_->AddInstruction(dummy, current_block_); | 869 chunk_->AddInstruction(dummy, current_block_); |
| 868 } | 870 } |
| 869 } else { | 871 } else { |
| 870 instr = current->CompileToLithium(this); | 872 instr = current->CompileToLithium(this); |
| 871 } | 873 } |
| 872 | 874 |
| 873 argument_count_ += current->argument_delta(); | 875 argument_count_ += current->argument_delta(); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 943 HType type = value->type(); | 945 HType type = value->type(); |
| 944 if (rep.IsTagged() && !type.IsSmi() && !type.IsBoolean() && | 946 if (rep.IsTagged() && !type.IsSmi() && !type.IsBoolean() && |
| 945 !expected.IsGeneric()) { | 947 !expected.IsGeneric()) { |
| 946 return AssignEnvironment(result); | 948 return AssignEnvironment(result); |
| 947 } | 949 } |
| 948 return result; | 950 return result; |
| 949 } | 951 } |
| 950 | 952 |
| 951 | 953 |
| 952 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { | 954 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { |
| 955 LInstruction* goto_instr = CheckElideControlInstruction(instr); |
| 956 if (goto_instr != NULL) return goto_instr; |
| 957 |
| 953 ASSERT(instr->value()->representation().IsTagged()); | 958 ASSERT(instr->value()->representation().IsTagged()); |
| 954 LOperand* value = UseRegisterAtStart(instr->value()); | 959 LOperand* value = UseRegisterAtStart(instr->value()); |
| 955 return new(zone()) LCmpMapAndBranch(value); | 960 return new(zone()) LCmpMapAndBranch(value); |
| 956 } | 961 } |
| 957 | 962 |
| 958 | 963 |
| 959 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { | 964 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { |
| 960 info()->MarkAsRequiresFrame(); | 965 info()->MarkAsRequiresFrame(); |
| 961 return DefineAsRegister(new(zone()) LArgumentsLength(Use(length->value()))); | 966 return DefineAsRegister(new(zone()) LArgumentsLength(Use(length->value()))); |
| 962 } | 967 } |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1042 if (instr->HasNoUses()) return NULL; | 1047 if (instr->HasNoUses()) return NULL; |
| 1043 | 1048 |
| 1044 if (info()->IsStub()) { | 1049 if (info()->IsStub()) { |
| 1045 return DefineFixed(new(zone()) LContext, rsi); | 1050 return DefineFixed(new(zone()) LContext, rsi); |
| 1046 } | 1051 } |
| 1047 | 1052 |
| 1048 return DefineAsRegister(new(zone()) LContext); | 1053 return DefineAsRegister(new(zone()) LContext); |
| 1049 } | 1054 } |
| 1050 | 1055 |
| 1051 | 1056 |
| 1052 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { | |
| 1053 LOperand* context = UseRegisterAtStart(instr->value()); | |
| 1054 return DefineAsRegister(new(zone()) LOuterContext(context)); | |
| 1055 } | |
| 1056 | |
| 1057 | |
| 1058 LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) { | 1057 LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) { |
| 1059 LOperand* context = UseFixed(instr->context(), rsi); | 1058 LOperand* context = UseFixed(instr->context(), rsi); |
| 1060 return MarkAsCall(new(zone()) LDeclareGlobals(context), instr); | 1059 return MarkAsCall(new(zone()) LDeclareGlobals(context), instr); |
| 1061 } | 1060 } |
| 1062 | 1061 |
| 1063 | 1062 |
| 1064 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { | |
| 1065 LOperand* context = UseRegisterAtStart(instr->value()); | |
| 1066 return DefineAsRegister(new(zone()) LGlobalObject(context)); | |
| 1067 } | |
| 1068 | |
| 1069 | |
| 1070 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { | |
| 1071 LOperand* global_object = UseRegisterAtStart(instr->value()); | |
| 1072 return DefineAsRegister(new(zone()) LGlobalReceiver(global_object)); | |
| 1073 } | |
| 1074 | |
| 1075 | |
| 1076 LInstruction* LChunkBuilder::DoCallJSFunction( | 1063 LInstruction* LChunkBuilder::DoCallJSFunction( |
| 1077 HCallJSFunction* instr) { | 1064 HCallJSFunction* instr) { |
| 1078 LOperand* function = UseFixed(instr->function(), rdi); | 1065 LOperand* function = UseFixed(instr->function(), rdi); |
| 1079 | 1066 |
| 1080 LCallJSFunction* result = new(zone()) LCallJSFunction(function); | 1067 LCallJSFunction* result = new(zone()) LCallJSFunction(function); |
| 1081 | 1068 |
| 1082 return MarkAsCall(DefineFixed(result, rax), instr); | 1069 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1083 } | 1070 } |
| 1084 | 1071 |
| 1085 | 1072 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1112 | 1099 |
| 1113 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { | 1100 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { |
| 1114 switch (instr->op()) { | 1101 switch (instr->op()) { |
| 1115 case kMathFloor: return DoMathFloor(instr); | 1102 case kMathFloor: return DoMathFloor(instr); |
| 1116 case kMathRound: return DoMathRound(instr); | 1103 case kMathRound: return DoMathRound(instr); |
| 1117 case kMathAbs: return DoMathAbs(instr); | 1104 case kMathAbs: return DoMathAbs(instr); |
| 1118 case kMathLog: return DoMathLog(instr); | 1105 case kMathLog: return DoMathLog(instr); |
| 1119 case kMathExp: return DoMathExp(instr); | 1106 case kMathExp: return DoMathExp(instr); |
| 1120 case kMathSqrt: return DoMathSqrt(instr); | 1107 case kMathSqrt: return DoMathSqrt(instr); |
| 1121 case kMathPowHalf: return DoMathPowHalf(instr); | 1108 case kMathPowHalf: return DoMathPowHalf(instr); |
| 1109 case kMathClz32: return DoMathClz32(instr); |
| 1122 default: | 1110 default: |
| 1123 UNREACHABLE(); | 1111 UNREACHABLE(); |
| 1124 return NULL; | 1112 return NULL; |
| 1125 } | 1113 } |
| 1126 } | 1114 } |
| 1127 | 1115 |
| 1128 | 1116 |
| 1129 LInstruction* LChunkBuilder::DoMathFloor(HUnaryMathOperation* instr) { | 1117 LInstruction* LChunkBuilder::DoMathFloor(HUnaryMathOperation* instr) { |
| 1130 LOperand* input = UseRegisterAtStart(instr->value()); | 1118 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1131 LMathFloor* result = new(zone()) LMathFloor(input); | 1119 LMathFloor* result = new(zone()) LMathFloor(input); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1149 | 1137 |
| 1150 | 1138 |
| 1151 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) { | 1139 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) { |
| 1152 ASSERT(instr->representation().IsDouble()); | 1140 ASSERT(instr->representation().IsDouble()); |
| 1153 ASSERT(instr->value()->representation().IsDouble()); | 1141 ASSERT(instr->value()->representation().IsDouble()); |
| 1154 LOperand* input = UseRegisterAtStart(instr->value()); | 1142 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1155 return MarkAsCall(DefineSameAsFirst(new(zone()) LMathLog(input)), instr); | 1143 return MarkAsCall(DefineSameAsFirst(new(zone()) LMathLog(input)), instr); |
| 1156 } | 1144 } |
| 1157 | 1145 |
| 1158 | 1146 |
| 1147 LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) { |
| 1148 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1149 LMathClz32* result = new(zone()) LMathClz32(input); |
| 1150 return DefineAsRegister(result); |
| 1151 } |
| 1152 |
| 1153 |
| 1159 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) { | 1154 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) { |
| 1160 ASSERT(instr->representation().IsDouble()); | 1155 ASSERT(instr->representation().IsDouble()); |
| 1161 ASSERT(instr->value()->representation().IsDouble()); | 1156 ASSERT(instr->value()->representation().IsDouble()); |
| 1162 LOperand* value = UseTempRegister(instr->value()); | 1157 LOperand* value = UseTempRegister(instr->value()); |
| 1163 LOperand* temp1 = TempRegister(); | 1158 LOperand* temp1 = TempRegister(); |
| 1164 LOperand* temp2 = TempRegister(); | 1159 LOperand* temp2 = TempRegister(); |
| 1165 LMathExp* result = new(zone()) LMathExp(value, temp1, temp2); | 1160 LMathExp* result = new(zone()) LMathExp(value, temp1, temp2); |
| 1166 return DefineAsRegister(result); | 1161 return DefineAsRegister(result); |
| 1167 } | 1162 } |
| 1168 | 1163 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1194 LOperand* constructor = UseFixed(instr->constructor(), rdi); | 1189 LOperand* constructor = UseFixed(instr->constructor(), rdi); |
| 1195 LCallNewArray* result = new(zone()) LCallNewArray(context, constructor); | 1190 LCallNewArray* result = new(zone()) LCallNewArray(context, constructor); |
| 1196 return MarkAsCall(DefineFixed(result, rax), instr); | 1191 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1197 } | 1192 } |
| 1198 | 1193 |
| 1199 | 1194 |
| 1200 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { | 1195 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { |
| 1201 LOperand* context = UseFixed(instr->context(), rsi); | 1196 LOperand* context = UseFixed(instr->context(), rsi); |
| 1202 LOperand* function = UseFixed(instr->function(), rdi); | 1197 LOperand* function = UseFixed(instr->function(), rdi); |
| 1203 LCallFunction* call = new(zone()) LCallFunction(context, function); | 1198 LCallFunction* call = new(zone()) LCallFunction(context, function); |
| 1204 LInstruction* result = DefineFixed(call, rax); | 1199 return MarkAsCall(DefineFixed(call, rax), instr); |
| 1205 if (instr->IsTailCall()) return result; | |
| 1206 return MarkAsCall(result, instr); | |
| 1207 } | 1200 } |
| 1208 | 1201 |
| 1209 | 1202 |
| 1210 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { | 1203 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { |
| 1211 LOperand* context = UseFixed(instr->context(), rsi); | 1204 LOperand* context = UseFixed(instr->context(), rsi); |
| 1212 LCallRuntime* result = new(zone()) LCallRuntime(context); | 1205 LCallRuntime* result = new(zone()) LCallRuntime(context); |
| 1213 return MarkAsCall(DefineFixed(result, rax), instr); | 1206 return MarkAsCall(DefineFixed(result, rax), instr); |
| 1214 } | 1207 } |
| 1215 | 1208 |
| 1216 | 1209 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1246 } else { | 1239 } else { |
| 1247 return DoArithmeticT(instr->op(), instr); | 1240 return DoArithmeticT(instr->op(), instr); |
| 1248 } | 1241 } |
| 1249 } | 1242 } |
| 1250 | 1243 |
| 1251 | 1244 |
| 1252 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { | 1245 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { |
| 1253 if (instr->representation().IsSmiOrInteger32()) { | 1246 if (instr->representation().IsSmiOrInteger32()) { |
| 1254 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1247 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1255 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1248 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 1256 if (instr->HasPowerOf2Divisor()) { | 1249 if (instr->RightIsPowerOf2()) { |
| 1257 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); | 1250 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); |
| 1258 LOperand* value = UseRegisterAtStart(instr->left()); | 1251 LOperand* value = UseRegister(instr->left()); |
| 1259 LDivI* div = | 1252 LDivI* div = |
| 1260 new(zone()) LDivI(value, UseOrConstant(instr->right()), NULL); | 1253 new(zone()) LDivI(value, UseOrConstant(instr->right()), NULL); |
| 1261 return AssignEnvironment(DefineSameAsFirst(div)); | 1254 return AssignEnvironment(DefineAsRegister(div)); |
| 1262 } | 1255 } |
| 1263 // The temporary operand is necessary to ensure that right is not allocated | 1256 // The temporary operand is necessary to ensure that right is not allocated |
| 1264 // into rdx. | 1257 // into rdx. |
| 1265 LOperand* temp = FixedTemp(rdx); | 1258 LOperand* temp = FixedTemp(rdx); |
| 1266 LOperand* dividend = UseFixed(instr->left(), rax); | 1259 LOperand* dividend = UseFixed(instr->left(), rax); |
| 1267 LOperand* divisor = UseRegister(instr->right()); | 1260 LOperand* divisor = UseRegister(instr->right()); |
| 1268 LDivI* result = new(zone()) LDivI(dividend, divisor, temp); | 1261 LDivI* result = new(zone()) LDivI(dividend, divisor, temp); |
| 1269 return AssignEnvironment(DefineFixed(result, rax)); | 1262 return AssignEnvironment(DefineFixed(result, rax)); |
| 1270 } else if (instr->representation().IsDouble()) { | 1263 } else if (instr->representation().IsDouble()) { |
| 1271 return DoArithmeticD(Token::DIV, instr); | 1264 return DoArithmeticD(Token::DIV, instr); |
| 1272 } else { | 1265 } else { |
| 1273 return DoArithmeticT(Token::DIV, instr); | 1266 return DoArithmeticT(Token::DIV, instr); |
| 1274 } | 1267 } |
| 1275 } | 1268 } |
| 1276 | 1269 |
| 1277 | 1270 |
| 1278 HValue* LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(HValue* divisor) { | |
| 1279 if (divisor->IsConstant() && | |
| 1280 HConstant::cast(divisor)->HasInteger32Value()) { | |
| 1281 HConstant* constant_val = HConstant::cast(divisor); | |
| 1282 return constant_val->CopyToRepresentation(Representation::Integer32(), | |
| 1283 divisor->block()->zone()); | |
| 1284 } | |
| 1285 // A value with an integer representation does not need to be transformed. | |
| 1286 if (divisor->representation().IsInteger32()) { | |
| 1287 return divisor; | |
| 1288 // A change from an integer32 can be replaced by the integer32 value. | |
| 1289 } else if (divisor->IsChange() && | |
| 1290 HChange::cast(divisor)->from().IsInteger32()) { | |
| 1291 return HChange::cast(divisor)->value(); | |
| 1292 } | |
| 1293 return NULL; | |
| 1294 } | |
| 1295 | |
| 1296 | |
| 1297 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { | 1271 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { |
| 1298 HValue* right = instr->right(); | 1272 HValue* right = instr->right(); |
| 1299 if (!right->IsConstant()) { | 1273 if (!right->IsConstant()) { |
| 1300 ASSERT(right->representation().IsInteger32()); | 1274 ASSERT(right->representation().IsInteger32()); |
| 1301 // The temporary operand is necessary to ensure that right is not allocated | 1275 // The temporary operand is necessary to ensure that right is not allocated |
| 1302 // into rdx. | 1276 // into rdx. |
| 1303 LOperand* temp = FixedTemp(rdx); | 1277 LOperand* temp = FixedTemp(rdx); |
| 1304 LOperand* dividend = UseFixed(instr->left(), rax); | 1278 LOperand* dividend = UseFixed(instr->left(), rax); |
| 1305 LOperand* divisor = UseRegister(instr->right()); | 1279 LOperand* divisor = UseRegister(instr->right()); |
| 1306 LDivI* flooring_div = new(zone()) LDivI(dividend, divisor, temp); | 1280 LDivI* flooring_div = new(zone()) LDivI(dividend, divisor, temp); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1329 } | 1303 } |
| 1330 } | 1304 } |
| 1331 | 1305 |
| 1332 | 1306 |
| 1333 LInstruction* LChunkBuilder::DoMod(HMod* instr) { | 1307 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
| 1334 HValue* left = instr->left(); | 1308 HValue* left = instr->left(); |
| 1335 HValue* right = instr->right(); | 1309 HValue* right = instr->right(); |
| 1336 if (instr->representation().IsSmiOrInteger32()) { | 1310 if (instr->representation().IsSmiOrInteger32()) { |
| 1337 ASSERT(left->representation().Equals(instr->representation())); | 1311 ASSERT(left->representation().Equals(instr->representation())); |
| 1338 ASSERT(right->representation().Equals(instr->representation())); | 1312 ASSERT(right->representation().Equals(instr->representation())); |
| 1339 if (instr->HasPowerOf2Divisor()) { | 1313 if (instr->RightIsPowerOf2()) { |
| 1340 ASSERT(!right->CanBeZero()); | 1314 ASSERT(!right->CanBeZero()); |
| 1341 LModI* mod = new(zone()) LModI(UseRegisterAtStart(left), | 1315 LModI* mod = new(zone()) LModI(UseRegisterAtStart(left), |
| 1342 UseOrConstant(right), | 1316 UseOrConstant(right), |
| 1343 NULL); | 1317 NULL); |
| 1344 LInstruction* result = DefineSameAsFirst(mod); | 1318 LInstruction* result = DefineSameAsFirst(mod); |
| 1345 return (left->CanBeNegative() && | 1319 return (left->CanBeNegative() && |
| 1346 instr->CheckFlag(HValue::kBailoutOnMinusZero)) | 1320 instr->CheckFlag(HValue::kBailoutOnMinusZero)) |
| 1347 ? AssignEnvironment(result) | 1321 ? AssignEnvironment(result) |
| 1348 : result; | 1322 : result; |
| 1349 } else { | 1323 } else { |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1634 TempRegister()); | 1608 TempRegister()); |
| 1635 } | 1609 } |
| 1636 | 1610 |
| 1637 | 1611 |
| 1638 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { | 1612 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { |
| 1639 LOperand* map = UseRegisterAtStart(instr->value()); | 1613 LOperand* map = UseRegisterAtStart(instr->value()); |
| 1640 return DefineAsRegister(new(zone()) LMapEnumLength(map)); | 1614 return DefineAsRegister(new(zone()) LMapEnumLength(map)); |
| 1641 } | 1615 } |
| 1642 | 1616 |
| 1643 | 1617 |
| 1644 LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) { | |
| 1645 LOperand* object = UseRegisterAtStart(instr->value()); | |
| 1646 return DefineAsRegister(new(zone()) LElementsKind(object)); | |
| 1647 } | |
| 1648 | |
| 1649 | |
| 1650 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { | |
| 1651 LOperand* object = UseRegister(instr->value()); | |
| 1652 LValueOf* result = new(zone()) LValueOf(object); | |
| 1653 return DefineSameAsFirst(result); | |
| 1654 } | |
| 1655 | |
| 1656 | |
| 1657 LInstruction* LChunkBuilder::DoDateField(HDateField* instr) { | 1618 LInstruction* LChunkBuilder::DoDateField(HDateField* instr) { |
| 1658 LOperand* object = UseFixed(instr->value(), rax); | 1619 LOperand* object = UseFixed(instr->value(), rax); |
| 1659 LDateField* result = new(zone()) LDateField(object, instr->index()); | 1620 LDateField* result = new(zone()) LDateField(object, instr->index()); |
| 1660 return MarkAsCall(DefineFixed(result, rax), instr, CAN_DEOPTIMIZE_EAGERLY); | 1621 return MarkAsCall(DefineFixed(result, rax), instr, CAN_DEOPTIMIZE_EAGERLY); |
| 1661 } | 1622 } |
| 1662 | 1623 |
| 1663 | 1624 |
| 1664 LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) { | 1625 LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) { |
| 1665 LOperand* string = UseRegisterAtStart(instr->string()); | 1626 LOperand* string = UseRegisterAtStart(instr->string()); |
| 1666 LOperand* index = UseRegisterOrConstantAtStart(instr->index()); | 1627 LOperand* index = UseRegisterOrConstantAtStart(instr->index()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1700 } | 1661 } |
| 1701 | 1662 |
| 1702 | 1663 |
| 1703 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { | 1664 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { |
| 1704 // The control instruction marking the end of a block that completed | 1665 // The control instruction marking the end of a block that completed |
| 1705 // abruptly (e.g., threw an exception). There is nothing specific to do. | 1666 // abruptly (e.g., threw an exception). There is nothing specific to do. |
| 1706 return NULL; | 1667 return NULL; |
| 1707 } | 1668 } |
| 1708 | 1669 |
| 1709 | 1670 |
| 1710 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { | |
| 1711 LOperand* context = UseFixed(instr->context(), rsi); | |
| 1712 LOperand* value = UseFixed(instr->value(), rax); | |
| 1713 return MarkAsCall(new(zone()) LThrow(context, value), instr); | |
| 1714 } | |
| 1715 | |
| 1716 | |
| 1717 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) { | 1671 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) { |
| 1718 return NULL; | 1672 return NULL; |
| 1719 } | 1673 } |
| 1720 | 1674 |
| 1721 | 1675 |
| 1722 LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) { | 1676 LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) { |
| 1723 // All HForceRepresentation instructions should be eliminated in the | 1677 // All HForceRepresentation instructions should be eliminated in the |
| 1724 // representation change phase of Hydrogen. | 1678 // representation change phase of Hydrogen. |
| 1725 UNREACHABLE(); | 1679 UNREACHABLE(); |
| 1726 return NULL; | 1680 return NULL; |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2003 return AssignEnvironment(DefineAsRegister( | 1957 return AssignEnvironment(DefineAsRegister( |
| 2004 new(zone()) LLoadFunctionPrototype(UseRegister(instr->function())))); | 1958 new(zone()) LLoadFunctionPrototype(UseRegister(instr->function())))); |
| 2005 } | 1959 } |
| 2006 | 1960 |
| 2007 | 1961 |
| 2008 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) { | 1962 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) { |
| 2009 return DefineAsRegister(new(zone()) LLoadRoot); | 1963 return DefineAsRegister(new(zone()) LLoadRoot); |
| 2010 } | 1964 } |
| 2011 | 1965 |
| 2012 | 1966 |
| 2013 LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( | |
| 2014 HLoadExternalArrayPointer* instr) { | |
| 2015 LOperand* input = UseRegisterAtStart(instr->value()); | |
| 2016 return DefineAsRegister(new(zone()) LLoadExternalArrayPointer(input)); | |
| 2017 } | |
| 2018 | |
| 2019 | |
| 2020 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { | 1967 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { |
| 2021 ASSERT(instr->key()->representation().IsInteger32()); | 1968 ASSERT(instr->key()->representation().IsInteger32()); |
| 2022 ElementsKind elements_kind = instr->elements_kind(); | 1969 ElementsKind elements_kind = instr->elements_kind(); |
| 2023 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); | 1970 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); |
| 2024 LLoadKeyed* result = NULL; | 1971 LLoadKeyed* result = NULL; |
| 2025 | 1972 |
| 2026 if (!instr->is_typed_elements()) { | 1973 if (!instr->is_typed_elements()) { |
| 2027 LOperand* obj = UseRegisterAtStart(instr->elements()); | 1974 LOperand* obj = UseRegisterAtStart(instr->elements()); |
| 2028 result = new(zone()) LLoadKeyed(obj, key); | 1975 result = new(zone()) LLoadKeyed(obj, key); |
| 2029 } else { | 1976 } else { |
| 2030 ASSERT( | 1977 ASSERT( |
| 2031 (instr->representation().IsInteger32() && | 1978 (instr->representation().IsInteger32() && |
| 2032 !(IsDoubleOrFloatElementsKind(instr->elements_kind()))) || | 1979 !(IsDoubleOrFloatElementsKind(instr->elements_kind()))) || |
| 2033 (instr->representation().IsDouble() && | 1980 (instr->representation().IsDouble() && |
| 2034 (IsDoubleOrFloatElementsKind(instr->elements_kind())))); | 1981 (IsDoubleOrFloatElementsKind(instr->elements_kind())))); |
| 2035 LOperand* backing_store = UseRegister(instr->elements()); | 1982 LOperand* backing_store = UseRegister(instr->elements()); |
| 2036 result = new(zone()) LLoadKeyed(backing_store, key); | 1983 result = new(zone()) LLoadKeyed(backing_store, key); |
| 2037 } | 1984 } |
| 2038 | 1985 |
| 2039 DefineAsRegister(result); | 1986 DefineAsRegister(result); |
| 2040 bool can_deoptimize = instr->RequiresHoleCheck() || | 1987 bool can_deoptimize = instr->RequiresHoleCheck() || |
| 2041 (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) || | 1988 (elements_kind == EXTERNAL_UINT32_ELEMENTS) || |
| 2042 (elements_kind == UINT32_ELEMENTS); | 1989 (elements_kind == UINT32_ELEMENTS); |
| 2043 // An unsigned int array load might overflow and cause a deopt, make sure it | 1990 // An unsigned int array load might overflow and cause a deopt, make sure it |
| 2044 // has an environment. | 1991 // has an environment. |
| 2045 return can_deoptimize ? AssignEnvironment(result) : result; | 1992 return can_deoptimize ? AssignEnvironment(result) : result; |
| 2046 } | 1993 } |
| 2047 | 1994 |
| 2048 | 1995 |
| 2049 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { | 1996 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { |
| 2050 LOperand* context = UseFixed(instr->context(), rsi); | 1997 LOperand* context = UseFixed(instr->context(), rsi); |
| 2051 LOperand* object = UseFixed(instr->object(), rdx); | 1998 LOperand* object = UseFixed(instr->object(), rdx); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2092 ASSERT( | 2039 ASSERT( |
| 2093 (instr->value()->representation().IsInteger32() && | 2040 (instr->value()->representation().IsInteger32() && |
| 2094 !IsDoubleOrFloatElementsKind(elements_kind)) || | 2041 !IsDoubleOrFloatElementsKind(elements_kind)) || |
| 2095 (instr->value()->representation().IsDouble() && | 2042 (instr->value()->representation().IsDouble() && |
| 2096 IsDoubleOrFloatElementsKind(elements_kind))); | 2043 IsDoubleOrFloatElementsKind(elements_kind))); |
| 2097 ASSERT((instr->is_fixed_typed_array() && | 2044 ASSERT((instr->is_fixed_typed_array() && |
| 2098 instr->elements()->representation().IsTagged()) || | 2045 instr->elements()->representation().IsTagged()) || |
| 2099 (instr->is_external() && | 2046 (instr->is_external() && |
| 2100 instr->elements()->representation().IsExternal())); | 2047 instr->elements()->representation().IsExternal())); |
| 2101 bool val_is_temp_register = | 2048 bool val_is_temp_register = |
| 2102 elements_kind == EXTERNAL_PIXEL_ELEMENTS || | 2049 elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS || |
| 2103 elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 2050 elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
| 2104 elements_kind == FLOAT32_ELEMENTS; | 2051 elements_kind == FLOAT32_ELEMENTS; |
| 2105 LOperand* val = val_is_temp_register ? UseTempRegister(instr->value()) | 2052 LOperand* val = val_is_temp_register ? UseTempRegister(instr->value()) |
| 2106 : UseRegister(instr->value()); | 2053 : UseRegister(instr->value()); |
| 2107 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); | 2054 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); |
| 2108 LOperand* backing_store = UseRegister(instr->elements()); | 2055 LOperand* backing_store = UseRegister(instr->elements()); |
| 2109 return new(zone()) LStoreKeyed(backing_store, key, val); | 2056 return new(zone()) LStoreKeyed(backing_store, key, val); |
| 2110 } | 2057 } |
| 2111 | 2058 |
| 2112 | 2059 |
| 2113 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { | 2060 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2221 LOperand* value = UseFixed(instr->value(), rax); | 2168 LOperand* value = UseFixed(instr->value(), rax); |
| 2222 | 2169 |
| 2223 LStoreNamedGeneric* result = | 2170 LStoreNamedGeneric* result = |
| 2224 new(zone()) LStoreNamedGeneric(context, object, value); | 2171 new(zone()) LStoreNamedGeneric(context, object, value); |
| 2225 return MarkAsCall(result, instr); | 2172 return MarkAsCall(result, instr); |
| 2226 } | 2173 } |
| 2227 | 2174 |
| 2228 | 2175 |
| 2229 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) { | 2176 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) { |
| 2230 LOperand* context = UseFixed(instr->context(), rsi); | 2177 LOperand* context = UseFixed(instr->context(), rsi); |
| 2231 LOperand* left = FLAG_new_string_add | 2178 LOperand* left = UseFixed(instr->left(), rdx); |
| 2232 ? UseFixed(instr->left(), rdx) | 2179 LOperand* right = UseFixed(instr->right(), rax); |
| 2233 : UseOrConstantAtStart(instr->left()); | |
| 2234 LOperand* right = FLAG_new_string_add | |
| 2235 ? UseFixed(instr->right(), rax) | |
| 2236 : UseOrConstantAtStart(instr->right()); | |
| 2237 return MarkAsCall( | 2180 return MarkAsCall( |
| 2238 DefineFixed(new(zone()) LStringAdd(context, left, right), rax), instr); | 2181 DefineFixed(new(zone()) LStringAdd(context, left, right), rax), instr); |
| 2239 } | 2182 } |
| 2240 | 2183 |
| 2241 | 2184 |
| 2242 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { | 2185 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { |
| 2243 LOperand* string = UseTempRegister(instr->string()); | 2186 LOperand* string = UseTempRegister(instr->string()); |
| 2244 LOperand* index = UseTempRegister(instr->index()); | 2187 LOperand* index = UseTempRegister(instr->index()); |
| 2245 LOperand* context = UseAny(instr->context()); | 2188 LOperand* context = UseAny(instr->context()); |
| 2246 LStringCharCodeAt* result = | 2189 LStringCharCodeAt* result = |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2493 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2436 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
| 2494 LOperand* object = UseRegister(instr->object()); | 2437 LOperand* object = UseRegister(instr->object()); |
| 2495 LOperand* index = UseTempRegister(instr->index()); | 2438 LOperand* index = UseTempRegister(instr->index()); |
| 2496 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); | 2439 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); |
| 2497 } | 2440 } |
| 2498 | 2441 |
| 2499 | 2442 |
| 2500 } } // namespace v8::internal | 2443 } } // namespace v8::internal |
| 2501 | 2444 |
| 2502 #endif // V8_TARGET_ARCH_X64 | 2445 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |