| 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 830 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 841 } | 841 } |
| 842 block->set_argument_count(argument_count_); | 842 block->set_argument_count(argument_count_); |
| 843 next_block_ = NULL; | 843 next_block_ = NULL; |
| 844 current_block_ = NULL; | 844 current_block_ = NULL; |
| 845 } | 845 } |
| 846 | 846 |
| 847 | 847 |
| 848 void LChunkBuilder::VisitInstruction(HInstruction* current) { | 848 void LChunkBuilder::VisitInstruction(HInstruction* current) { |
| 849 HInstruction* old_current = current_instruction_; | 849 HInstruction* old_current = current_instruction_; |
| 850 current_instruction_ = current; | 850 current_instruction_ = current; |
| 851 if (current->has_position()) position_ = current->position(); | |
| 852 | 851 |
| 853 LInstruction* instr = NULL; | 852 LInstruction* instr = NULL; |
| 854 if (current->CanReplaceWithDummyUses()) { | 853 if (current->CanReplaceWithDummyUses()) { |
| 855 if (current->OperandCount() == 0) { | 854 if (current->OperandCount() == 0) { |
| 856 instr = DefineAsRegister(new(zone()) LDummy()); | 855 instr = DefineAsRegister(new(zone()) LDummy()); |
| 857 } else { | 856 } else { |
| 857 ASSERT(!current->OperandAt(0)->IsControlInstruction()); |
| 858 instr = DefineAsRegister(new(zone()) | 858 instr = DefineAsRegister(new(zone()) |
| 859 LDummyUse(UseAny(current->OperandAt(0)))); | 859 LDummyUse(UseAny(current->OperandAt(0)))); |
| 860 } | 860 } |
| 861 for (int i = 1; i < current->OperandCount(); ++i) { | 861 for (int i = 1; i < current->OperandCount(); ++i) { |
| 862 if (current->OperandAt(i)->IsControlInstruction()) continue; |
| 862 LInstruction* dummy = | 863 LInstruction* dummy = |
| 863 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); | 864 new(zone()) LDummyUse(UseAny(current->OperandAt(i))); |
| 864 dummy->set_hydrogen_value(current); | 865 dummy->set_hydrogen_value(current); |
| 865 chunk_->AddInstruction(dummy, current_block_); | 866 chunk_->AddInstruction(dummy, current_block_); |
| 866 } | 867 } |
| 867 } else { | 868 } else { |
| 868 instr = current->CompileToLithium(this); | 869 instr = current->CompileToLithium(this); |
| 869 } | 870 } |
| 870 | 871 |
| 871 argument_count_ += current->argument_delta(); | 872 argument_count_ += current->argument_delta(); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 936 ToBooleanStub::Types expected = instr->expected_input_types(); | 937 ToBooleanStub::Types expected = instr->expected_input_types(); |
| 937 if (rep.IsTagged() && !type.IsSmi() && !type.IsBoolean() && | 938 if (rep.IsTagged() && !type.IsSmi() && !type.IsBoolean() && |
| 938 !expected.IsGeneric()) { | 939 !expected.IsGeneric()) { |
| 939 return AssignEnvironment(result); | 940 return AssignEnvironment(result); |
| 940 } | 941 } |
| 941 return result; | 942 return result; |
| 942 } | 943 } |
| 943 | 944 |
| 944 | 945 |
| 945 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { | 946 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) { |
| 947 LInstruction* goto_instr = CheckElideControlInstruction(instr); |
| 948 if (goto_instr != NULL) return goto_instr; |
| 949 |
| 946 ASSERT(instr->value()->representation().IsTagged()); | 950 ASSERT(instr->value()->representation().IsTagged()); |
| 947 LOperand* value = UseRegisterAtStart(instr->value()); | 951 LOperand* value = UseRegisterAtStart(instr->value()); |
| 948 LOperand* temp = TempRegister(); | 952 LOperand* temp = TempRegister(); |
| 949 return new(zone()) LCmpMapAndBranch(value, temp); | 953 return new(zone()) LCmpMapAndBranch(value, temp); |
| 950 } | 954 } |
| 951 | 955 |
| 952 | 956 |
| 953 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { | 957 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { |
| 954 info()->MarkAsRequiresFrame(); | 958 info()->MarkAsRequiresFrame(); |
| 955 return DefineAsRegister( | 959 return DefineAsRegister( |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1038 if (instr->HasNoUses()) return NULL; | 1042 if (instr->HasNoUses()) return NULL; |
| 1039 | 1043 |
| 1040 if (info()->IsStub()) { | 1044 if (info()->IsStub()) { |
| 1041 return DefineFixed(new(zone()) LContext, cp); | 1045 return DefineFixed(new(zone()) LContext, cp); |
| 1042 } | 1046 } |
| 1043 | 1047 |
| 1044 return DefineAsRegister(new(zone()) LContext); | 1048 return DefineAsRegister(new(zone()) LContext); |
| 1045 } | 1049 } |
| 1046 | 1050 |
| 1047 | 1051 |
| 1048 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { | |
| 1049 LOperand* context = UseRegisterAtStart(instr->value()); | |
| 1050 return DefineAsRegister(new(zone()) LOuterContext(context)); | |
| 1051 } | |
| 1052 | |
| 1053 | |
| 1054 LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) { | 1052 LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) { |
| 1055 LOperand* context = UseFixed(instr->context(), cp); | 1053 LOperand* context = UseFixed(instr->context(), cp); |
| 1056 return MarkAsCall(new(zone()) LDeclareGlobals(context), instr); | 1054 return MarkAsCall(new(zone()) LDeclareGlobals(context), instr); |
| 1057 } | 1055 } |
| 1058 | 1056 |
| 1059 | 1057 |
| 1060 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { | |
| 1061 LOperand* context = UseRegisterAtStart(instr->value()); | |
| 1062 return DefineAsRegister(new(zone()) LGlobalObject(context)); | |
| 1063 } | |
| 1064 | |
| 1065 | |
| 1066 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { | |
| 1067 LOperand* global_object = UseRegisterAtStart(instr->value()); | |
| 1068 return DefineAsRegister(new(zone()) LGlobalReceiver(global_object)); | |
| 1069 } | |
| 1070 | |
| 1071 | |
| 1072 LInstruction* LChunkBuilder::DoCallJSFunction( | 1058 LInstruction* LChunkBuilder::DoCallJSFunction( |
| 1073 HCallJSFunction* instr) { | 1059 HCallJSFunction* instr) { |
| 1074 LOperand* function = UseFixed(instr->function(), a1); | 1060 LOperand* function = UseFixed(instr->function(), a1); |
| 1075 | 1061 |
| 1076 LCallJSFunction* result = new(zone()) LCallJSFunction(function); | 1062 LCallJSFunction* result = new(zone()) LCallJSFunction(function); |
| 1077 | 1063 |
| 1078 return MarkAsCall(DefineFixed(result, v0), instr); | 1064 return MarkAsCall(DefineFixed(result, v0), instr); |
| 1079 } | 1065 } |
| 1080 | 1066 |
| 1081 | 1067 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1108 | 1094 |
| 1109 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { | 1095 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { |
| 1110 switch (instr->op()) { | 1096 switch (instr->op()) { |
| 1111 case kMathFloor: return DoMathFloor(instr); | 1097 case kMathFloor: return DoMathFloor(instr); |
| 1112 case kMathRound: return DoMathRound(instr); | 1098 case kMathRound: return DoMathRound(instr); |
| 1113 case kMathAbs: return DoMathAbs(instr); | 1099 case kMathAbs: return DoMathAbs(instr); |
| 1114 case kMathLog: return DoMathLog(instr); | 1100 case kMathLog: return DoMathLog(instr); |
| 1115 case kMathExp: return DoMathExp(instr); | 1101 case kMathExp: return DoMathExp(instr); |
| 1116 case kMathSqrt: return DoMathSqrt(instr); | 1102 case kMathSqrt: return DoMathSqrt(instr); |
| 1117 case kMathPowHalf: return DoMathPowHalf(instr); | 1103 case kMathPowHalf: return DoMathPowHalf(instr); |
| 1104 case kMathClz32: return DoMathClz32(instr); |
| 1118 default: | 1105 default: |
| 1119 UNREACHABLE(); | 1106 UNREACHABLE(); |
| 1120 return NULL; | 1107 return NULL; |
| 1121 } | 1108 } |
| 1122 } | 1109 } |
| 1123 | 1110 |
| 1124 | 1111 |
| 1125 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) { | 1112 LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) { |
| 1126 ASSERT(instr->representation().IsDouble()); | 1113 ASSERT(instr->representation().IsDouble()); |
| 1127 ASSERT(instr->value()->representation().IsDouble()); | 1114 ASSERT(instr->value()->representation().IsDouble()); |
| 1128 LOperand* input = UseFixedDouble(instr->value(), f4); | 1115 LOperand* input = UseFixedDouble(instr->value(), f4); |
| 1129 return MarkAsCall(DefineFixedDouble(new(zone()) LMathLog(input), f4), instr); | 1116 return MarkAsCall(DefineFixedDouble(new(zone()) LMathLog(input), f4), instr); |
| 1130 } | 1117 } |
| 1131 | 1118 |
| 1132 | 1119 |
| 1120 LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) { |
| 1121 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1122 LMathClz32* result = new(zone()) LMathClz32(input); |
| 1123 return DefineAsRegister(result); |
| 1124 } |
| 1125 |
| 1126 |
| 1133 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) { | 1127 LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) { |
| 1134 ASSERT(instr->representation().IsDouble()); | 1128 ASSERT(instr->representation().IsDouble()); |
| 1135 ASSERT(instr->value()->representation().IsDouble()); | 1129 ASSERT(instr->value()->representation().IsDouble()); |
| 1136 LOperand* input = UseRegister(instr->value()); | 1130 LOperand* input = UseRegister(instr->value()); |
| 1137 LOperand* temp1 = TempRegister(); | 1131 LOperand* temp1 = TempRegister(); |
| 1138 LOperand* temp2 = TempRegister(); | 1132 LOperand* temp2 = TempRegister(); |
| 1139 LOperand* double_temp = FixedTemp(f6); // Chosen by fair dice roll. | 1133 LOperand* double_temp = FixedTemp(f6); // Chosen by fair dice roll. |
| 1140 LMathExp* result = new(zone()) LMathExp(input, double_temp, temp1, temp2); | 1134 LMathExp* result = new(zone()) LMathExp(input, double_temp, temp1, temp2); |
| 1141 return DefineAsRegister(result); | 1135 return DefineAsRegister(result); |
| 1142 } | 1136 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1198 LOperand* constructor = UseFixed(instr->constructor(), a1); | 1192 LOperand* constructor = UseFixed(instr->constructor(), a1); |
| 1199 LCallNewArray* result = new(zone()) LCallNewArray(context, constructor); | 1193 LCallNewArray* result = new(zone()) LCallNewArray(context, constructor); |
| 1200 return MarkAsCall(DefineFixed(result, v0), instr); | 1194 return MarkAsCall(DefineFixed(result, v0), instr); |
| 1201 } | 1195 } |
| 1202 | 1196 |
| 1203 | 1197 |
| 1204 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { | 1198 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { |
| 1205 LOperand* context = UseFixed(instr->context(), cp); | 1199 LOperand* context = UseFixed(instr->context(), cp); |
| 1206 LOperand* function = UseFixed(instr->function(), a1); | 1200 LOperand* function = UseFixed(instr->function(), a1); |
| 1207 LCallFunction* call = new(zone()) LCallFunction(context, function); | 1201 LCallFunction* call = new(zone()) LCallFunction(context, function); |
| 1208 LInstruction* result = DefineFixed(call, v0); | 1202 return MarkAsCall(DefineFixed(call, v0), instr); |
| 1209 if (instr->IsTailCall()) return result; | |
| 1210 return MarkAsCall(result, instr); | |
| 1211 } | 1203 } |
| 1212 | 1204 |
| 1213 | 1205 |
| 1214 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { | 1206 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { |
| 1215 LOperand* context = UseFixed(instr->context(), cp); | 1207 LOperand* context = UseFixed(instr->context(), cp); |
| 1216 return MarkAsCall(DefineFixed(new(zone()) LCallRuntime(context), v0), instr); | 1208 return MarkAsCall(DefineFixed(new(zone()) LCallRuntime(context), v0), instr); |
| 1217 } | 1209 } |
| 1218 | 1210 |
| 1219 | 1211 |
| 1220 LInstruction* LChunkBuilder::DoRor(HRor* instr) { | 1212 LInstruction* LChunkBuilder::DoRor(HRor* instr) { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1288 int32_t power_of_2_factor = | 1280 int32_t power_of_2_factor = |
| 1289 CompilerIntrinsics::CountTrailingZeros(divisor_abs); | 1281 CompilerIntrinsics::CountTrailingZeros(divisor_abs); |
| 1290 DivMagicNumbers magic_numbers = | 1282 DivMagicNumbers magic_numbers = |
| 1291 DivMagicNumberFor(divisor_abs >> power_of_2_factor); | 1283 DivMagicNumberFor(divisor_abs >> power_of_2_factor); |
| 1292 if (magic_numbers.M != InvalidDivMagicNumber.M) return true; | 1284 if (magic_numbers.M != InvalidDivMagicNumber.M) return true; |
| 1293 | 1285 |
| 1294 return false; | 1286 return false; |
| 1295 } | 1287 } |
| 1296 | 1288 |
| 1297 | 1289 |
| 1298 HValue* LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(HValue* divisor) { | |
| 1299 // Only optimize when we have magic numbers for the divisor. | |
| 1300 // The standard integer division routine is usually slower than transitionning | |
| 1301 // to FPU. | |
| 1302 if (divisor->IsConstant() && | |
| 1303 HConstant::cast(divisor)->HasInteger32Value()) { | |
| 1304 HConstant* constant_val = HConstant::cast(divisor); | |
| 1305 return constant_val->CopyToRepresentation(Representation::Integer32(), | |
| 1306 divisor->block()->zone()); | |
| 1307 } | |
| 1308 return NULL; | |
| 1309 } | |
| 1310 | |
| 1311 | |
| 1312 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { | 1290 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { |
| 1313 HValue* right = instr->right(); | 1291 HValue* right = instr->right(); |
| 1314 LOperand* dividend = UseRegister(instr->left()); | 1292 LOperand* dividend = UseRegister(instr->left()); |
| 1315 LOperand* divisor = UseRegisterOrConstant(right); | 1293 LOperand* divisor = UseRegisterOrConstant(right); |
| 1316 LOperand* remainder = TempRegister(); | 1294 LOperand* remainder = TempRegister(); |
| 1317 return AssignEnvironment(DefineAsRegister( | 1295 return AssignEnvironment(DefineAsRegister( |
| 1318 new(zone()) LMathFloorOfDiv(dividend, divisor, remainder))); | 1296 new(zone()) LMathFloorOfDiv(dividend, divisor, remainder))); |
| 1319 } | 1297 } |
| 1320 | 1298 |
| 1321 | 1299 |
| 1322 LInstruction* LChunkBuilder::DoMod(HMod* instr) { | 1300 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
| 1323 HValue* left = instr->left(); | 1301 HValue* left = instr->left(); |
| 1324 HValue* right = instr->right(); | 1302 HValue* right = instr->right(); |
| 1325 if (instr->representation().IsSmiOrInteger32()) { | 1303 if (instr->representation().IsSmiOrInteger32()) { |
| 1326 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1304 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1327 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1305 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 1328 if (instr->HasPowerOf2Divisor()) { | 1306 if (instr->RightIsPowerOf2()) { |
| 1329 ASSERT(!right->CanBeZero()); | 1307 ASSERT(!right->CanBeZero()); |
| 1330 LModI* mod = new(zone()) LModI(UseRegisterAtStart(left), | 1308 LModI* mod = new(zone()) LModI(UseRegisterAtStart(left), |
| 1331 UseConstant(right)); | 1309 UseConstant(right)); |
| 1332 LInstruction* result = DefineAsRegister(mod); | 1310 LInstruction* result = DefineAsRegister(mod); |
| 1333 return (left->CanBeNegative() && | 1311 return (left->CanBeNegative() && |
| 1334 instr->CheckFlag(HValue::kBailoutOnMinusZero)) | 1312 instr->CheckFlag(HValue::kBailoutOnMinusZero)) |
| 1335 ? AssignEnvironment(result) | 1313 ? AssignEnvironment(result) |
| 1336 : result; | 1314 : result; |
| 1337 } else { | 1315 } else { |
| 1338 LModI* mod = new(zone()) LModI(UseRegister(left), | 1316 LModI* mod = new(zone()) LModI(UseRegister(left), |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1656 TempRegister()); | 1634 TempRegister()); |
| 1657 } | 1635 } |
| 1658 | 1636 |
| 1659 | 1637 |
| 1660 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { | 1638 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { |
| 1661 LOperand* map = UseRegisterAtStart(instr->value()); | 1639 LOperand* map = UseRegisterAtStart(instr->value()); |
| 1662 return DefineAsRegister(new(zone()) LMapEnumLength(map)); | 1640 return DefineAsRegister(new(zone()) LMapEnumLength(map)); |
| 1663 } | 1641 } |
| 1664 | 1642 |
| 1665 | 1643 |
| 1666 LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) { | |
| 1667 LOperand* object = UseRegisterAtStart(instr->value()); | |
| 1668 return DefineAsRegister(new(zone()) LElementsKind(object)); | |
| 1669 } | |
| 1670 | |
| 1671 | |
| 1672 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { | |
| 1673 LOperand* object = UseRegister(instr->value()); | |
| 1674 LValueOf* result = new(zone()) LValueOf(object, TempRegister()); | |
| 1675 return DefineAsRegister(result); | |
| 1676 } | |
| 1677 | |
| 1678 | |
| 1679 LInstruction* LChunkBuilder::DoDateField(HDateField* instr) { | 1644 LInstruction* LChunkBuilder::DoDateField(HDateField* instr) { |
| 1680 LOperand* object = UseFixed(instr->value(), a0); | 1645 LOperand* object = UseFixed(instr->value(), a0); |
| 1681 LDateField* result = | 1646 LDateField* result = |
| 1682 new(zone()) LDateField(object, FixedTemp(a1), instr->index()); | 1647 new(zone()) LDateField(object, FixedTemp(a1), instr->index()); |
| 1683 return MarkAsCall(DefineFixed(result, v0), instr, CAN_DEOPTIMIZE_EAGERLY); | 1648 return MarkAsCall(DefineFixed(result, v0), instr, CAN_DEOPTIMIZE_EAGERLY); |
| 1684 } | 1649 } |
| 1685 | 1650 |
| 1686 | 1651 |
| 1687 LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) { | 1652 LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) { |
| 1688 LOperand* string = UseRegisterAtStart(instr->string()); | 1653 LOperand* string = UseRegisterAtStart(instr->string()); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1716 } | 1681 } |
| 1717 | 1682 |
| 1718 | 1683 |
| 1719 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { | 1684 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { |
| 1720 // The control instruction marking the end of a block that completed | 1685 // The control instruction marking the end of a block that completed |
| 1721 // abruptly (e.g., threw an exception). There is nothing specific to do. | 1686 // abruptly (e.g., threw an exception). There is nothing specific to do. |
| 1722 return NULL; | 1687 return NULL; |
| 1723 } | 1688 } |
| 1724 | 1689 |
| 1725 | 1690 |
| 1726 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { | |
| 1727 LOperand* context = UseFixed(instr->context(), cp); | |
| 1728 LOperand* value = UseFixed(instr->value(), a0); | |
| 1729 return MarkAsCall(new(zone()) LThrow(context, value), instr); | |
| 1730 } | |
| 1731 | |
| 1732 | |
| 1733 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) { | 1691 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) { |
| 1734 return NULL; | 1692 return NULL; |
| 1735 } | 1693 } |
| 1736 | 1694 |
| 1737 | 1695 |
| 1738 LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) { | 1696 LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) { |
| 1739 // All HForceRepresentation instructions should be eliminated in the | 1697 // All HForceRepresentation instructions should be eliminated in the |
| 1740 // representation change phase of Hydrogen. | 1698 // representation change phase of Hydrogen. |
| 1741 UNREACHABLE(); | 1699 UNREACHABLE(); |
| 1742 return NULL; | 1700 return NULL; |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2005 return AssignEnvironment(DefineAsRegister( | 1963 return AssignEnvironment(DefineAsRegister( |
| 2006 new(zone()) LLoadFunctionPrototype(UseRegister(instr->function())))); | 1964 new(zone()) LLoadFunctionPrototype(UseRegister(instr->function())))); |
| 2007 } | 1965 } |
| 2008 | 1966 |
| 2009 | 1967 |
| 2010 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) { | 1968 LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) { |
| 2011 return DefineAsRegister(new(zone()) LLoadRoot); | 1969 return DefineAsRegister(new(zone()) LLoadRoot); |
| 2012 } | 1970 } |
| 2013 | 1971 |
| 2014 | 1972 |
| 2015 LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( | |
| 2016 HLoadExternalArrayPointer* instr) { | |
| 2017 LOperand* input = UseRegisterAtStart(instr->value()); | |
| 2018 return DefineAsRegister(new(zone()) LLoadExternalArrayPointer(input)); | |
| 2019 } | |
| 2020 | |
| 2021 | |
| 2022 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { | 1973 LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { |
| 2023 ASSERT(instr->key()->representation().IsSmiOrInteger32()); | 1974 ASSERT(instr->key()->representation().IsSmiOrInteger32()); |
| 2024 ElementsKind elements_kind = instr->elements_kind(); | 1975 ElementsKind elements_kind = instr->elements_kind(); |
| 2025 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); | 1976 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); |
| 2026 LLoadKeyed* result = NULL; | 1977 LLoadKeyed* result = NULL; |
| 2027 | 1978 |
| 2028 if (!instr->is_typed_elements()) { | 1979 if (!instr->is_typed_elements()) { |
| 2029 LOperand* obj = NULL; | 1980 LOperand* obj = NULL; |
| 2030 if (instr->representation().IsDouble()) { | 1981 if (instr->representation().IsDouble()) { |
| 2031 obj = UseRegister(instr->elements()); | 1982 obj = UseRegister(instr->elements()); |
| 2032 } else { | 1983 } else { |
| 2033 ASSERT(instr->representation().IsSmiOrTagged()); | 1984 ASSERT(instr->representation().IsSmiOrTagged()); |
| 2034 obj = UseRegisterAtStart(instr->elements()); | 1985 obj = UseRegisterAtStart(instr->elements()); |
| 2035 } | 1986 } |
| 2036 result = new(zone()) LLoadKeyed(obj, key); | 1987 result = new(zone()) LLoadKeyed(obj, key); |
| 2037 } else { | 1988 } else { |
| 2038 ASSERT( | 1989 ASSERT( |
| 2039 (instr->representation().IsInteger32() && | 1990 (instr->representation().IsInteger32() && |
| 2040 !IsDoubleOrFloatElementsKind(instr->elements_kind())) || | 1991 !IsDoubleOrFloatElementsKind(instr->elements_kind())) || |
| 2041 (instr->representation().IsDouble() && | 1992 (instr->representation().IsDouble() && |
| 2042 IsDoubleOrFloatElementsKind(instr->elements_kind()))); | 1993 IsDoubleOrFloatElementsKind(instr->elements_kind()))); |
| 2043 LOperand* backing_store = UseRegister(instr->elements()); | 1994 LOperand* backing_store = UseRegister(instr->elements()); |
| 2044 result = new(zone()) LLoadKeyed(backing_store, key); | 1995 result = new(zone()) LLoadKeyed(backing_store, key); |
| 2045 } | 1996 } |
| 2046 | 1997 |
| 2047 DefineAsRegister(result); | 1998 DefineAsRegister(result); |
| 2048 // An unsigned int array load might overflow and cause a deopt, make sure it | 1999 // An unsigned int array load might overflow and cause a deopt, make sure it |
| 2049 // has an environment. | 2000 // has an environment. |
| 2050 bool can_deoptimize = instr->RequiresHoleCheck() || | 2001 bool can_deoptimize = instr->RequiresHoleCheck() || |
| 2051 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS || | 2002 elements_kind == EXTERNAL_UINT32_ELEMENTS || |
| 2052 elements_kind == UINT32_ELEMENTS; | 2003 elements_kind == UINT32_ELEMENTS; |
| 2053 return can_deoptimize ? AssignEnvironment(result) : result; | 2004 return can_deoptimize ? AssignEnvironment(result) : result; |
| 2054 } | 2005 } |
| 2055 | 2006 |
| 2056 | 2007 |
| 2057 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { | 2008 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { |
| 2058 LOperand* context = UseFixed(instr->context(), cp); | 2009 LOperand* context = UseFixed(instr->context(), cp); |
| 2059 LOperand* object = UseFixed(instr->object(), a1); | 2010 LOperand* object = UseFixed(instr->object(), a1); |
| 2060 LOperand* key = UseFixed(instr->key(), a0); | 2011 LOperand* key = UseFixed(instr->key(), a0); |
| 2061 | 2012 |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2198 LOperand* obj = UseFixed(instr->object(), a1); | 2149 LOperand* obj = UseFixed(instr->object(), a1); |
| 2199 LOperand* val = UseFixed(instr->value(), a0); | 2150 LOperand* val = UseFixed(instr->value(), a0); |
| 2200 | 2151 |
| 2201 LInstruction* result = new(zone()) LStoreNamedGeneric(context, obj, val); | 2152 LInstruction* result = new(zone()) LStoreNamedGeneric(context, obj, val); |
| 2202 return MarkAsCall(result, instr); | 2153 return MarkAsCall(result, instr); |
| 2203 } | 2154 } |
| 2204 | 2155 |
| 2205 | 2156 |
| 2206 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) { | 2157 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) { |
| 2207 LOperand* context = UseFixed(instr->context(), cp); | 2158 LOperand* context = UseFixed(instr->context(), cp); |
| 2208 LOperand* left = FLAG_new_string_add | 2159 LOperand* left = UseFixed(instr->left(), a1); |
| 2209 ? UseFixed(instr->left(), a1) | 2160 LOperand* right = UseFixed(instr->right(), a0); |
| 2210 : UseRegisterAtStart(instr->left()); | |
| 2211 LOperand* right = FLAG_new_string_add | |
| 2212 ? UseFixed(instr->right(), a0) | |
| 2213 : UseRegisterAtStart(instr->right()); | |
| 2214 return MarkAsCall( | 2161 return MarkAsCall( |
| 2215 DefineFixed(new(zone()) LStringAdd(context, left, right), v0), | 2162 DefineFixed(new(zone()) LStringAdd(context, left, right), v0), |
| 2216 instr); | 2163 instr); |
| 2217 } | 2164 } |
| 2218 | 2165 |
| 2219 | 2166 |
| 2220 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { | 2167 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { |
| 2221 LOperand* string = UseTempRegister(instr->string()); | 2168 LOperand* string = UseTempRegister(instr->string()); |
| 2222 LOperand* index = UseTempRegister(instr->index()); | 2169 LOperand* index = UseTempRegister(instr->index()); |
| 2223 LOperand* context = UseAny(instr->context()); | 2170 LOperand* context = UseAny(instr->context()); |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2459 | 2406 |
| 2460 | 2407 |
| 2461 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2408 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
| 2462 LOperand* object = UseRegister(instr->object()); | 2409 LOperand* object = UseRegister(instr->object()); |
| 2463 LOperand* index = UseRegister(instr->index()); | 2410 LOperand* index = UseRegister(instr->index()); |
| 2464 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); | 2411 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); |
| 2465 } | 2412 } |
| 2466 | 2413 |
| 2467 | 2414 |
| 2468 } } // namespace v8::internal | 2415 } } // namespace v8::internal |
| OLD | NEW |