| 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 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 | 397 |
| 398 if (can_eliminate) { | 398 if (can_eliminate) { |
| 399 label->set_replacement(GetLabel(goto_instr->block_id())); | 399 label->set_replacement(GetLabel(goto_instr->block_id())); |
| 400 } | 400 } |
| 401 } | 401 } |
| 402 } | 402 } |
| 403 } | 403 } |
| 404 } | 404 } |
| 405 | 405 |
| 406 | 406 |
| 407 void LStoreNamed::PrintDataTo(StringStream* stream) { | 407 void LStoreNamedField::PrintDataTo(StringStream* stream) { |
| 408 object()->PrintTo(stream); | 408 object()->PrintTo(stream); |
| 409 stream->Add("."); | 409 stream->Add("."); |
| 410 stream->Add(*String::cast(*name())->ToCString()); | 410 stream->Add(*String::cast(*name())->ToCString()); |
| 411 stream->Add(" <- "); | 411 stream->Add(" <- "); |
| 412 value()->PrintTo(stream); | 412 value()->PrintTo(stream); |
| 413 } | 413 } |
| 414 | 414 |
| 415 | 415 |
| 416 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) { |
| 417 object()->PrintTo(stream); | 426 object()->PrintTo(stream); |
| 418 stream->Add("["); | 427 stream->Add("["); |
| 419 key()->PrintTo(stream); | 428 key()->PrintTo(stream); |
| 420 stream->Add("] <- "); | 429 stream->Add("] <- "); |
| 421 value()->PrintTo(stream); | 430 value()->PrintTo(stream); |
| 422 } | 431 } |
| 423 | 432 |
| 424 | 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 |
| 425 void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { | 443 void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { |
| 426 LGap* gap = new LGap(block); | 444 LGap* gap = new LGap(block); |
| 427 int index = -1; | 445 int index = -1; |
| 428 if (instr->IsControl()) { | 446 if (instr->IsControl()) { |
| 429 instructions_.Add(gap); | 447 instructions_.Add(gap); |
| 430 index = instructions_.length(); | 448 index = instructions_.length(); |
| 431 instructions_.Add(instr); | 449 instructions_.Add(instr); |
| 432 } else { | 450 } else { |
| 433 index = instructions_.length(); | 451 index = instructions_.length(); |
| 434 instructions_.Add(instr); | 452 instructions_.Add(instr); |
| 435 instructions_.Add(gap); | 453 instructions_.Add(gap); |
| 436 } | 454 } |
| 437 if (instr->HasPointerMap()) { | 455 if (instr->HasPointerMap()) { |
| 438 pointer_maps_.Add(instr->pointer_map()); | 456 pointer_maps_.Add(instr->pointer_map()); |
| 439 instr->pointer_map()->set_lithium_position(index); | 457 instr->pointer_map()->set_lithium_position(index); |
| 440 } | 458 } |
| 441 } | 459 } |
| 442 | 460 |
| 443 | 461 |
| 444 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) { | 462 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) { |
| 445 return LConstantOperand::Create(constant->id()); | 463 return LConstantOperand::Create(constant->id()); |
| 446 } | 464 } |
| 447 | 465 |
| 448 | 466 |
| 449 int LChunk::GetParameterStackSlot(int index) const { | 467 int LChunk::GetParameterStackSlot(int index) const { |
| 450 // The receiver is at index 0, the first parameter at index 1, so we | 468 // The receiver is at index 0, the first parameter at index 1, so we |
| 451 // shift all parameter indexes down by the number of parameters, and | 469 // shift all parameter indexes down by the number of parameters, and |
| 452 // make sure they end up negative so they are distinguishable from | 470 // make sure they end up negative so they are distinguishable from |
| 453 // spill slots. | 471 // spill slots. |
| 454 int result = index - graph()->info()->scope()->num_parameters() - 1; | 472 int result = index - info()->scope()->num_parameters() - 1; |
| 455 ASSERT(result < 0); | 473 ASSERT(result < 0); |
| 456 return result; | 474 return result; |
| 457 } | 475 } |
| 458 | 476 |
| 459 // A parameter relative to ebp in the arguments stub. | 477 // A parameter relative to ebp in the arguments stub. |
| 460 int LChunk::ParameterAt(int index) { | 478 int LChunk::ParameterAt(int index) { |
| 461 ASSERT(-1 <= index); // -1 is the receiver. | 479 ASSERT(-1 <= index); // -1 is the receiver. |
| 462 return (1 + graph()->info()->scope()->num_parameters() - index) * | 480 return (1 + info()->scope()->num_parameters() - index) * |
| 463 kPointerSize; | 481 kPointerSize; |
| 464 } | 482 } |
| 465 | 483 |
| 466 | 484 |
| 467 LGap* LChunk::GetGapAt(int index) const { | 485 LGap* LChunk::GetGapAt(int index) const { |
| 468 return LGap::cast(instructions_[index]); | 486 return LGap::cast(instructions_[index]); |
| 469 } | 487 } |
| 470 | 488 |
| 471 | 489 |
| 472 bool LChunk::IsGapAt(int index) const { | 490 bool LChunk::IsGapAt(int index) const { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 491 | 509 |
| 492 | 510 |
| 493 Representation LChunk::LookupLiteralRepresentation( | 511 Representation LChunk::LookupLiteralRepresentation( |
| 494 LConstantOperand* operand) const { | 512 LConstantOperand* operand) const { |
| 495 return graph_->LookupValue(operand->index())->representation(); | 513 return graph_->LookupValue(operand->index())->representation(); |
| 496 } | 514 } |
| 497 | 515 |
| 498 | 516 |
| 499 LChunk* LChunkBuilder::Build() { | 517 LChunk* LChunkBuilder::Build() { |
| 500 ASSERT(is_unused()); | 518 ASSERT(is_unused()); |
| 501 chunk_ = new LChunk(graph()); | 519 chunk_ = new LChunk(info(), graph()); |
| 502 HPhase phase("Building chunk", chunk_); | 520 HPhase phase("Building chunk", chunk_); |
| 503 status_ = BUILDING; | 521 status_ = BUILDING; |
| 504 const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); | 522 const ZoneList<HBasicBlock*>* blocks = graph()->blocks(); |
| 505 for (int i = 0; i < blocks->length(); i++) { | 523 for (int i = 0; i < blocks->length(); i++) { |
| 506 HBasicBlock* next = NULL; | 524 HBasicBlock* next = NULL; |
| 507 if (i < blocks->length() - 1) next = blocks->at(i + 1); | 525 if (i < blocks->length() - 1) next = blocks->at(i + 1); |
| 508 DoBasicBlock(blocks->at(i), next); | 526 DoBasicBlock(blocks->at(i), next); |
| 509 if (is_aborted()) return NULL; | 527 if (is_aborted()) return NULL; |
| 510 } | 528 } |
| 511 status_ = DONE; | 529 status_ = DONE; |
| 512 return chunk_; | 530 return chunk_; |
| 513 } | 531 } |
| 514 | 532 |
| 515 | 533 |
| 516 void LChunkBuilder::Abort(const char* format, ...) { | 534 void LChunkBuilder::Abort(const char* format, ...) { |
| 517 if (FLAG_trace_bailout) { | 535 if (FLAG_trace_bailout) { |
| 518 SmartPointer<char> debug_name = graph()->debug_name()->ToCString(); | 536 SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString()); |
| 519 PrintF("Aborting LChunk building in @\"%s\": ", *debug_name); | 537 PrintF("Aborting LChunk building in @\"%s\": ", *name); |
| 520 va_list arguments; | 538 va_list arguments; |
| 521 va_start(arguments, format); | 539 va_start(arguments, format); |
| 522 OS::VPrint(format, arguments); | 540 OS::VPrint(format, arguments); |
| 523 va_end(arguments); | 541 va_end(arguments); |
| 524 PrintF("\n"); | 542 PrintF("\n"); |
| 525 } | 543 } |
| 526 status_ = ABORTED; | 544 status_ = ABORTED; |
| 527 } | 545 } |
| 528 | 546 |
| 529 | 547 |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 845 ? AssignEnvironment(DefineSameAsFirst(result)) | 863 ? AssignEnvironment(DefineSameAsFirst(result)) |
| 846 : DefineSameAsFirst(result); | 864 : DefineSameAsFirst(result); |
| 847 } | 865 } |
| 848 | 866 |
| 849 | 867 |
| 850 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, | 868 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, |
| 851 HArithmeticBinaryOperation* instr) { | 869 HArithmeticBinaryOperation* instr) { |
| 852 ASSERT(instr->representation().IsDouble()); | 870 ASSERT(instr->representation().IsDouble()); |
| 853 ASSERT(instr->left()->representation().IsDouble()); | 871 ASSERT(instr->left()->representation().IsDouble()); |
| 854 ASSERT(instr->right()->representation().IsDouble()); | 872 ASSERT(instr->right()->representation().IsDouble()); |
| 873 ASSERT(op != Token::MOD); |
| 855 LOperand* left = UseRegisterAtStart(instr->left()); | 874 LOperand* left = UseRegisterAtStart(instr->left()); |
| 856 LOperand* right = UseRegisterAtStart(instr->right()); | 875 LOperand* right = UseRegisterAtStart(instr->right()); |
| 857 LArithmeticD* result = new LArithmeticD(op, left, right); | 876 LArithmeticD* result = new LArithmeticD(op, left, right); |
| 858 return DefineSameAsFirst(result); | 877 return DefineSameAsFirst(result); |
| 859 } | 878 } |
| 860 | 879 |
| 861 | 880 |
| 862 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, | 881 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, |
| 863 HArithmeticBinaryOperation* instr) { | 882 HArithmeticBinaryOperation* instr) { |
| 864 ASSERT(op == Token::ADD || | 883 ASSERT(op == Token::ADD || |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 = UseFixed(instr->length(), ebx); | 1176 LOperand* length = UseFixed(instr->length(), ebx); |
| 1159 LOperand* elements = UseFixed(instr->elements(), ecx); | 1177 LOperand* elements = UseFixed(instr->elements(), ecx); |
| 1160 LOperand* temp = FixedTemp(edx); | 1178 LOperand* temp = FixedTemp(edx); |
| 1161 LApplyArguments* result = new LApplyArguments(function, | 1179 LApplyArguments* result = new LApplyArguments(function, |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1216 switch (op) { | 1234 switch (op) { |
| 1217 case kMathAbs: | 1235 case kMathAbs: |
| 1218 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); | 1236 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); |
| 1219 case kMathFloor: | 1237 case kMathFloor: |
| 1220 return AssignEnvironment(DefineAsRegister(result)); | 1238 return AssignEnvironment(DefineAsRegister(result)); |
| 1221 case kMathRound: | 1239 case kMathRound: |
| 1222 return AssignEnvironment(DefineAsRegister(result)); | 1240 return AssignEnvironment(DefineAsRegister(result)); |
| 1223 case kMathSqrt: | 1241 case kMathSqrt: |
| 1224 return DefineSameAsFirst(result); | 1242 return DefineSameAsFirst(result); |
| 1225 case kMathPowHalf: | 1243 case kMathPowHalf: |
| 1226 return AssignEnvironment(DefineSameAsFirst(result)); | 1244 return DefineSameAsFirst(result); |
| 1227 default: | 1245 default: |
| 1228 UNREACHABLE(); | 1246 UNREACHABLE(); |
| 1229 return NULL; | 1247 return NULL; |
| 1230 } | 1248 } |
| 1231 } | 1249 } |
| 1232 } | 1250 } |
| 1233 | 1251 |
| 1234 | 1252 |
| 1235 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { | 1253 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { |
| 1236 ASSERT(instr->key()->representation().IsTagged()); | 1254 ASSERT(instr->key()->representation().IsTagged()); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1341 ASSERT(instr->representation().IsTagged()); | 1359 ASSERT(instr->representation().IsTagged()); |
| 1342 return DoArithmeticT(Token::DIV, instr); | 1360 return DoArithmeticT(Token::DIV, instr); |
| 1343 } | 1361 } |
| 1344 } | 1362 } |
| 1345 | 1363 |
| 1346 | 1364 |
| 1347 LInstruction* LChunkBuilder::DoMod(HMod* instr) { | 1365 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
| 1348 if (instr->representation().IsInteger32()) { | 1366 if (instr->representation().IsInteger32()) { |
| 1349 ASSERT(instr->left()->representation().IsInteger32()); | 1367 ASSERT(instr->left()->representation().IsInteger32()); |
| 1350 ASSERT(instr->right()->representation().IsInteger32()); | 1368 ASSERT(instr->right()->representation().IsInteger32()); |
| 1351 // The temporary operand is necessary to ensure that right is not allocated | 1369 |
| 1352 // into edx. | 1370 LInstruction* result; |
| 1353 LOperand* temp = FixedTemp(edx); | 1371 if (instr->HasPowerOf2Divisor()) { |
| 1354 LOperand* value = UseFixed(instr->left(), eax); | 1372 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); |
| 1355 LOperand* divisor = UseRegister(instr->right()); | 1373 LOperand* value = UseRegisterAtStart(instr->left()); |
| 1356 LModI* mod = new LModI(value, divisor, temp); | 1374 LModI* mod = new LModI(value, UseOrConstant(instr->right()), NULL); |
| 1357 LInstruction* result = DefineFixed(mod, edx); | 1375 result = DefineSameAsFirst(mod); |
| 1376 } else { |
| 1377 // The temporary operand is necessary to ensure that right is |
| 1378 // not allocated into edx. |
| 1379 LOperand* temp = FixedTemp(edx); |
| 1380 LOperand* value = UseFixed(instr->left(), eax); |
| 1381 LOperand* divisor = UseRegister(instr->right()); |
| 1382 LModI* mod = new LModI(value, divisor, temp); |
| 1383 result = DefineFixed(mod, edx); |
| 1384 } |
| 1385 |
| 1358 return (instr->CheckFlag(HValue::kBailoutOnMinusZero) || | 1386 return (instr->CheckFlag(HValue::kBailoutOnMinusZero) || |
| 1359 instr->CheckFlag(HValue::kCanBeDivByZero)) | 1387 instr->CheckFlag(HValue::kCanBeDivByZero)) |
| 1360 ? AssignEnvironment(result) | 1388 ? AssignEnvironment(result) |
| 1361 : result; | 1389 : result; |
| 1362 } else if (instr->representation().IsTagged()) { | 1390 } else if (instr->representation().IsTagged()) { |
| 1363 return DoArithmeticT(Token::MOD, instr); | 1391 return DoArithmeticT(Token::MOD, instr); |
| 1364 } else { | 1392 } else { |
| 1365 ASSERT(instr->representation().IsDouble()); | 1393 ASSERT(instr->representation().IsDouble()); |
| 1366 // We call a C function for double modulo. It can't trigger a GC. | 1394 // We call a C function for double modulo. It can't trigger a GC. |
| 1367 // We need to use fixed result register for the call. | 1395 // We need to use fixed result register for the call. |
| 1368 // TODO(fschneider): Allow any register as input registers. | 1396 // TODO(fschneider): Allow any register as input registers. |
| 1369 LOperand* left = UseFixedDouble(instr->left(), xmm1); | 1397 LOperand* left = UseFixedDouble(instr->left(), xmm2); |
| 1370 LOperand* right = UseFixedDouble(instr->right(), xmm2); | 1398 LOperand* right = UseFixedDouble(instr->right(), xmm1); |
| 1371 LArithmeticD* result = new LArithmeticD(Token::MOD, left, right); | 1399 LArithmeticD* result = new LArithmeticD(Token::MOD, left, right); |
| 1372 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); | 1400 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); |
| 1373 } | 1401 } |
| 1374 } | 1402 } |
| 1375 | 1403 |
| 1376 | 1404 |
| 1377 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1405 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
| 1378 if (instr->representation().IsInteger32()) { | 1406 if (instr->representation().IsInteger32()) { |
| 1379 ASSERT(instr->left()->representation().IsInteger32()); | 1407 ASSERT(instr->left()->representation().IsInteger32()); |
| 1380 ASSERT(instr->right()->representation().IsInteger32()); | 1408 ASSERT(instr->right()->representation().IsInteger32()); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1514 | 1542 |
| 1515 | 1543 |
| 1516 LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) { | 1544 LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) { |
| 1517 ASSERT(instr->value()->representation().IsTagged()); | 1545 ASSERT(instr->value()->representation().IsTagged()); |
| 1518 LOperand* value = UseRegisterAtStart(instr->value()); | 1546 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1519 | 1547 |
| 1520 return DefineAsRegister(new LHasInstanceType(value)); | 1548 return DefineAsRegister(new LHasInstanceType(value)); |
| 1521 } | 1549 } |
| 1522 | 1550 |
| 1523 | 1551 |
| 1552 LInstruction* LChunkBuilder::DoGetCachedArrayIndex( |
| 1553 HGetCachedArrayIndex* instr) { |
| 1554 ASSERT(instr->value()->representation().IsTagged()); |
| 1555 LOperand* value = UseRegisterAtStart(instr->value()); |
| 1556 |
| 1557 return DefineAsRegister(new LGetCachedArrayIndex(value)); |
| 1558 } |
| 1559 |
| 1560 |
| 1524 LInstruction* LChunkBuilder::DoHasCachedArrayIndex( | 1561 LInstruction* LChunkBuilder::DoHasCachedArrayIndex( |
| 1525 HHasCachedArrayIndex* instr) { | 1562 HHasCachedArrayIndex* instr) { |
| 1526 ASSERT(instr->value()->representation().IsTagged()); | 1563 ASSERT(instr->value()->representation().IsTagged()); |
| 1527 LOperand* value = UseRegister(instr->value()); | 1564 LOperand* value = UseRegister(instr->value()); |
| 1528 | 1565 |
| 1529 return DefineAsRegister(new LHasCachedArrayIndex(value)); | 1566 return DefineAsRegister(new LHasCachedArrayIndex(value)); |
| 1530 } | 1567 } |
| 1531 | 1568 |
| 1532 | 1569 |
| 1533 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) { | 1570 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) { |
| 1534 ASSERT(instr->value()->representation().IsTagged()); | 1571 ASSERT(instr->value()->representation().IsTagged()); |
| 1535 LOperand* value = UseTempRegister(instr->value()); | 1572 LOperand* value = UseTempRegister(instr->value()); |
| 1536 | 1573 |
| 1537 return DefineSameAsFirst(new LClassOfTest(value, TempRegister())); | 1574 return DefineSameAsFirst(new LClassOfTest(value, TempRegister())); |
| 1538 } | 1575 } |
| 1539 | 1576 |
| 1540 | 1577 |
| 1541 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) { | 1578 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) { |
| 1542 LOperand* array = UseRegisterAtStart(instr->value()); | 1579 LOperand* array = UseRegisterAtStart(instr->value()); |
| 1543 return DefineAsRegister(new LJSArrayLength(array)); | 1580 return DefineAsRegister(new LJSArrayLength(array)); |
| 1544 } | 1581 } |
| 1545 | 1582 |
| 1546 | 1583 |
| 1547 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { | 1584 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { |
| 1548 LOperand* array = UseRegisterAtStart(instr->value()); | 1585 LOperand* array = UseRegisterAtStart(instr->value()); |
| 1549 return DefineAsRegister(new LFixedArrayLength(array)); | 1586 return DefineAsRegister(new LFixedArrayLength(array)); |
| 1550 } | 1587 } |
| 1551 | 1588 |
| 1552 | 1589 |
| 1553 LInstruction* LChunkBuilder::DoPixelArrayLength(HPixelArrayLength* instr) { | 1590 LInstruction* LChunkBuilder::DoExternalArrayLength( |
| 1591 HExternalArrayLength* instr) { |
| 1554 LOperand* array = UseRegisterAtStart(instr->value()); | 1592 LOperand* array = UseRegisterAtStart(instr->value()); |
| 1555 return DefineAsRegister(new LPixelArrayLength(array)); | 1593 return DefineAsRegister(new LExternalArrayLength(array)); |
| 1556 } | 1594 } |
| 1557 | 1595 |
| 1558 | 1596 |
| 1559 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { | 1597 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { |
| 1560 LOperand* object = UseRegister(instr->value()); | 1598 LOperand* object = UseRegister(instr->value()); |
| 1561 LValueOf* result = new LValueOf(object, TempRegister()); | 1599 LValueOf* result = new LValueOf(object, TempRegister()); |
| 1562 return AssignEnvironment(DefineSameAsFirst(result)); | 1600 return AssignEnvironment(DefineSameAsFirst(result)); |
| 1563 } | 1601 } |
| 1564 | 1602 |
| 1565 | 1603 |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1768 TempRegister()))); | 1806 TempRegister()))); |
| 1769 } | 1807 } |
| 1770 | 1808 |
| 1771 | 1809 |
| 1772 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { | 1810 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { |
| 1773 LOperand* input = UseRegisterAtStart(instr->value()); | 1811 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1774 return DefineAsRegister(new LLoadElements(input)); | 1812 return DefineAsRegister(new LLoadElements(input)); |
| 1775 } | 1813 } |
| 1776 | 1814 |
| 1777 | 1815 |
| 1778 LInstruction* LChunkBuilder::DoLoadPixelArrayExternalPointer( | 1816 LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( |
| 1779 HLoadPixelArrayExternalPointer* instr) { | 1817 HLoadExternalArrayPointer* instr) { |
| 1780 LOperand* input = UseRegisterAtStart(instr->value()); | 1818 LOperand* input = UseRegisterAtStart(instr->value()); |
| 1781 return DefineAsRegister(new LLoadPixelArrayExternalPointer(input)); | 1819 return DefineAsRegister(new LLoadExternalArrayPointer(input)); |
| 1782 } | 1820 } |
| 1783 | 1821 |
| 1784 | 1822 |
| 1785 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( | 1823 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( |
| 1786 HLoadKeyedFastElement* instr) { | 1824 HLoadKeyedFastElement* instr) { |
| 1787 ASSERT(instr->representation().IsTagged()); | 1825 ASSERT(instr->representation().IsTagged()); |
| 1788 ASSERT(instr->key()->representation().IsInteger32()); | 1826 ASSERT(instr->key()->representation().IsInteger32()); |
| 1789 LOperand* obj = UseRegisterAtStart(instr->object()); | 1827 LOperand* obj = UseRegisterAtStart(instr->object()); |
| 1790 LOperand* key = UseRegisterAtStart(instr->key()); | 1828 LOperand* key = UseRegisterAtStart(instr->key()); |
| 1791 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key); | 1829 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1828 ? UseTempRegister(instr->value()) | 1866 ? UseTempRegister(instr->value()) |
| 1829 : UseRegisterAtStart(instr->value()); | 1867 : UseRegisterAtStart(instr->value()); |
| 1830 LOperand* key = needs_write_barrier | 1868 LOperand* key = needs_write_barrier |
| 1831 ? UseTempRegister(instr->key()) | 1869 ? UseTempRegister(instr->key()) |
| 1832 : UseRegisterOrConstantAtStart(instr->key()); | 1870 : UseRegisterOrConstantAtStart(instr->key()); |
| 1833 | 1871 |
| 1834 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val)); | 1872 return AssignEnvironment(new LStoreKeyedFastElement(obj, key, val)); |
| 1835 } | 1873 } |
| 1836 | 1874 |
| 1837 | 1875 |
| 1876 LInstruction* LChunkBuilder::DoStorePixelArrayElement( |
| 1877 HStorePixelArrayElement* instr) { |
| 1878 ASSERT(instr->value()->representation().IsInteger32()); |
| 1879 ASSERT(instr->external_pointer()->representation().IsExternal()); |
| 1880 ASSERT(instr->key()->representation().IsInteger32()); |
| 1881 |
| 1882 LOperand* external_pointer = UseRegister(instr->external_pointer()); |
| 1883 LOperand* val = UseRegister(instr->value()); |
| 1884 LOperand* key = UseRegister(instr->key()); |
| 1885 // The generated code requires that the clamped value is in a byte |
| 1886 // register. eax is an arbitrary choice to satisfy this requirement. |
| 1887 LOperand* clamped = FixedTemp(eax); |
| 1888 |
| 1889 return new LStorePixelArrayElement(external_pointer, key, val, clamped); |
| 1890 } |
| 1891 |
| 1892 |
| 1838 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { | 1893 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { |
| 1839 LOperand* context = UseFixed(instr->context(), esi); | 1894 LOperand* context = UseFixed(instr->context(), esi); |
| 1840 LOperand* object = UseFixed(instr->object(), edx); | 1895 LOperand* object = UseFixed(instr->object(), edx); |
| 1841 LOperand* key = UseFixed(instr->key(), ecx); | 1896 LOperand* key = UseFixed(instr->key(), ecx); |
| 1842 LOperand* value = UseFixed(instr->value(), eax); | 1897 LOperand* value = UseFixed(instr->value(), eax); |
| 1843 | 1898 |
| 1844 ASSERT(instr->object()->representation().IsTagged()); | 1899 ASSERT(instr->object()->representation().IsTagged()); |
| 1845 ASSERT(instr->key()->representation().IsTagged()); | 1900 ASSERT(instr->key()->representation().IsTagged()); |
| 1846 ASSERT(instr->value()->representation().IsTagged()); | 1901 ASSERT(instr->value()->representation().IsTagged()); |
| 1847 | 1902 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1883 | 1938 |
| 1884 | 1939 |
| 1885 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { | 1940 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { |
| 1886 LOperand* string = UseRegister(instr->string()); | 1941 LOperand* string = UseRegister(instr->string()); |
| 1887 LOperand* index = UseRegisterOrConstant(instr->index()); | 1942 LOperand* index = UseRegisterOrConstant(instr->index()); |
| 1888 LStringCharCodeAt* result = new LStringCharCodeAt(string, index); | 1943 LStringCharCodeAt* result = new LStringCharCodeAt(string, index); |
| 1889 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); | 1944 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); |
| 1890 } | 1945 } |
| 1891 | 1946 |
| 1892 | 1947 |
| 1948 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) { |
| 1949 LOperand* char_code = UseRegister(instr->value()); |
| 1950 LStringCharFromCode* result = new LStringCharFromCode(char_code); |
| 1951 return AssignPointerMap(DefineAsRegister(result)); |
| 1952 } |
| 1953 |
| 1954 |
| 1893 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { | 1955 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { |
| 1894 LOperand* string = UseRegisterAtStart(instr->value()); | 1956 LOperand* string = UseRegisterAtStart(instr->value()); |
| 1895 return DefineAsRegister(new LStringLength(string)); | 1957 return DefineAsRegister(new LStringLength(string)); |
| 1896 } | 1958 } |
| 1897 | 1959 |
| 1898 | 1960 |
| 1899 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { | 1961 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { |
| 1900 return MarkAsCall(DefineFixed(new LArrayLiteral, eax), instr); | 1962 return MarkAsCall(DefineFixed(new LArrayLiteral, eax), instr); |
| 1901 } | 1963 } |
| 1902 | 1964 |
| 1903 | 1965 |
| 1904 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { | 1966 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { |
| 1905 LOperand* context = UseFixed(instr->context(), esi); | 1967 LOperand* context = UseFixed(instr->context(), esi); |
| 1906 return MarkAsCall(DefineFixed(new LObjectLiteral(context), eax), instr); | 1968 return MarkAsCall(DefineFixed(new LObjectLiteral(context), eax), instr); |
| 1907 } | 1969 } |
| 1908 | 1970 |
| 1909 | 1971 |
| 1910 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { | 1972 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { |
| 1911 return MarkAsCall(DefineFixed(new LRegExpLiteral, eax), instr); | 1973 return MarkAsCall(DefineFixed(new LRegExpLiteral, eax), instr); |
| 1912 } | 1974 } |
| 1913 | 1975 |
| 1914 | 1976 |
| 1915 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { | 1977 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { |
| 1916 return MarkAsCall(DefineFixed(new LFunctionLiteral, eax), instr); | 1978 return MarkAsCall(DefineFixed(new LFunctionLiteral, eax), instr); |
| 1917 } | 1979 } |
| 1918 | 1980 |
| 1919 | 1981 |
| 1920 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { | 1982 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { |
| 1921 LDeleteProperty* result = new LDeleteProperty(Use(instr->object()), | 1983 LDeleteProperty* result = |
| 1922 UseOrConstant(instr->key())); | 1984 new LDeleteProperty(Use(instr->object()), UseOrConstant(instr->key())); |
| 1923 return MarkAsCall(DefineFixed(result, eax), instr); | 1985 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1924 } | 1986 } |
| 1925 | 1987 |
| 1926 | 1988 |
| 1927 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { | 1989 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { |
| 1928 allocator_->MarkAsOsrEntry(); | 1990 allocator_->MarkAsOsrEntry(); |
| 1929 current_block_->last_environment()->set_ast_id(instr->ast_id()); | 1991 current_block_->last_environment()->set_ast_id(instr->ast_id()); |
| 1930 return AssignEnvironment(new LOsrEntry); | 1992 return AssignEnvironment(new LOsrEntry); |
| 1931 } | 1993 } |
| 1932 | 1994 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1945 | 2007 |
| 1946 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { | 2008 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { |
| 1947 LOperand* context = UseFixed(instr->context(), esi); | 2009 LOperand* context = UseFixed(instr->context(), esi); |
| 1948 argument_count_ -= instr->argument_count(); | 2010 argument_count_ -= instr->argument_count(); |
| 1949 LCallStub* result = new LCallStub(context); | 2011 LCallStub* result = new LCallStub(context); |
| 1950 return MarkAsCall(DefineFixed(result, eax), instr); | 2012 return MarkAsCall(DefineFixed(result, eax), instr); |
| 1951 } | 2013 } |
| 1952 | 2014 |
| 1953 | 2015 |
| 1954 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { | 2016 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { |
| 1955 // There are no real uses of the arguments object (we bail out in all other | 2017 // There are no real uses of the arguments object. |
| 1956 // cases). | 2018 // arguments.length and element access are supported directly on |
| 2019 // stack arguments, and any real arguments object use causes a bailout. |
| 2020 // So this value is never used. |
| 1957 return NULL; | 2021 return NULL; |
| 1958 } | 2022 } |
| 1959 | 2023 |
| 1960 | 2024 |
| 1961 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { | 2025 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { |
| 1962 LOperand* arguments = UseRegister(instr->arguments()); | 2026 LOperand* arguments = UseRegister(instr->arguments()); |
| 1963 LOperand* length = UseTempRegister(instr->length()); | 2027 LOperand* length = UseTempRegister(instr->length()); |
| 1964 LOperand* index = Use(instr->index()); | 2028 LOperand* index = Use(instr->index()); |
| 1965 LAccessArgumentsAt* result = new LAccessArgumentsAt(arguments, length, index); | 2029 LAccessArgumentsAt* result = new LAccessArgumentsAt(arguments, length, index); |
| 1966 return AssignEnvironment(DefineAsRegister(result)); | 2030 return AssignEnvironment(DefineAsRegister(result)); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2037 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { | 2101 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { |
| 2038 HEnvironment* outer = current_block_->last_environment()->outer(); | 2102 HEnvironment* outer = current_block_->last_environment()->outer(); |
| 2039 current_block_->UpdateEnvironment(outer); | 2103 current_block_->UpdateEnvironment(outer); |
| 2040 return NULL; | 2104 return NULL; |
| 2041 } | 2105 } |
| 2042 | 2106 |
| 2043 | 2107 |
| 2044 } } // namespace v8::internal | 2108 } } // namespace v8::internal |
| 2045 | 2109 |
| 2046 #endif // V8_TARGET_ARCH_IA32 | 2110 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |