| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 ASSERT(double_register_spills_[allocation_index] == NULL); | 67 ASSERT(double_register_spills_[allocation_index] == NULL); |
| 68 double_register_spills_[allocation_index] = spill_operand; | 68 double_register_spills_[allocation_index] = spill_operand; |
| 69 } | 69 } |
| 70 | 70 |
| 71 | 71 |
| 72 #ifdef DEBUG | 72 #ifdef DEBUG |
| 73 void LInstruction::VerifyCall() { | 73 void LInstruction::VerifyCall() { |
| 74 // Call instructions can use only fixed registers as | 74 // Call instructions can use only fixed registers as |
| 75 // temporaries and outputs because all registers | 75 // temporaries and outputs because all registers |
| 76 // are blocked by the calling convention. | 76 // are blocked by the calling convention. |
| 77 // Inputs can use either fixed register or have a short lifetime (be | 77 // Inputs must use a fixed register. |
| 78 // used at start of the instruction). | |
| 79 ASSERT(Output() == NULL || | 78 ASSERT(Output() == NULL || |
| 80 LUnallocated::cast(Output())->HasFixedPolicy() || | 79 LUnallocated::cast(Output())->HasFixedPolicy() || |
| 81 !LUnallocated::cast(Output())->HasRegisterPolicy()); | 80 !LUnallocated::cast(Output())->HasRegisterPolicy()); |
| 82 for (UseIterator it(this); it.HasNext(); it.Advance()) { | 81 for (UseIterator it(this); it.HasNext(); it.Advance()) { |
| 83 LOperand* operand = it.Next(); | 82 LOperand* operand = it.Next(); |
| 84 ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() || | 83 ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() || |
| 85 LUnallocated::cast(operand)->IsUsedAtStart() || | |
| 86 !LUnallocated::cast(operand)->HasRegisterPolicy()); | 84 !LUnallocated::cast(operand)->HasRegisterPolicy()); |
| 87 } | 85 } |
| 88 for (TempIterator it(this); it.HasNext(); it.Advance()) { | 86 for (TempIterator it(this); it.HasNext(); it.Advance()) { |
| 89 LOperand* operand = it.Next(); | 87 LOperand* operand = it.Next(); |
| 90 ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() || | 88 ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() || |
| 91 !LUnallocated::cast(operand)->HasRegisterPolicy()); | 89 !LUnallocated::cast(operand)->HasRegisterPolicy()); |
| 92 } | 90 } |
| 93 } | 91 } |
| 94 #endif | 92 #endif |
| 95 | 93 |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 | 397 |
| 400 if (can_eliminate) { | 398 if (can_eliminate) { |
| 401 label->set_replacement(GetLabel(goto_instr->block_id())); | 399 label->set_replacement(GetLabel(goto_instr->block_id())); |
| 402 } | 400 } |
| 403 } | 401 } |
| 404 } | 402 } |
| 405 } | 403 } |
| 406 } | 404 } |
| 407 | 405 |
| 408 | 406 |
| 409 void LStoreNamed::PrintDataTo(StringStream* stream) { | 407 void LStoreNamedField::PrintDataTo(StringStream* stream) { |
| 410 object()->PrintTo(stream); | 408 object()->PrintTo(stream); |
| 411 stream->Add("."); | 409 stream->Add("."); |
| 412 stream->Add(*String::cast(*name())->ToCString()); | 410 stream->Add(*String::cast(*name())->ToCString()); |
| 413 stream->Add(" <- "); | 411 stream->Add(" <- "); |
| 414 value()->PrintTo(stream); | 412 value()->PrintTo(stream); |
| 415 } | 413 } |
| 416 | 414 |
| 417 | 415 |
| 418 void LStoreKeyed::PrintDataTo(StringStream* stream) { | 416 void LStoreNamedGeneric::PrintDataTo(StringStream* stream) { |
| 417 object()->PrintTo(stream); |
| 418 stream->Add("."); |
| 419 stream->Add(*String::cast(*name())->ToCString()); |
| 420 stream->Add(" <- "); |
| 421 value()->PrintTo(stream); |
| 422 } |
| 423 |
| 424 |
| 425 void LStoreKeyedFastElement::PrintDataTo(StringStream* stream) { |
| 419 object()->PrintTo(stream); | 426 object()->PrintTo(stream); |
| 420 stream->Add("["); | 427 stream->Add("["); |
| 421 key()->PrintTo(stream); | 428 key()->PrintTo(stream); |
| 422 stream->Add("] <- "); | 429 stream->Add("] <- "); |
| 423 value()->PrintTo(stream); | 430 value()->PrintTo(stream); |
| 424 } | 431 } |
| 425 | 432 |
| 426 | 433 |
| 434 void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) { |
| 435 object()->PrintTo(stream); |
| 436 stream->Add("["); |
| 437 key()->PrintTo(stream); |
| 438 stream->Add("] <- "); |
| 439 value()->PrintTo(stream); |
| 440 } |
| 441 |
| 442 |
| 427 void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { | 443 void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { |
| 428 LGap* gap = new LGap(block); | 444 LGap* gap = new LGap(block); |
| 429 int index = -1; | 445 int index = -1; |
| 430 if (instr->IsControl()) { | 446 if (instr->IsControl()) { |
| 431 instructions_.Add(gap); | 447 instructions_.Add(gap); |
| 432 index = instructions_.length(); | 448 index = instructions_.length(); |
| 433 instructions_.Add(instr); | 449 instructions_.Add(instr); |
| 434 } else { | 450 } else { |
| 435 index = instructions_.length(); | 451 index = instructions_.length(); |
| 436 instructions_.Add(instr); | 452 instructions_.Add(instr); |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 847 ? AssignEnvironment(DefineSameAsFirst(result)) | 863 ? AssignEnvironment(DefineSameAsFirst(result)) |
| 848 : DefineSameAsFirst(result); | 864 : DefineSameAsFirst(result); |
| 849 } | 865 } |
| 850 | 866 |
| 851 | 867 |
| 852 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, | 868 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, |
| 853 HArithmeticBinaryOperation* instr) { | 869 HArithmeticBinaryOperation* instr) { |
| 854 ASSERT(instr->representation().IsDouble()); | 870 ASSERT(instr->representation().IsDouble()); |
| 855 ASSERT(instr->left()->representation().IsDouble()); | 871 ASSERT(instr->left()->representation().IsDouble()); |
| 856 ASSERT(instr->right()->representation().IsDouble()); | 872 ASSERT(instr->right()->representation().IsDouble()); |
| 873 ASSERT(op != Token::MOD); |
| 857 LOperand* left = UseRegisterAtStart(instr->left()); | 874 LOperand* left = UseRegisterAtStart(instr->left()); |
| 858 LOperand* right = UseRegisterAtStart(instr->right()); | 875 LOperand* right = UseRegisterAtStart(instr->right()); |
| 859 LArithmeticD* result = new LArithmeticD(op, left, right); | 876 LArithmeticD* result = new LArithmeticD(op, left, right); |
| 860 return DefineSameAsFirst(result); | 877 return DefineSameAsFirst(result); |
| 861 } | 878 } |
| 862 | 879 |
| 863 | 880 |
| 864 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, | 881 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, |
| 865 HArithmeticBinaryOperation* instr) { | 882 HArithmeticBinaryOperation* instr) { |
| 866 ASSERT(op == Token::ADD || | 883 ASSERT(op == Token::ADD || |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1083 LOperand* temp2 = TempRegister(); | 1100 LOperand* temp2 = TempRegister(); |
| 1084 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()), | 1101 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()), |
| 1085 temp1, | 1102 temp1, |
| 1086 temp2); | 1103 temp2); |
| 1087 } else if (v->IsCompareJSObjectEq()) { | 1104 } else if (v->IsCompareJSObjectEq()) { |
| 1088 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); | 1105 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); |
| 1089 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), | 1106 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), |
| 1090 UseRegisterAtStart(compare->right())); | 1107 UseRegisterAtStart(compare->right())); |
| 1091 } else if (v->IsInstanceOf()) { | 1108 } else if (v->IsInstanceOf()) { |
| 1092 HInstanceOf* instance_of = HInstanceOf::cast(v); | 1109 HInstanceOf* instance_of = HInstanceOf::cast(v); |
| 1110 LOperand* left = UseFixed(instance_of->left(), InstanceofStub::left()); |
| 1111 LOperand* right = UseFixed(instance_of->right(), InstanceofStub::right()); |
| 1112 LOperand* context = UseFixed(instance_of->context(), esi); |
| 1093 LInstanceOfAndBranch* result = | 1113 LInstanceOfAndBranch* result = |
| 1094 new LInstanceOfAndBranch( | 1114 new LInstanceOfAndBranch(context, left, right); |
| 1095 UseFixed(instance_of->left(), InstanceofStub::left()), | |
| 1096 UseFixed(instance_of->right(), InstanceofStub::right())); | |
| 1097 return MarkAsCall(result, instr); | 1115 return MarkAsCall(result, instr); |
| 1098 } else if (v->IsTypeofIs()) { | 1116 } else if (v->IsTypeofIs()) { |
| 1099 HTypeofIs* typeof_is = HTypeofIs::cast(v); | 1117 HTypeofIs* typeof_is = HTypeofIs::cast(v); |
| 1100 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value())); | 1118 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value())); |
| 1101 } else if (v->IsIsConstructCall()) { | 1119 } else if (v->IsIsConstructCall()) { |
| 1102 return new LIsConstructCallAndBranch(TempRegister()); | 1120 return new LIsConstructCallAndBranch(TempRegister()); |
| 1103 } else { | 1121 } else { |
| 1104 if (v->IsConstant()) { | 1122 if (v->IsConstant()) { |
| 1105 if (HConstant::cast(v)->handle()->IsTrue()) { | 1123 if (HConstant::cast(v)->handle()->IsTrue()) { |
| 1106 return new LGoto(instr->FirstSuccessor()->block_id()); | 1124 return new LGoto(instr->FirstSuccessor()->block_id()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1127 return DefineAsRegister(new LArgumentsLength(Use(length->value()))); | 1145 return DefineAsRegister(new LArgumentsLength(Use(length->value()))); |
| 1128 } | 1146 } |
| 1129 | 1147 |
| 1130 | 1148 |
| 1131 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { | 1149 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { |
| 1132 return DefineAsRegister(new LArgumentsElements); | 1150 return DefineAsRegister(new LArgumentsElements); |
| 1133 } | 1151 } |
| 1134 | 1152 |
| 1135 | 1153 |
| 1136 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { | 1154 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { |
| 1137 LInstanceOf* result = | 1155 LOperand* left = UseFixed(instr->left(), InstanceofStub::left()); |
| 1138 new LInstanceOf(UseFixed(instr->left(), InstanceofStub::left()), | 1156 LOperand* right = UseFixed(instr->right(), InstanceofStub::right()); |
| 1139 UseFixed(instr->right(), InstanceofStub::right())); | 1157 LOperand* context = UseFixed(instr->context(), esi); |
| 1158 LInstanceOf* result = new LInstanceOf(context, left, right); |
| 1140 return MarkAsCall(DefineFixed(result, eax), instr); | 1159 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1141 } | 1160 } |
| 1142 | 1161 |
| 1143 | 1162 |
| 1144 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( | 1163 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( |
| 1145 HInstanceOfKnownGlobal* instr) { | 1164 HInstanceOfKnownGlobal* instr) { |
| 1146 LInstanceOfKnownGlobal* result = | 1165 LInstanceOfKnownGlobal* result = |
| 1147 new LInstanceOfKnownGlobal( | 1166 new LInstanceOfKnownGlobal( |
| 1148 UseFixed(instr->value(), InstanceofStub::left()), | 1167 UseFixed(instr->value(), InstanceofStub::left()), |
| 1149 FixedTemp(edi)); | 1168 FixedTemp(edi)); |
| 1150 MarkAsSaveDoubles(result); | 1169 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1151 return AssignEnvironment(AssignPointerMap(DefineFixed(result, eax))); | |
| 1152 } | 1170 } |
| 1153 | 1171 |
| 1154 | 1172 |
| 1155 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { | 1173 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { |
| 1156 LOperand* function = UseFixed(instr->function(), edi); | 1174 LOperand* function = UseFixed(instr->function(), edi); |
| 1157 LOperand* receiver = UseFixed(instr->receiver(), eax); | 1175 LOperand* receiver = UseFixed(instr->receiver(), eax); |
| 1158 LOperand* length = UseRegisterAtStart(instr->length()); | 1176 LOperand* length = UseFixed(instr->length(), ebx); |
| 1159 LOperand* elements = UseRegisterAtStart(instr->elements()); | 1177 LOperand* elements = UseFixed(instr->elements(), ecx); |
| 1178 LOperand* temp = FixedTemp(edx); |
| 1160 LApplyArguments* result = new LApplyArguments(function, | 1179 LApplyArguments* result = new LApplyArguments(function, |
| 1161 receiver, | 1180 receiver, |
| 1162 length, | 1181 length, |
| 1163 elements); | 1182 elements, |
| 1183 temp); |
| 1164 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY); | 1184 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY); |
| 1165 } | 1185 } |
| 1166 | 1186 |
| 1167 | 1187 |
| 1168 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { | 1188 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { |
| 1169 ++argument_count_; | 1189 ++argument_count_; |
| 1170 LOperand* argument = UseOrConstant(instr->argument()); | 1190 LOperand* argument = UseOrConstant(instr->argument()); |
| 1171 return new LPushArgument(argument); | 1191 return new LPushArgument(argument); |
| 1172 } | 1192 } |
| 1173 | 1193 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1214 switch (op) { | 1234 switch (op) { |
| 1215 case kMathAbs: | 1235 case kMathAbs: |
| 1216 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); | 1236 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); |
| 1217 case kMathFloor: | 1237 case kMathFloor: |
| 1218 return AssignEnvironment(DefineAsRegister(result)); | 1238 return AssignEnvironment(DefineAsRegister(result)); |
| 1219 case kMathRound: | 1239 case kMathRound: |
| 1220 return AssignEnvironment(DefineAsRegister(result)); | 1240 return AssignEnvironment(DefineAsRegister(result)); |
| 1221 case kMathSqrt: | 1241 case kMathSqrt: |
| 1222 return DefineSameAsFirst(result); | 1242 return DefineSameAsFirst(result); |
| 1223 case kMathPowHalf: | 1243 case kMathPowHalf: |
| 1224 return AssignEnvironment(DefineSameAsFirst(result)); | 1244 return DefineSameAsFirst(result); |
| 1225 default: | 1245 default: |
| 1226 UNREACHABLE(); | 1246 UNREACHABLE(); |
| 1227 return NULL; | 1247 return NULL; |
| 1228 } | 1248 } |
| 1229 } | 1249 } |
| 1230 } | 1250 } |
| 1231 | 1251 |
| 1232 | 1252 |
| 1233 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { | 1253 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { |
| 1234 ASSERT(instr->key()->representation().IsTagged()); | 1254 ASSERT(instr->key()->representation().IsTagged()); |
| 1255 LOperand* context = UseFixed(instr->context(), esi); |
| 1256 LOperand* key = UseFixed(instr->key(), ecx); |
| 1235 argument_count_ -= instr->argument_count(); | 1257 argument_count_ -= instr->argument_count(); |
| 1236 LOperand* key = UseFixed(instr->key(), ecx); | 1258 LCallKeyed* result = new LCallKeyed(context, key); |
| 1237 return MarkAsCall(DefineFixed(new LCallKeyed(key), eax), instr); | 1259 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1238 } | 1260 } |
| 1239 | 1261 |
| 1240 | 1262 |
| 1241 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { | 1263 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { |
| 1264 LOperand* context = UseFixed(instr->context(), esi); |
| 1242 argument_count_ -= instr->argument_count(); | 1265 argument_count_ -= instr->argument_count(); |
| 1243 return MarkAsCall(DefineFixed(new LCallNamed, eax), instr); | 1266 LCallNamed* result = new LCallNamed(context); |
| 1267 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1244 } | 1268 } |
| 1245 | 1269 |
| 1246 | 1270 |
| 1247 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { | 1271 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { |
| 1272 LOperand* context = UseFixed(instr->context(), esi); |
| 1248 argument_count_ -= instr->argument_count(); | 1273 argument_count_ -= instr->argument_count(); |
| 1249 return MarkAsCall(DefineFixed(new LCallGlobal, eax), instr); | 1274 LCallGlobal* result = new LCallGlobal(context); |
| 1275 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1250 } | 1276 } |
| 1251 | 1277 |
| 1252 | 1278 |
| 1253 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { | 1279 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { |
| 1254 argument_count_ -= instr->argument_count(); | 1280 argument_count_ -= instr->argument_count(); |
| 1255 return MarkAsCall(DefineFixed(new LCallKnownGlobal, eax), instr); | 1281 return MarkAsCall(DefineFixed(new LCallKnownGlobal, eax), instr); |
| 1256 } | 1282 } |
| 1257 | 1283 |
| 1258 | 1284 |
| 1259 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { | 1285 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { |
| 1286 LOperand* context = UseFixed(instr->context(), esi); |
| 1260 LOperand* constructor = UseFixed(instr->constructor(), edi); | 1287 LOperand* constructor = UseFixed(instr->constructor(), edi); |
| 1261 argument_count_ -= instr->argument_count(); | 1288 argument_count_ -= instr->argument_count(); |
| 1262 LCallNew* result = new LCallNew(constructor); | 1289 LCallNew* result = new LCallNew(context, constructor); |
| 1263 return MarkAsCall(DefineFixed(result, eax), instr); | 1290 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1264 } | 1291 } |
| 1265 | 1292 |
| 1266 | 1293 |
| 1267 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { | 1294 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { |
| 1295 LOperand* context = UseFixed(instr->context(), esi); |
| 1268 argument_count_ -= instr->argument_count(); | 1296 argument_count_ -= instr->argument_count(); |
| 1269 return MarkAsCall(DefineFixed(new LCallFunction, eax), instr); | 1297 LCallFunction* result = new LCallFunction(context); |
| 1298 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1270 } | 1299 } |
| 1271 | 1300 |
| 1272 | 1301 |
| 1273 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { | 1302 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { |
| 1274 argument_count_ -= instr->argument_count(); | 1303 argument_count_ -= instr->argument_count(); |
| 1275 return MarkAsCall(DefineFixed(new LCallRuntime, eax), instr); | 1304 return MarkAsCall(DefineFixed(new LCallRuntime, eax), instr); |
| 1276 } | 1305 } |
| 1277 | 1306 |
| 1278 | 1307 |
| 1279 LInstruction* LChunkBuilder::DoShr(HShr* instr) { | 1308 LInstruction* LChunkBuilder::DoShr(HShr* instr) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1348 instr->CheckFlag(HValue::kCanBeDivByZero)) | 1377 instr->CheckFlag(HValue::kCanBeDivByZero)) |
| 1349 ? AssignEnvironment(result) | 1378 ? AssignEnvironment(result) |
| 1350 : result; | 1379 : result; |
| 1351 } else if (instr->representation().IsTagged()) { | 1380 } else if (instr->representation().IsTagged()) { |
| 1352 return DoArithmeticT(Token::MOD, instr); | 1381 return DoArithmeticT(Token::MOD, instr); |
| 1353 } else { | 1382 } else { |
| 1354 ASSERT(instr->representation().IsDouble()); | 1383 ASSERT(instr->representation().IsDouble()); |
| 1355 // We call a C function for double modulo. It can't trigger a GC. | 1384 // We call a C function for double modulo. It can't trigger a GC. |
| 1356 // We need to use fixed result register for the call. | 1385 // We need to use fixed result register for the call. |
| 1357 // TODO(fschneider): Allow any register as input registers. | 1386 // TODO(fschneider): Allow any register as input registers. |
| 1358 LOperand* left = UseFixedDouble(instr->left(), xmm1); | 1387 LOperand* left = UseFixedDouble(instr->left(), xmm2); |
| 1359 LOperand* right = UseFixedDouble(instr->right(), xmm2); | 1388 LOperand* right = UseFixedDouble(instr->right(), xmm1); |
| 1360 LArithmeticD* result = new LArithmeticD(Token::MOD, left, right); | 1389 LArithmeticD* result = new LArithmeticD(Token::MOD, left, right); |
| 1361 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); | 1390 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); |
| 1362 } | 1391 } |
| 1363 } | 1392 } |
| 1364 | 1393 |
| 1365 | 1394 |
| 1366 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1395 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
| 1367 if (instr->representation().IsInteger32()) { | 1396 if (instr->representation().IsInteger32()) { |
| 1368 ASSERT(instr->left()->representation().IsInteger32()); | 1397 ASSERT(instr->left()->representation().IsInteger32()); |
| 1369 ASSERT(instr->right()->representation().IsInteger32()); | 1398 ASSERT(instr->right()->representation().IsInteger32()); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1503 | 1532 |
| 1504 | 1533 |
| 1505 LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) { | 1534 LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) { |
| 1506 ASSERT(instr->value()->representation().IsTagged()); | 1535 ASSERT(instr->value()->representation().IsTagged()); |
| 1507 LOperand* value = UseRegisterAtStart(instr->value()); | 1536 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1508 | 1537 |
| 1509 return DefineAsRegister(new LHasInstanceType(value)); | 1538 return DefineAsRegister(new LHasInstanceType(value)); |
| 1510 } | 1539 } |
| 1511 | 1540 |
| 1512 | 1541 |
| 1542 LInstruction* LChunkBuilder::DoGetCachedArrayIndex( |
| 1543 HGetCachedArrayIndex* instr) { |
| 1544 Abort("Unimplemented: %s", "DoGetCachedArrayIndex"); |
| 1545 return NULL; |
| 1546 } |
| 1547 |
| 1548 |
| 1513 LInstruction* LChunkBuilder::DoHasCachedArrayIndex( | 1549 LInstruction* LChunkBuilder::DoHasCachedArrayIndex( |
| 1514 HHasCachedArrayIndex* instr) { | 1550 HHasCachedArrayIndex* instr) { |
| 1515 ASSERT(instr->value()->representation().IsTagged()); | 1551 ASSERT(instr->value()->representation().IsTagged()); |
| 1516 LOperand* value = UseRegister(instr->value()); | 1552 LOperand* value = UseRegister(instr->value()); |
| 1517 | 1553 |
| 1518 return DefineAsRegister(new LHasCachedArrayIndex(value)); | 1554 return DefineAsRegister(new LHasCachedArrayIndex(value)); |
| 1519 } | 1555 } |
| 1520 | 1556 |
| 1521 | 1557 |
| 1522 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) { | 1558 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) { |
| 1523 ASSERT(instr->value()->representation().IsTagged()); | 1559 ASSERT(instr->value()->representation().IsTagged()); |
| 1524 LOperand* value = UseTempRegister(instr->value()); | 1560 LOperand* value = UseTempRegister(instr->value()); |
| 1525 | 1561 |
| 1526 return DefineSameAsFirst(new LClassOfTest(value, TempRegister())); | 1562 return DefineSameAsFirst(new LClassOfTest(value, TempRegister())); |
| 1527 } | 1563 } |
| 1528 | 1564 |
| 1529 | 1565 |
| 1530 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) { | 1566 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) { |
| 1531 LOperand* array = UseRegisterAtStart(instr->value()); | 1567 LOperand* array = UseRegisterAtStart(instr->value()); |
| 1532 return DefineAsRegister(new LJSArrayLength(array)); | 1568 return DefineAsRegister(new LJSArrayLength(array)); |
| 1533 } | 1569 } |
| 1534 | 1570 |
| 1535 | 1571 |
| 1536 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { | 1572 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { |
| 1537 LOperand* array = UseRegisterAtStart(instr->value()); | 1573 LOperand* array = UseRegisterAtStart(instr->value()); |
| 1538 return DefineAsRegister(new LFixedArrayLength(array)); | 1574 return DefineAsRegister(new LFixedArrayLength(array)); |
| 1539 } | 1575 } |
| 1540 | 1576 |
| 1541 | 1577 |
| 1578 LInstruction* LChunkBuilder::DoPixelArrayLength(HPixelArrayLength* instr) { |
| 1579 LOperand* array = UseRegisterAtStart(instr->value()); |
| 1580 return DefineAsRegister(new LPixelArrayLength(array)); |
| 1581 } |
| 1582 |
| 1583 |
| 1542 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { | 1584 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { |
| 1543 LOperand* object = UseRegister(instr->value()); | 1585 LOperand* object = UseRegister(instr->value()); |
| 1544 LValueOf* result = new LValueOf(object, TempRegister()); | 1586 LValueOf* result = new LValueOf(object, TempRegister()); |
| 1545 return AssignEnvironment(DefineSameAsFirst(result)); | 1587 return AssignEnvironment(DefineSameAsFirst(result)); |
| 1546 } | 1588 } |
| 1547 | 1589 |
| 1548 | 1590 |
| 1549 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { | 1591 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { |
| 1550 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), | 1592 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), |
| 1551 Use(instr->length()))); | 1593 Use(instr->length()))); |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1729 | 1771 |
| 1730 | 1772 |
| 1731 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { | 1773 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { |
| 1732 ASSERT(instr->representation().IsTagged()); | 1774 ASSERT(instr->representation().IsTagged()); |
| 1733 LOperand* obj = UseRegisterAtStart(instr->object()); | 1775 LOperand* obj = UseRegisterAtStart(instr->object()); |
| 1734 return DefineAsRegister(new LLoadNamedField(obj)); | 1776 return DefineAsRegister(new LLoadNamedField(obj)); |
| 1735 } | 1777 } |
| 1736 | 1778 |
| 1737 | 1779 |
| 1738 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { | 1780 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { |
| 1781 LOperand* context = UseFixed(instr->context(), esi); |
| 1739 LOperand* object = UseFixed(instr->object(), eax); | 1782 LOperand* object = UseFixed(instr->object(), eax); |
| 1740 LLoadNamedGeneric* result = new LLoadNamedGeneric(object); | 1783 LLoadNamedGeneric* result = new LLoadNamedGeneric(context, object); |
| 1741 return MarkAsCall(DefineFixed(result, eax), instr); | 1784 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1742 } | 1785 } |
| 1743 | 1786 |
| 1744 | 1787 |
| 1745 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( | 1788 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( |
| 1746 HLoadFunctionPrototype* instr) { | 1789 HLoadFunctionPrototype* instr) { |
| 1747 return AssignEnvironment(DefineAsRegister( | 1790 return AssignEnvironment(DefineAsRegister( |
| 1748 new LLoadFunctionPrototype(UseRegister(instr->function()), | 1791 new LLoadFunctionPrototype(UseRegister(instr->function()), |
| 1749 TempRegister()))); | 1792 TempRegister()))); |
| 1750 } | 1793 } |
| 1751 | 1794 |
| 1752 | 1795 |
| 1753 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { | 1796 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { |
| 1754 LOperand* input = UseRegisterAtStart(instr->value()); | 1797 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1755 return DefineSameAsFirst(new LLoadElements(input)); | 1798 return DefineAsRegister(new LLoadElements(input)); |
| 1799 } |
| 1800 |
| 1801 |
| 1802 LInstruction* LChunkBuilder::DoLoadPixelArrayExternalPointer( |
| 1803 HLoadPixelArrayExternalPointer* instr) { |
| 1804 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1805 return DefineAsRegister(new LLoadPixelArrayExternalPointer(input)); |
| 1756 } | 1806 } |
| 1757 | 1807 |
| 1758 | 1808 |
| 1759 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( | 1809 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( |
| 1760 HLoadKeyedFastElement* instr) { | 1810 HLoadKeyedFastElement* instr) { |
| 1761 ASSERT(instr->representation().IsTagged()); | 1811 ASSERT(instr->representation().IsTagged()); |
| 1762 ASSERT(instr->key()->representation().IsInteger32()); | 1812 ASSERT(instr->key()->representation().IsInteger32()); |
| 1763 LOperand* obj = UseRegisterAtStart(instr->object()); | 1813 LOperand* obj = UseRegisterAtStart(instr->object()); |
| 1764 LOperand* key = UseRegisterAtStart(instr->key()); | 1814 LOperand* key = UseRegisterAtStart(instr->key()); |
| 1765 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key); | 1815 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key); |
| 1766 return AssignEnvironment(DefineSameAsFirst(result)); | 1816 return AssignEnvironment(DefineSameAsFirst(result)); |
| 1767 } | 1817 } |
| 1768 | 1818 |
| 1769 | 1819 |
| 1820 LInstruction* LChunkBuilder::DoLoadPixelArrayElement( |
| 1821 HLoadPixelArrayElement* instr) { |
| 1822 ASSERT(instr->representation().IsInteger32()); |
| 1823 ASSERT(instr->key()->representation().IsInteger32()); |
| 1824 LOperand* external_pointer = |
| 1825 UseRegisterAtStart(instr->external_pointer()); |
| 1826 LOperand* key = UseRegisterAtStart(instr->key()); |
| 1827 LLoadPixelArrayElement* result = |
| 1828 new LLoadPixelArrayElement(external_pointer, key); |
| 1829 return DefineSameAsFirst(result); |
| 1830 } |
| 1831 |
| 1832 |
| 1770 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { | 1833 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { |
| 1834 LOperand* context = UseFixed(instr->context(), esi); |
| 1771 LOperand* object = UseFixed(instr->object(), edx); | 1835 LOperand* object = UseFixed(instr->object(), edx); |
| 1772 LOperand* key = UseFixed(instr->key(), eax); | 1836 LOperand* key = UseFixed(instr->key(), eax); |
| 1773 | 1837 |
| 1774 LLoadKeyedGeneric* result = new LLoadKeyedGeneric(object, key); | 1838 LLoadKeyedGeneric* result = new LLoadKeyedGeneric(context, object, key); |
| 1775 return MarkAsCall(DefineFixed(result, eax), instr); | 1839 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1776 } | 1840 } |
| 1777 | 1841 |
| 1778 | 1842 |
| 1779 LInstruction* LChunkBuilder::DoStoreKeyedFastElement( | 1843 LInstruction* LChunkBuilder::DoStoreKeyedFastElement( |
| 1780 HStoreKeyedFastElement* instr) { | 1844 HStoreKeyedFastElement* instr) { |
| 1781 bool needs_write_barrier = instr->NeedsWriteBarrier(); | 1845 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
| 1782 ASSERT(instr->value()->representation().IsTagged()); | 1846 ASSERT(instr->value()->representation().IsTagged()); |
| 1783 ASSERT(instr->object()->representation().IsTagged()); | 1847 ASSERT(instr->object()->representation().IsTagged()); |
| 1784 ASSERT(instr->key()->representation().IsInteger32()); | 1848 ASSERT(instr->key()->representation().IsInteger32()); |
| 1785 | 1849 |
| 1786 LOperand* obj = UseTempRegister(instr->object()); | 1850 LOperand* obj = UseTempRegister(instr->object()); |
| 1787 LOperand* val = needs_write_barrier | 1851 LOperand* val = needs_write_barrier |
| 1788 ? UseTempRegister(instr->value()) | 1852 ? UseTempRegister(instr->value()) |
| 1789 : UseRegisterAtStart(instr->value()); | 1853 : UseRegisterAtStart(instr->value()); |
| 1790 LOperand* key = needs_write_barrier | 1854 LOperand* key = needs_write_barrier |
| 1791 ? UseTempRegister(instr->key()) | 1855 ? UseTempRegister(instr->key()) |
| 1792 : UseRegisterOrConstantAtStart(instr->key()); | 1856 : UseRegisterOrConstantAtStart(instr->key()); |
| 1793 | 1857 |
| 1794 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val)); | 1858 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val)); |
| 1795 } | 1859 } |
| 1796 | 1860 |
| 1797 | 1861 |
| 1862 LInstruction* LChunkBuilder::DoStorePixelArrayElement( |
| 1863 HStorePixelArrayElement* instr) { |
| 1864 ASSERT(instr->value()->representation().IsInteger32()); |
| 1865 ASSERT(instr->external_pointer()->representation().IsExternal()); |
| 1866 ASSERT(instr->key()->representation().IsInteger32()); |
| 1867 |
| 1868 LOperand* external_pointer = UseRegister(instr->external_pointer()); |
| 1869 LOperand* val = UseRegister(instr->value()); |
| 1870 LOperand* key = UseRegister(instr->key()); |
| 1871 // The generated code requires that the clamped value is in a byte |
| 1872 // register. eax is an arbitrary choice to satisfy this requirement. |
| 1873 LOperand* clamped = FixedTemp(eax); |
| 1874 |
| 1875 return new LStorePixelArrayElement(external_pointer, key, val, clamped); |
| 1876 } |
| 1877 |
| 1878 |
| 1798 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { | 1879 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { |
| 1799 LOperand* obj = UseFixed(instr->object(), edx); | 1880 LOperand* context = UseFixed(instr->context(), esi); |
| 1881 LOperand* object = UseFixed(instr->object(), edx); |
| 1800 LOperand* key = UseFixed(instr->key(), ecx); | 1882 LOperand* key = UseFixed(instr->key(), ecx); |
| 1801 LOperand* val = UseFixed(instr->value(), eax); | 1883 LOperand* value = UseFixed(instr->value(), eax); |
| 1802 | 1884 |
| 1803 ASSERT(instr->object()->representation().IsTagged()); | 1885 ASSERT(instr->object()->representation().IsTagged()); |
| 1804 ASSERT(instr->key()->representation().IsTagged()); | 1886 ASSERT(instr->key()->representation().IsTagged()); |
| 1805 ASSERT(instr->value()->representation().IsTagged()); | 1887 ASSERT(instr->value()->representation().IsTagged()); |
| 1806 | 1888 |
| 1807 return MarkAsCall(new LStoreKeyedGeneric(obj, key, val), instr); | 1889 LStoreKeyedGeneric* result = |
| 1890 new LStoreKeyedGeneric(context, object, key, value); |
| 1891 return MarkAsCall(result, instr); |
| 1808 } | 1892 } |
| 1809 | 1893 |
| 1810 | 1894 |
| 1811 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { | 1895 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { |
| 1812 bool needs_write_barrier = instr->NeedsWriteBarrier(); | 1896 bool needs_write_barrier = instr->NeedsWriteBarrier(); |
| 1813 | 1897 |
| 1814 LOperand* obj = needs_write_barrier | 1898 LOperand* obj = needs_write_barrier |
| 1815 ? UseTempRegister(instr->object()) | 1899 ? UseTempRegister(instr->object()) |
| 1816 : UseRegisterAtStart(instr->object()); | 1900 : UseRegisterAtStart(instr->object()); |
| 1817 | 1901 |
| 1818 LOperand* val = needs_write_barrier | 1902 LOperand* val = needs_write_barrier |
| 1819 ? UseTempRegister(instr->value()) | 1903 ? UseTempRegister(instr->value()) |
| 1820 : UseRegister(instr->value()); | 1904 : UseRegister(instr->value()); |
| 1821 | 1905 |
| 1822 // We only need a scratch register if we have a write barrier or we | 1906 // We only need a scratch register if we have a write barrier or we |
| 1823 // have a store into the properties array (not in-object-property). | 1907 // have a store into the properties array (not in-object-property). |
| 1824 LOperand* temp = (!instr->is_in_object() || needs_write_barrier) | 1908 LOperand* temp = (!instr->is_in_object() || needs_write_barrier) |
| 1825 ? TempRegister() | 1909 ? TempRegister() |
| 1826 : NULL; | 1910 : NULL; |
| 1827 | 1911 |
| 1828 return new LStoreNamedField(obj, val, temp); | 1912 return new LStoreNamedField(obj, val, temp); |
| 1829 } | 1913 } |
| 1830 | 1914 |
| 1831 | 1915 |
| 1832 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { | 1916 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { |
| 1833 LOperand* obj = UseFixed(instr->object(), edx); | 1917 LOperand* context = UseFixed(instr->context(), esi); |
| 1834 LOperand* val = UseFixed(instr->value(), eax); | 1918 LOperand* object = UseFixed(instr->object(), edx); |
| 1919 LOperand* value = UseFixed(instr->value(), eax); |
| 1835 | 1920 |
| 1836 LStoreNamedGeneric* result = new LStoreNamedGeneric(obj, val); | 1921 LStoreNamedGeneric* result = new LStoreNamedGeneric(context, object, value); |
| 1837 return MarkAsCall(result, instr); | 1922 return MarkAsCall(result, instr); |
| 1838 } | 1923 } |
| 1839 | 1924 |
| 1840 | 1925 |
| 1841 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { | 1926 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { |
| 1842 LOperand* string = UseRegister(instr->string()); | 1927 LOperand* string = UseRegister(instr->string()); |
| 1843 LOperand* index = UseRegisterOrConstant(instr->index()); | 1928 LOperand* index = UseRegisterOrConstant(instr->index()); |
| 1844 LStringCharCodeAt* result = new LStringCharCodeAt(string, index); | 1929 LStringCharCodeAt* result = new LStringCharCodeAt(string, index); |
| 1845 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); | 1930 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); |
| 1846 } | 1931 } |
| 1847 | 1932 |
| 1848 | 1933 |
| 1849 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { | 1934 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { |
| 1850 LOperand* string = UseRegisterAtStart(instr->value()); | 1935 LOperand* string = UseRegisterAtStart(instr->value()); |
| 1851 return DefineAsRegister(new LStringLength(string)); | 1936 return DefineAsRegister(new LStringLength(string)); |
| 1852 } | 1937 } |
| 1853 | 1938 |
| 1854 | 1939 |
| 1855 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { | 1940 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { |
| 1856 return MarkAsCall(DefineFixed(new LArrayLiteral, eax), instr); | 1941 return MarkAsCall(DefineFixed(new LArrayLiteral, eax), instr); |
| 1857 } | 1942 } |
| 1858 | 1943 |
| 1859 | 1944 |
| 1860 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { | 1945 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { |
| 1861 return MarkAsCall(DefineFixed(new LObjectLiteral, eax), instr); | 1946 LOperand* context = UseFixed(instr->context(), esi); |
| 1947 return MarkAsCall(DefineFixed(new LObjectLiteral(context), eax), instr); |
| 1862 } | 1948 } |
| 1863 | 1949 |
| 1864 | 1950 |
| 1865 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { | 1951 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { |
| 1866 return MarkAsCall(DefineFixed(new LRegExpLiteral, eax), instr); | 1952 return MarkAsCall(DefineFixed(new LRegExpLiteral, eax), instr); |
| 1867 } | 1953 } |
| 1868 | 1954 |
| 1869 | 1955 |
| 1870 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { | 1956 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { |
| 1871 return MarkAsCall(DefineFixed(new LFunctionLiteral, eax), instr); | 1957 return MarkAsCall(DefineFixed(new LFunctionLiteral, eax), instr); |
| 1872 } | 1958 } |
| 1873 | 1959 |
| 1874 | 1960 |
| 1875 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { | 1961 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { |
| 1876 LDeleteProperty* result = new LDeleteProperty(Use(instr->object()), | 1962 LDeleteProperty* result = |
| 1877 UseOrConstant(instr->key())); | 1963 new LDeleteProperty(Use(instr->object()), UseOrConstant(instr->key())); |
| 1878 return MarkAsCall(DefineFixed(result, eax), instr); | 1964 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1879 } | 1965 } |
| 1880 | 1966 |
| 1881 | 1967 |
| 1882 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { | 1968 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { |
| 1883 allocator_->MarkAsOsrEntry(); | 1969 allocator_->MarkAsOsrEntry(); |
| 1884 current_block_->last_environment()->set_ast_id(instr->ast_id()); | 1970 current_block_->last_environment()->set_ast_id(instr->ast_id()); |
| 1885 return AssignEnvironment(new LOsrEntry); | 1971 return AssignEnvironment(new LOsrEntry); |
| 1886 } | 1972 } |
| 1887 | 1973 |
| 1888 | 1974 |
| 1889 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { | 1975 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { |
| 1890 int spill_index = chunk()->GetParameterStackSlot(instr->index()); | 1976 int spill_index = chunk()->GetParameterStackSlot(instr->index()); |
| 1891 return DefineAsSpilled(new LParameter, spill_index); | 1977 return DefineAsSpilled(new LParameter, spill_index); |
| 1892 } | 1978 } |
| 1893 | 1979 |
| 1894 | 1980 |
| 1895 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { | 1981 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { |
| 1896 int spill_index = chunk()->GetNextSpillIndex(false); // Not double-width. | 1982 int spill_index = chunk()->GetNextSpillIndex(false); // Not double-width. |
| 1897 return DefineAsSpilled(new LUnknownOSRValue, spill_index); | 1983 return DefineAsSpilled(new LUnknownOSRValue, spill_index); |
| 1898 } | 1984 } |
| 1899 | 1985 |
| 1900 | 1986 |
| 1901 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { | 1987 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { |
| 1988 LOperand* context = UseFixed(instr->context(), esi); |
| 1902 argument_count_ -= instr->argument_count(); | 1989 argument_count_ -= instr->argument_count(); |
| 1903 return MarkAsCall(DefineFixed(new LCallStub, eax), instr); | 1990 LCallStub* result = new LCallStub(context); |
| 1991 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1904 } | 1992 } |
| 1905 | 1993 |
| 1906 | 1994 |
| 1907 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { | 1995 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { |
| 1908 // There are no real uses of the arguments object (we bail out in all other | 1996 // There are no real uses of the arguments object. |
| 1909 // cases). | 1997 // arguments.length and element access are supported directly on |
| 1998 // stack arguments, and any real arguments object use causes a bailout. |
| 1999 // So this value is never used. |
| 1910 return NULL; | 2000 return NULL; |
| 1911 } | 2001 } |
| 1912 | 2002 |
| 1913 | 2003 |
| 1914 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { | 2004 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { |
| 1915 LOperand* arguments = UseRegister(instr->arguments()); | 2005 LOperand* arguments = UseRegister(instr->arguments()); |
| 1916 LOperand* length = UseTempRegister(instr->length()); | 2006 LOperand* length = UseTempRegister(instr->length()); |
| 1917 LOperand* index = Use(instr->index()); | 2007 LOperand* index = Use(instr->index()); |
| 1918 LAccessArgumentsAt* result = new LAccessArgumentsAt(arguments, length, index); | 2008 LAccessArgumentsAt* result = new LAccessArgumentsAt(arguments, length, index); |
| 1919 return AssignEnvironment(DefineAsRegister(result)); | 2009 return AssignEnvironment(DefineAsRegister(result)); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1990 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 2080 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
| 1991 HEnvironment* outer = current_block_->last_environment()->outer(); | 2081 HEnvironment* outer = current_block_->last_environment()->outer(); |
| 1992 current_block_->UpdateEnvironment(outer); | 2082 current_block_->UpdateEnvironment(outer); |
| 1993 return NULL; | 2083 return NULL; |
| 1994 } | 2084 } |
| 1995 | 2085 |
| 1996 | 2086 |
| 1997 } } // namespace v8::internal | 2087 } } // namespace v8::internal |
| 1998 | 2088 |
| 1999 #endif // V8_TARGET_ARCH_IA32 | 2089 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |