| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 codegen_->RecordSafepoint(pointers_, deopt_mode_); | 57 codegen_->RecordSafepoint(pointers_, deopt_mode_); |
| 58 } | 58 } |
| 59 | 59 |
| 60 private: | 60 private: |
| 61 LCodeGen* codegen_; | 61 LCodeGen* codegen_; |
| 62 LPointerMap* pointers_; | 62 LPointerMap* pointers_; |
| 63 Safepoint::DeoptMode deopt_mode_; | 63 Safepoint::DeoptMode deopt_mode_; |
| 64 }; | 64 }; |
| 65 | 65 |
| 66 | 66 |
| 67 class LithiumSmiInstructionWrapper |
| 68 : public MacroAssembler::SmiInstructionWrapper { |
| 69 public: |
| 70 LithiumSmiInstructionWrapper(LCodeGen* codegen, |
| 71 LEnvironment* environment, |
| 72 bool check_overflow = false, |
| 73 bool check_minus_zero = false) |
| 74 : codegen_(codegen), |
| 75 environment_(environment), |
| 76 check_overflow_(check_overflow), |
| 77 check_minus_zero_(check_minus_zero) { } |
| 78 virtual ~LithiumSmiInstructionWrapper() { } |
| 79 virtual bool NeedsCheckOverflow() const { return check_overflow_; } |
| 80 virtual bool NeedsCheckMinusZero() const { return check_minus_zero_; } |
| 81 virtual bool NeedsKeepSourceOperandsIntact() const { return false; } |
| 82 virtual void BailoutIf(Condition cc) const { |
| 83 codegen_->DeoptimizeIf(cc, environment_); |
| 84 } |
| 85 |
| 86 private: |
| 87 LCodeGen* codegen_; |
| 88 LEnvironment* environment_; |
| 89 bool check_overflow_; |
| 90 bool check_minus_zero_; |
| 91 }; |
| 92 |
| 93 |
| 67 #define __ masm()-> | 94 #define __ masm()-> |
| 68 | 95 |
| 69 bool LCodeGen::GenerateCode() { | 96 bool LCodeGen::GenerateCode() { |
| 70 LPhase phase("Z_Code generation", chunk()); | 97 LPhase phase("Z_Code generation", chunk()); |
| 71 ASSERT(is_unused()); | 98 ASSERT(is_unused()); |
| 72 status_ = GENERATING; | 99 status_ = GENERATING; |
| 73 | 100 |
| 74 // Open a frame scope to indicate that there is a frame on the stack. The | 101 // Open a frame scope to indicate that there is a frame on the stack. The |
| 75 // MANUAL indicates that the scope shouldn't actually generate code to set up | 102 // MANUAL indicates that the scope shouldn't actually generate code to set up |
| 76 // the frame (that is done in GeneratePrologue). | 103 // the frame (that is done in GeneratePrologue). |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 409 } | 436 } |
| 410 | 437 |
| 411 | 438 |
| 412 bool LCodeGen::IsTaggedConstant(LConstantOperand* op) const { | 439 bool LCodeGen::IsTaggedConstant(LConstantOperand* op) const { |
| 413 return op->IsConstantOperand() && | 440 return op->IsConstantOperand() && |
| 414 chunk_->LookupLiteralRepresentation(op).IsTagged(); | 441 chunk_->LookupLiteralRepresentation(op).IsTagged(); |
| 415 } | 442 } |
| 416 | 443 |
| 417 | 444 |
| 418 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const { | 445 int32_t LCodeGen::ToInteger32(LConstantOperand* op) const { |
| 419 HConstant* constant = chunk_->LookupConstant(op); | 446 return ToRepresentation(op, Representation::Integer32()); |
| 420 return constant->Integer32Value(); | |
| 421 } | 447 } |
| 422 | 448 |
| 423 | 449 |
| 450 int32_t LCodeGen::ToRepresentation(LConstantOperand* op, |
| 451 const Representation& r) const { |
| 452 HConstant* constant = chunk_->LookupConstant(op); |
| 453 int32_t value = constant->Integer32Value(); |
| 454 if (r.IsInteger32()) return value; |
| 455 ASSERT(r.IsSmiOrTagged()); |
| 456 return static_cast<int32_t>(reinterpret_cast<intptr_t>(Smi::FromInt(value))); |
| 457 } |
| 458 |
| 459 |
| 424 Smi* LCodeGen::ToSmi(LConstantOperand* op) const { | 460 Smi* LCodeGen::ToSmi(LConstantOperand* op) const { |
| 425 HConstant* constant = chunk_->LookupConstant(op); | 461 HConstant* constant = chunk_->LookupConstant(op); |
| 426 return Smi::FromInt(constant->Integer32Value()); | 462 return Smi::FromInt(constant->Integer32Value()); |
| 427 } | 463 } |
| 428 | 464 |
| 429 | 465 |
| 430 double LCodeGen::ToDouble(LConstantOperand* op) const { | 466 double LCodeGen::ToDouble(LConstantOperand* op) const { |
| 431 HConstant* constant = chunk_->LookupConstant(op); | 467 HConstant* constant = chunk_->LookupConstant(op); |
| 432 ASSERT(constant->HasDoubleValue()); | 468 ASSERT(constant->HasDoubleValue()); |
| 433 return constant->DoubleValue(); | 469 return constant->DoubleValue(); |
| (...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1355 } | 1391 } |
| 1356 | 1392 |
| 1357 | 1393 |
| 1358 void LCodeGen::DoBitI(LBitI* instr) { | 1394 void LCodeGen::DoBitI(LBitI* instr) { |
| 1359 LOperand* left = instr->left(); | 1395 LOperand* left = instr->left(); |
| 1360 LOperand* right = instr->right(); | 1396 LOperand* right = instr->right(); |
| 1361 ASSERT(left->Equals(instr->result())); | 1397 ASSERT(left->Equals(instr->result())); |
| 1362 ASSERT(left->IsRegister()); | 1398 ASSERT(left->IsRegister()); |
| 1363 | 1399 |
| 1364 if (right->IsConstantOperand()) { | 1400 if (right->IsConstantOperand()) { |
| 1365 int right_operand = ToInteger32(LConstantOperand::cast(right)); | 1401 int32_t right_value = ToInteger32(LConstantOperand::cast(right)); |
| 1366 switch (instr->op()) { | 1402 switch (instr->op()) { |
| 1367 case Token::BIT_AND: | 1403 case Token::BIT_AND: |
| 1368 __ andl(ToRegister(left), Immediate(right_operand)); | 1404 if (instr->hydrogen()->representation().IsSmi()) { |
| 1405 __ SmiAndConstant(ToRegister(left), ToRegister(left), |
| 1406 Smi::FromInt(right_value)); |
| 1407 } else { |
| 1408 __ andl(ToRegister(left), Immediate(right_value)); |
| 1409 } |
| 1369 break; | 1410 break; |
| 1370 case Token::BIT_OR: | 1411 case Token::BIT_OR: |
| 1371 __ orl(ToRegister(left), Immediate(right_operand)); | 1412 if (instr->hydrogen()->representation().IsSmi()) { |
| 1413 __ SmiOrConstant(ToRegister(left), ToRegister(left), |
| 1414 Smi::FromInt(right_value)); |
| 1415 } else { |
| 1416 __ orl(ToRegister(left), Immediate(right_value)); |
| 1417 } |
| 1372 break; | 1418 break; |
| 1373 case Token::BIT_XOR: | 1419 case Token::BIT_XOR: |
| 1374 __ xorl(ToRegister(left), Immediate(right_operand)); | 1420 if (instr->hydrogen()->representation().IsSmi()) { |
| 1421 __ SmiXorConstant(ToRegister(left), ToRegister(left), |
| 1422 Smi::FromInt(right_value)); |
| 1423 } else { |
| 1424 __ xorl(ToRegister(left), Immediate(right_value)); |
| 1425 } |
| 1375 break; | 1426 break; |
| 1376 default: | 1427 default: |
| 1377 UNREACHABLE(); | 1428 UNREACHABLE(); |
| 1378 break; | 1429 break; |
| 1379 } | 1430 } |
| 1380 } else if (right->IsStackSlot()) { | 1431 } else if (right->IsStackSlot()) { |
| 1381 switch (instr->op()) { | 1432 switch (instr->op()) { |
| 1382 case Token::BIT_AND: | 1433 case Token::BIT_AND: |
| 1383 __ and_(ToRegister(left), ToOperand(right)); | 1434 __ and_(ToRegister(left), ToOperand(right)); |
| 1384 break; | 1435 break; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1459 if (shift_count == 0 && instr->can_deopt()) { | 1510 if (shift_count == 0 && instr->can_deopt()) { |
| 1460 __ testl(ToRegister(left), ToRegister(left)); | 1511 __ testl(ToRegister(left), ToRegister(left)); |
| 1461 DeoptimizeIf(negative, instr->environment()); | 1512 DeoptimizeIf(negative, instr->environment()); |
| 1462 } else { | 1513 } else { |
| 1463 __ shrl(ToRegister(left), Immediate(shift_count)); | 1514 __ shrl(ToRegister(left), Immediate(shift_count)); |
| 1464 } | 1515 } |
| 1465 break; | 1516 break; |
| 1466 case Token::SHL: | 1517 case Token::SHL: |
| 1467 if (shift_count != 0) { | 1518 if (shift_count != 0) { |
| 1468 if (instr->hydrogen_value()->representation().IsSmi()) { | 1519 if (instr->hydrogen_value()->representation().IsSmi()) { |
| 1469 __ shl(ToRegister(left), Immediate(shift_count)); | 1520 if (SmiValuesAre32Bits() || !instr->can_deopt()) { |
| 1521 __ shl(ToRegister(left), Immediate(shift_count)); |
| 1522 } else { |
| 1523 ASSERT(SmiValuesAre31Bits() && instr->can_deopt()); |
| 1524 LithiumSmiInstructionWrapper wrapper(this, instr->environment()); |
| 1525 __ SmiShiftLeftConstant(ToRegister(left), ToRegister(left), |
| 1526 shift_count, wrapper); |
| 1527 } |
| 1470 } else { | 1528 } else { |
| 1471 __ shll(ToRegister(left), Immediate(shift_count)); | 1529 __ shll(ToRegister(left), Immediate(shift_count)); |
| 1472 } | 1530 } |
| 1473 } | 1531 } |
| 1474 break; | 1532 break; |
| 1475 default: | 1533 default: |
| 1476 UNREACHABLE(); | 1534 UNREACHABLE(); |
| 1477 break; | 1535 break; |
| 1478 } | 1536 } |
| 1479 } | 1537 } |
| 1480 } | 1538 } |
| 1481 | 1539 |
| 1482 | 1540 |
| 1483 void LCodeGen::DoSubI(LSubI* instr) { | 1541 void LCodeGen::DoSubI(LSubI* instr) { |
| 1484 LOperand* left = instr->left(); | 1542 LOperand* left = instr->left(); |
| 1485 LOperand* right = instr->right(); | 1543 LOperand* right = instr->right(); |
| 1486 ASSERT(left->Equals(instr->result())); | 1544 ASSERT(left->Equals(instr->result())); |
| 1487 | 1545 |
| 1546 bool check_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
| 1547 LithiumSmiInstructionWrapper wrapper(this, instr->environment(), |
| 1548 check_overflow); |
| 1488 if (right->IsConstantOperand()) { | 1549 if (right->IsConstantOperand()) { |
| 1489 __ subl(ToRegister(left), | 1550 int32_t right_value = ToInteger32(LConstantOperand::cast(right)); |
| 1490 Immediate(ToInteger32(LConstantOperand::cast(right)))); | 1551 if (instr->hydrogen()->representation().IsSmi()) { |
| 1552 __ SmiSubConstant(ToRegister(left), ToRegister(left), |
| 1553 Smi::FromInt(right_value), wrapper); |
| 1554 } else { |
| 1555 __ subl(ToRegister(left), Immediate(right_value)); |
| 1556 } |
| 1491 } else if (right->IsRegister()) { | 1557 } else if (right->IsRegister()) { |
| 1492 if (instr->hydrogen_value()->representation().IsSmi()) { | 1558 if (instr->hydrogen_value()->representation().IsSmi()) { |
| 1493 __ subq(ToRegister(left), ToRegister(right)); | 1559 __ SmiSub(ToRegister(left), ToRegister(left), ToRegister(right), wrapper); |
| 1494 } else { | 1560 } else { |
| 1495 __ subl(ToRegister(left), ToRegister(right)); | 1561 __ subl(ToRegister(left), ToRegister(right)); |
| 1496 } | 1562 } |
| 1497 } else { | 1563 } else { |
| 1498 if (instr->hydrogen_value()->representation().IsSmi()) { | 1564 if (instr->hydrogen_value()->representation().IsSmi()) { |
| 1499 __ subq(ToRegister(left), ToOperand(right)); | 1565 __ SmiSub(ToRegister(left), ToRegister(left), ToOperand(right), wrapper); |
| 1500 } else { | 1566 } else { |
| 1501 __ subl(ToRegister(left), ToOperand(right)); | 1567 __ subl(ToRegister(left), ToOperand(right)); |
| 1502 } | 1568 } |
| 1503 } | 1569 } |
| 1504 | 1570 |
| 1505 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 1571 if (instr->hydrogen_value()->representation().IsInteger32() && |
| 1572 check_overflow) { |
| 1506 DeoptimizeIf(overflow, instr->environment()); | 1573 DeoptimizeIf(overflow, instr->environment()); |
| 1507 } | 1574 } |
| 1508 } | 1575 } |
| 1509 | 1576 |
| 1510 | 1577 |
| 1511 void LCodeGen::DoConstantI(LConstantI* instr) { | 1578 void LCodeGen::DoConstantI(LConstantI* instr) { |
| 1512 __ Set(ToRegister(instr->result()), instr->value()); | 1579 __ Set(ToRegister(instr->result()), instr->value()); |
| 1513 } | 1580 } |
| 1514 | 1581 |
| 1515 | 1582 |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1673 } | 1740 } |
| 1674 } | 1741 } |
| 1675 | 1742 |
| 1676 | 1743 |
| 1677 void LCodeGen::DoAddI(LAddI* instr) { | 1744 void LCodeGen::DoAddI(LAddI* instr) { |
| 1678 LOperand* left = instr->left(); | 1745 LOperand* left = instr->left(); |
| 1679 LOperand* right = instr->right(); | 1746 LOperand* right = instr->right(); |
| 1680 | 1747 |
| 1681 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { | 1748 if (LAddI::UseLea(instr->hydrogen()) && !left->Equals(instr->result())) { |
| 1682 if (right->IsConstantOperand()) { | 1749 if (right->IsConstantOperand()) { |
| 1683 int32_t offset = ToInteger32(LConstantOperand::cast(right)); | 1750 int32_t offset = ToRepresentation(LConstantOperand::cast(right), |
| 1684 __ leal(ToRegister(instr->result()), | 1751 instr->hydrogen()->representation()); |
| 1685 MemOperand(ToRegister(left), offset)); | 1752 if (instr->hydrogen()->representation().IsSmi()) { |
| 1753 __ lea(ToRegister(instr->result()), |
| 1754 MemOperand(ToRegister(left), offset)); |
| 1755 } else { |
| 1756 __ leal(ToRegister(instr->result()), |
| 1757 MemOperand(ToRegister(left), offset)); |
| 1758 } |
| 1686 } else { | 1759 } else { |
| 1687 Operand address(ToRegister(left), ToRegister(right), times_1, 0); | 1760 Operand address(ToRegister(left), ToRegister(right), times_1, 0); |
| 1688 if (instr->hydrogen()->representation().IsSmi()) { | 1761 if (instr->hydrogen()->representation().IsSmi()) { |
| 1689 __ lea(ToRegister(instr->result()), address); | 1762 __ lea(ToRegister(instr->result()), address); |
| 1690 } else { | 1763 } else { |
| 1691 __ leal(ToRegister(instr->result()), address); | 1764 __ leal(ToRegister(instr->result()), address); |
| 1692 } | 1765 } |
| 1693 } | 1766 } |
| 1694 } else { | 1767 } else { |
| 1768 bool check_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
| 1769 LithiumSmiInstructionWrapper wrapper(this, instr->environment(), |
| 1770 check_overflow); |
| 1695 if (right->IsConstantOperand()) { | 1771 if (right->IsConstantOperand()) { |
| 1696 __ addl(ToRegister(left), | 1772 int32_t right_value = ToInteger32(LConstantOperand::cast(right)); |
| 1697 Immediate(ToInteger32(LConstantOperand::cast(right)))); | 1773 if (instr->hydrogen()->representation().IsSmi()) { |
| 1774 __ SmiAddConstant(ToRegister(left), ToRegister(left), |
| 1775 Smi::FromInt(right_value), wrapper); |
| 1776 } else { |
| 1777 __ addl(ToRegister(left), Immediate(right_value)); |
| 1778 } |
| 1698 } else if (right->IsRegister()) { | 1779 } else if (right->IsRegister()) { |
| 1699 if (instr->hydrogen_value()->representation().IsSmi()) { | 1780 if (instr->hydrogen_value()->representation().IsSmi()) { |
| 1700 __ addq(ToRegister(left), ToRegister(right)); | 1781 __ SmiAdd(ToRegister(left), ToRegister(left), ToRegister(right), |
| 1782 wrapper); |
| 1701 } else { | 1783 } else { |
| 1702 __ addl(ToRegister(left), ToRegister(right)); | 1784 __ addl(ToRegister(left), ToRegister(right)); |
| 1703 } | 1785 } |
| 1704 } else { | 1786 } else { |
| 1705 if (instr->hydrogen_value()->representation().IsSmi()) { | 1787 if (instr->hydrogen_value()->representation().IsSmi()) { |
| 1706 __ addq(ToRegister(left), ToOperand(right)); | 1788 __ SmiAdd(ToRegister(left), ToRegister(left), ToOperand(right), |
| 1789 wrapper); |
| 1707 } else { | 1790 } else { |
| 1708 __ addl(ToRegister(left), ToOperand(right)); | 1791 __ addl(ToRegister(left), ToOperand(right)); |
| 1709 } | 1792 } |
| 1710 } | 1793 } |
| 1711 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 1794 |
| 1795 if (instr->hydrogen_value()->representation().IsInteger32() && |
| 1796 check_overflow) { |
| 1712 DeoptimizeIf(overflow, instr->environment()); | 1797 DeoptimizeIf(overflow, instr->environment()); |
| 1713 } | 1798 } |
| 1714 } | 1799 } |
| 1715 } | 1800 } |
| 1716 | 1801 |
| 1717 | 1802 |
| 1718 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { | 1803 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { |
| 1719 LOperand* left = instr->left(); | 1804 LOperand* left = instr->left(); |
| 1720 LOperand* right = instr->right(); | 1805 LOperand* right = instr->right(); |
| 1721 ASSERT(left->Equals(instr->result())); | 1806 ASSERT(left->Equals(instr->result())); |
| 1722 HMathMinMax::Operation operation = instr->hydrogen()->operation(); | 1807 HMathMinMax::Operation operation = instr->hydrogen()->operation(); |
| 1723 if (instr->hydrogen()->representation().IsSmiOrInteger32()) { | 1808 if (instr->hydrogen()->representation().IsSmiOrInteger32()) { |
| 1724 Label return_left; | 1809 Label return_left; |
| 1725 Condition condition = (operation == HMathMinMax::kMathMin) | 1810 Condition condition = (operation == HMathMinMax::kMathMin) |
| 1726 ? less_equal | 1811 ? less_equal |
| 1727 : greater_equal; | 1812 : greater_equal; |
| 1728 Register left_reg = ToRegister(left); | 1813 Register left_reg = ToRegister(left); |
| 1729 if (right->IsConstantOperand()) { | 1814 if (right->IsConstantOperand()) { |
| 1730 Immediate right_imm = | 1815 Immediate right_imm = |
| 1731 Immediate(ToInteger32(LConstantOperand::cast(right))); | 1816 Immediate(ToRepresentation(LConstantOperand::cast(right), |
| 1732 ASSERT(!instr->hydrogen_value()->representation().IsSmi()); | 1817 instr->hydrogen()->representation())); |
| 1733 __ cmpl(left_reg, right_imm); | 1818 __ cmpl(left_reg, right_imm); |
| 1734 __ j(condition, &return_left, Label::kNear); | 1819 __ j(condition, &return_left, Label::kNear); |
| 1735 __ movq(left_reg, right_imm); | 1820 __ movq(left_reg, right_imm); |
| 1736 } else if (right->IsRegister()) { | 1821 } else if (right->IsRegister()) { |
| 1737 Register right_reg = ToRegister(right); | 1822 Register right_reg = ToRegister(right); |
| 1738 if (instr->hydrogen_value()->representation().IsSmi()) { | 1823 if (instr->hydrogen_value()->representation().IsSmi()) { |
| 1739 __ cmpq(left_reg, right_reg); | 1824 __ cmpq(left_reg, right_reg); |
| 1740 } else { | 1825 } else { |
| 1741 __ cmpl(left_reg, right_reg); | 1826 __ cmpl(left_reg, right_reg); |
| 1742 } | 1827 } |
| (...skipping 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2920 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { | 3005 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { |
| 2921 ElementsKind elements_kind = instr->elements_kind(); | 3006 ElementsKind elements_kind = instr->elements_kind(); |
| 2922 LOperand* key = instr->key(); | 3007 LOperand* key = instr->key(); |
| 2923 if (!key->IsConstantOperand()) { | 3008 if (!key->IsConstantOperand()) { |
| 2924 Register key_reg = ToRegister(key); | 3009 Register key_reg = ToRegister(key); |
| 2925 // Even though the HLoad/StoreKeyed (in this case) instructions force | 3010 // Even though the HLoad/StoreKeyed (in this case) instructions force |
| 2926 // the input representation for the key to be an integer, the input | 3011 // the input representation for the key to be an integer, the input |
| 2927 // gets replaced during bound check elimination with the index argument | 3012 // gets replaced during bound check elimination with the index argument |
| 2928 // to the bounds check, which can be tagged, so that case must be | 3013 // to the bounds check, which can be tagged, so that case must be |
| 2929 // handled here, too. | 3014 // handled here, too. |
| 2930 if (instr->hydrogen()->IsDehoisted()) { | 3015 if (instr->hydrogen()->key()->representation().IsSmi()) { |
| 3016 ASSERT(SmiValuesAre31Bits()); |
| 3017 __ SmiToInteger64(key_reg, key_reg); |
| 3018 } else if (instr->hydrogen()->IsDehoisted()) { |
| 2931 // Sign extend key because it could be a 32 bit negative value | 3019 // Sign extend key because it could be a 32 bit negative value |
| 2932 // and the dehoisted address computation happens in 64 bits | 3020 // and the dehoisted address computation happens in 64 bits |
| 2933 __ movsxlq(key_reg, key_reg); | 3021 __ movsxlq(key_reg, key_reg); |
| 2934 } | 3022 } |
| 2935 } | 3023 } |
| 2936 Operand operand(BuildFastArrayOperand( | 3024 Operand operand(BuildFastArrayOperand( |
| 2937 instr->elements(), | 3025 instr->elements(), |
| 2938 key, | 3026 key, |
| 2939 elements_kind, | 3027 elements_kind, |
| 2940 0, | 3028 0, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2991 | 3079 |
| 2992 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { | 3080 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { |
| 2993 XMMRegister result(ToDoubleRegister(instr->result())); | 3081 XMMRegister result(ToDoubleRegister(instr->result())); |
| 2994 LOperand* key = instr->key(); | 3082 LOperand* key = instr->key(); |
| 2995 if (!key->IsConstantOperand()) { | 3083 if (!key->IsConstantOperand()) { |
| 2996 Register key_reg = ToRegister(key); | 3084 Register key_reg = ToRegister(key); |
| 2997 // Even though the HLoad/StoreKeyed instructions force the input | 3085 // Even though the HLoad/StoreKeyed instructions force the input |
| 2998 // representation for the key to be an integer, the input gets replaced | 3086 // representation for the key to be an integer, the input gets replaced |
| 2999 // during bound check elimination with the index argument to the bounds | 3087 // during bound check elimination with the index argument to the bounds |
| 3000 // check, which can be tagged, so that case must be handled here, too. | 3088 // check, which can be tagged, so that case must be handled here, too. |
| 3001 if (instr->hydrogen()->IsDehoisted()) { | 3089 if (instr->hydrogen()->key()->representation().IsSmi()) { |
| 3090 ASSERT(SmiValuesAre31Bits()); |
| 3091 __ SmiToInteger64(key_reg, key_reg); |
| 3092 } else if (instr->hydrogen()->IsDehoisted()) { |
| 3002 // Sign extend key because it could be a 32 bit negative value | 3093 // Sign extend key because it could be a 32 bit negative value |
| 3003 // and the dehoisted address computation happens in 64 bits | 3094 // and the dehoisted address computation happens in 64 bits |
| 3004 __ movsxlq(key_reg, key_reg); | 3095 __ movsxlq(key_reg, key_reg); |
| 3005 } | 3096 } |
| 3006 } | 3097 } |
| 3007 | 3098 |
| 3008 if (instr->hydrogen()->RequiresHoleCheck()) { | 3099 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 3009 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + | 3100 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + |
| 3010 sizeof(kHoleNanLower32); | 3101 sizeof(kHoleNanLower32); |
| 3011 Operand hole_check_operand = BuildFastArrayOperand( | 3102 Operand hole_check_operand = BuildFastArrayOperand( |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3031 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 3122 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
| 3032 Register result = ToRegister(instr->result()); | 3123 Register result = ToRegister(instr->result()); |
| 3033 LOperand* key = instr->key(); | 3124 LOperand* key = instr->key(); |
| 3034 if (!key->IsConstantOperand()) { | 3125 if (!key->IsConstantOperand()) { |
| 3035 Register key_reg = ToRegister(key); | 3126 Register key_reg = ToRegister(key); |
| 3036 // Even though the HLoad/StoreKeyedFastElement instructions force | 3127 // Even though the HLoad/StoreKeyedFastElement instructions force |
| 3037 // the input representation for the key to be an integer, the input | 3128 // the input representation for the key to be an integer, the input |
| 3038 // gets replaced during bound check elimination with the index | 3129 // gets replaced during bound check elimination with the index |
| 3039 // argument to the bounds check, which can be tagged, so that | 3130 // argument to the bounds check, which can be tagged, so that |
| 3040 // case must be handled here, too. | 3131 // case must be handled here, too. |
| 3041 if (instr->hydrogen()->IsDehoisted()) { | 3132 if (instr->hydrogen()->key()->representation().IsSmi()) { |
| 3133 ASSERT(SmiValuesAre31Bits()); |
| 3134 __ SmiToInteger64(key_reg, key_reg); |
| 3135 } else if (instr->hydrogen()->IsDehoisted()) { |
| 3042 // Sign extend key because it could be a 32 bit negative value | 3136 // Sign extend key because it could be a 32 bit negative value |
| 3043 // and the dehoisted address computation happens in 64 bits | 3137 // and the dehoisted address computation happens in 64 bits |
| 3044 __ movsxlq(key_reg, key_reg); | 3138 __ movsxlq(key_reg, key_reg); |
| 3045 } | 3139 } |
| 3046 } | 3140 } |
| 3047 | 3141 |
| 3048 // Load the result. | 3142 // Load the result. |
| 3049 __ movq(result, | 3143 __ movq(result, |
| 3050 BuildFastArrayOperand(instr->elements(), | 3144 BuildFastArrayOperand(instr->elements(), |
| 3051 key, | 3145 key, |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3419 Register input_reg = ToRegister(instr->value()); | 3513 Register input_reg = ToRegister(instr->value()); |
| 3420 __ testl(input_reg, input_reg); | 3514 __ testl(input_reg, input_reg); |
| 3421 Label is_positive; | 3515 Label is_positive; |
| 3422 __ j(not_sign, &is_positive, Label::kNear); | 3516 __ j(not_sign, &is_positive, Label::kNear); |
| 3423 __ negl(input_reg); // Sets flags. | 3517 __ negl(input_reg); // Sets flags. |
| 3424 DeoptimizeIf(negative, instr->environment()); | 3518 DeoptimizeIf(negative, instr->environment()); |
| 3425 __ bind(&is_positive); | 3519 __ bind(&is_positive); |
| 3426 } | 3520 } |
| 3427 | 3521 |
| 3428 | 3522 |
| 3429 void LCodeGen::EmitInteger64MathAbs(LMathAbs* instr) { | 3523 void LCodeGen::EmitSmiMathAbs(LMathAbs* instr) { |
| 3430 Register input_reg = ToRegister(instr->value()); | 3524 Register input_reg = ToRegister(instr->value()); |
| 3431 __ testq(input_reg, input_reg); | 3525 __ testq(input_reg, input_reg); |
| 3432 Label is_positive; | 3526 Label is_positive; |
| 3433 __ j(not_sign, &is_positive, Label::kNear); | 3527 __ j(not_sign, &is_positive, Label::kNear); |
| 3434 __ neg(input_reg); // Sets flags. | 3528 if (SmiValuesAre32Bits()) { |
| 3529 __ neg(input_reg); // Sets flags. |
| 3530 } else { |
| 3531 ASSERT(SmiValuesAre31Bits()); |
| 3532 __ negl(input_reg); // Sets flags. |
| 3533 } |
| 3435 DeoptimizeIf(negative, instr->environment()); | 3534 DeoptimizeIf(negative, instr->environment()); |
| 3436 __ bind(&is_positive); | 3535 __ bind(&is_positive); |
| 3437 } | 3536 } |
| 3438 | 3537 |
| 3439 | 3538 |
| 3440 void LCodeGen::DoMathAbs(LMathAbs* instr) { | 3539 void LCodeGen::DoMathAbs(LMathAbs* instr) { |
| 3441 // Class for deferred case. | 3540 // Class for deferred case. |
| 3442 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { | 3541 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { |
| 3443 public: | 3542 public: |
| 3444 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) | 3543 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3456 | 3555 |
| 3457 if (r.IsDouble()) { | 3556 if (r.IsDouble()) { |
| 3458 XMMRegister scratch = xmm0; | 3557 XMMRegister scratch = xmm0; |
| 3459 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 3558 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 3460 __ xorps(scratch, scratch); | 3559 __ xorps(scratch, scratch); |
| 3461 __ subsd(scratch, input_reg); | 3560 __ subsd(scratch, input_reg); |
| 3462 __ andpd(input_reg, scratch); | 3561 __ andpd(input_reg, scratch); |
| 3463 } else if (r.IsInteger32()) { | 3562 } else if (r.IsInteger32()) { |
| 3464 EmitIntegerMathAbs(instr); | 3563 EmitIntegerMathAbs(instr); |
| 3465 } else if (r.IsSmi()) { | 3564 } else if (r.IsSmi()) { |
| 3466 EmitInteger64MathAbs(instr); | 3565 EmitSmiMathAbs(instr); |
| 3467 } else { // Tagged case. | 3566 } else { // Tagged case. |
| 3468 DeferredMathAbsTaggedHeapNumber* deferred = | 3567 DeferredMathAbsTaggedHeapNumber* deferred = |
| 3469 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); | 3568 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); |
| 3470 Register input_reg = ToRegister(instr->value()); | 3569 Register input_reg = ToRegister(instr->value()); |
| 3471 // Smi check. | 3570 // Smi check. |
| 3472 __ JumpIfNotSmi(input_reg, deferred->entry()); | 3571 __ JumpIfNotSmi(input_reg, deferred->entry()); |
| 3473 __ SmiToInteger32(input_reg, input_reg); | 3572 EmitSmiMathAbs(instr); |
| 3474 EmitIntegerMathAbs(instr); | |
| 3475 __ Integer32ToSmi(input_reg, input_reg); | |
| 3476 __ bind(deferred->exit()); | 3573 __ bind(deferred->exit()); |
| 3477 } | 3574 } |
| 3478 } | 3575 } |
| 3479 | 3576 |
| 3480 | 3577 |
| 3481 void LCodeGen::DoMathFloor(LMathFloor* instr) { | 3578 void LCodeGen::DoMathFloor(LMathFloor* instr) { |
| 3482 XMMRegister xmm_scratch = xmm0; | 3579 XMMRegister xmm_scratch = xmm0; |
| 3483 Register output_reg = ToRegister(instr->result()); | 3580 Register output_reg = ToRegister(instr->result()); |
| 3484 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 3581 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 3485 | 3582 |
| (...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4133 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { | 4230 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { |
| 4134 ElementsKind elements_kind = instr->elements_kind(); | 4231 ElementsKind elements_kind = instr->elements_kind(); |
| 4135 LOperand* key = instr->key(); | 4232 LOperand* key = instr->key(); |
| 4136 if (!key->IsConstantOperand()) { | 4233 if (!key->IsConstantOperand()) { |
| 4137 Register key_reg = ToRegister(key); | 4234 Register key_reg = ToRegister(key); |
| 4138 // Even though the HLoad/StoreKeyedFastElement instructions force | 4235 // Even though the HLoad/StoreKeyedFastElement instructions force |
| 4139 // the input representation for the key to be an integer, the input | 4236 // the input representation for the key to be an integer, the input |
| 4140 // gets replaced during bound check elimination with the index | 4237 // gets replaced during bound check elimination with the index |
| 4141 // argument to the bounds check, which can be tagged, so that case | 4238 // argument to the bounds check, which can be tagged, so that case |
| 4142 // must be handled here, too. | 4239 // must be handled here, too. |
| 4143 if (instr->hydrogen()->IsDehoisted()) { | 4240 if (instr->hydrogen()->key()->representation().IsSmi()) { |
| 4241 ASSERT(SmiValuesAre31Bits()); |
| 4242 __ SmiToInteger64(key_reg, key_reg); |
| 4243 } else if (instr->hydrogen()->IsDehoisted()) { |
| 4144 // Sign extend key because it could be a 32 bit negative value | 4244 // Sign extend key because it could be a 32 bit negative value |
| 4145 // and the dehoisted address computation happens in 64 bits | 4245 // and the dehoisted address computation happens in 64 bits |
| 4146 __ movsxlq(key_reg, key_reg); | 4246 __ movsxlq(key_reg, key_reg); |
| 4147 } | 4247 } |
| 4148 } | 4248 } |
| 4149 Operand operand(BuildFastArrayOperand( | 4249 Operand operand(BuildFastArrayOperand( |
| 4150 instr->elements(), | 4250 instr->elements(), |
| 4151 key, | 4251 key, |
| 4152 elements_kind, | 4252 elements_kind, |
| 4153 0, | 4253 0, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4195 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { | 4295 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
| 4196 XMMRegister value = ToDoubleRegister(instr->value()); | 4296 XMMRegister value = ToDoubleRegister(instr->value()); |
| 4197 LOperand* key = instr->key(); | 4297 LOperand* key = instr->key(); |
| 4198 if (!key->IsConstantOperand()) { | 4298 if (!key->IsConstantOperand()) { |
| 4199 Register key_reg = ToRegister(key); | 4299 Register key_reg = ToRegister(key); |
| 4200 // Even though the HLoad/StoreKeyedFastElement instructions force | 4300 // Even though the HLoad/StoreKeyedFastElement instructions force |
| 4201 // the input representation for the key to be an integer, the | 4301 // the input representation for the key to be an integer, the |
| 4202 // input gets replaced during bound check elimination with the index | 4302 // input gets replaced during bound check elimination with the index |
| 4203 // argument to the bounds check, which can be tagged, so that case | 4303 // argument to the bounds check, which can be tagged, so that case |
| 4204 // must be handled here, too. | 4304 // must be handled here, too. |
| 4205 if (instr->hydrogen()->IsDehoisted()) { | 4305 if (instr->hydrogen()->key()->representation().IsSmi()) { |
| 4306 ASSERT(SmiValuesAre31Bits()); |
| 4307 __ SmiToInteger64(key_reg, key_reg); |
| 4308 } else if (instr->hydrogen()->IsDehoisted()) { |
| 4206 // Sign extend key because it could be a 32 bit negative value | 4309 // Sign extend key because it could be a 32 bit negative value |
| 4207 // and the dehoisted address computation happens in 64 bits | 4310 // and the dehoisted address computation happens in 64 bits |
| 4208 __ movsxlq(key_reg, key_reg); | 4311 __ movsxlq(key_reg, key_reg); |
| 4209 } | 4312 } |
| 4210 } | 4313 } |
| 4211 | 4314 |
| 4212 if (instr->NeedsCanonicalization()) { | 4315 if (instr->NeedsCanonicalization()) { |
| 4213 Label have_value; | 4316 Label have_value; |
| 4214 | 4317 |
| 4215 __ ucomisd(value, value); | 4318 __ ucomisd(value, value); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 4236 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { | 4339 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { |
| 4237 Register elements = ToRegister(instr->elements()); | 4340 Register elements = ToRegister(instr->elements()); |
| 4238 LOperand* key = instr->key(); | 4341 LOperand* key = instr->key(); |
| 4239 if (!key->IsConstantOperand()) { | 4342 if (!key->IsConstantOperand()) { |
| 4240 Register key_reg = ToRegister(key); | 4343 Register key_reg = ToRegister(key); |
| 4241 // Even though the HLoad/StoreKeyedFastElement instructions force | 4344 // Even though the HLoad/StoreKeyedFastElement instructions force |
| 4242 // the input representation for the key to be an integer, the | 4345 // the input representation for the key to be an integer, the |
| 4243 // input gets replaced during bound check elimination with the index | 4346 // input gets replaced during bound check elimination with the index |
| 4244 // argument to the bounds check, which can be tagged, so that case | 4347 // argument to the bounds check, which can be tagged, so that case |
| 4245 // must be handled here, too. | 4348 // must be handled here, too. |
| 4246 if (instr->hydrogen()->IsDehoisted()) { | 4349 if (instr->hydrogen()->key()->representation().IsSmi()) { |
| 4350 ASSERT(SmiValuesAre31Bits()); |
| 4351 __ SmiToInteger64(key_reg, key_reg); |
| 4352 } else if (instr->hydrogen()->IsDehoisted()) { |
| 4247 // Sign extend key because it could be a 32 bit negative value | 4353 // Sign extend key because it could be a 32 bit negative value |
| 4248 // and the dehoisted address computation happens in 64 bits | 4354 // and the dehoisted address computation happens in 64 bits |
| 4249 __ movsxlq(key_reg, key_reg); | 4355 __ movsxlq(key_reg, key_reg); |
| 4250 } | 4356 } |
| 4251 } | 4357 } |
| 4252 | 4358 |
| 4253 Operand operand = | 4359 Operand operand = |
| 4254 BuildFastArrayOperand(instr->elements(), | 4360 BuildFastArrayOperand(instr->elements(), |
| 4255 key, | 4361 key, |
| 4256 FAST_ELEMENTS, | 4362 FAST_ELEMENTS, |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4493 LOperand* output = instr->result(); | 4599 LOperand* output = instr->result(); |
| 4494 LOperand* temp = instr->temp(); | 4600 LOperand* temp = instr->temp(); |
| 4495 | 4601 |
| 4496 __ LoadUint32(ToDoubleRegister(output), | 4602 __ LoadUint32(ToDoubleRegister(output), |
| 4497 ToRegister(input), | 4603 ToRegister(input), |
| 4498 ToDoubleRegister(temp)); | 4604 ToDoubleRegister(temp)); |
| 4499 } | 4605 } |
| 4500 | 4606 |
| 4501 | 4607 |
| 4502 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { | 4608 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { |
| 4503 LOperand* input = instr->value(); | 4609 if (SmiValuesAre32Bits()) { |
| 4504 ASSERT(input->IsRegister() && input->Equals(instr->result())); | 4610 LOperand* input = instr->value(); |
| 4505 Register reg = ToRegister(input); | 4611 ASSERT(input->IsRegister() && input->Equals(instr->result())); |
| 4612 Register reg = ToRegister(input); |
| 4506 | 4613 |
| 4507 __ Integer32ToSmi(reg, reg); | 4614 __ Integer32ToSmi(reg, reg); |
| 4615 } else { |
| 4616 ASSERT(SmiValuesAre31Bits()); |
| 4617 class DeferredNumberTagI: public LDeferredCode { |
| 4618 public: |
| 4619 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) |
| 4620 : LDeferredCode(codegen), instr_(instr) { } |
| 4621 virtual void Generate() { |
| 4622 codegen()->DoDeferredNumberTagI(instr_); |
| 4623 } |
| 4624 virtual LInstruction* instr() { return instr_; } |
| 4625 private: |
| 4626 LNumberTagI* instr_; |
| 4627 }; |
| 4628 |
| 4629 LOperand* input = instr->value(); |
| 4630 ASSERT(input->IsRegister() && input->Equals(instr->result())); |
| 4631 Register reg = ToRegister(input); |
| 4632 |
| 4633 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); |
| 4634 __ shll(reg, Immediate(kSmiTagSize + kSmiShiftSize)); |
| 4635 __ j(overflow, deferred->entry()); |
| 4636 __ movsxlq(reg, reg); |
| 4637 __ bind(deferred->exit()); |
| 4638 } |
| 4508 } | 4639 } |
| 4509 | 4640 |
| 4510 | 4641 |
| 4642 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { |
| 4643 ASSERT(SmiValuesAre31Bits()); |
| 4644 Label slow; |
| 4645 Register reg = ToRegister(instr->value()); |
| 4646 Register tmp = reg.is(rax) ? kScratchRegister : rax; |
| 4647 |
| 4648 // Preserve the value of all registers. |
| 4649 PushSafepointRegistersScope scope(this); |
| 4650 |
| 4651 Label done; |
| 4652 // There was overflow, so bits 30 and 31 of the original integer |
| 4653 // disagree. Try to allocate a heap number in new space and store |
| 4654 // the value in there. If that fails, call the runtime system. |
| 4655 __ SmiToInteger32(reg, reg); |
| 4656 __ xorl(reg, Immediate(0x80000000)); |
| 4657 __ cvtlsi2sd(xmm1, reg); |
| 4658 |
| 4659 if (FLAG_inline_new) { |
| 4660 __ AllocateHeapNumber(reg, tmp, &slow); |
| 4661 __ jmp(&done, Label::kNear); |
| 4662 } |
| 4663 |
| 4664 // Slow case: Call the runtime system to do the number allocation. |
| 4665 __ bind(&slow); |
| 4666 |
| 4667 // Put a valid pointer value in the stack slot where the result |
| 4668 // register is stored, as this register is in the pointer map, but contains an |
| 4669 // integer value. |
| 4670 __ StoreToSafepointRegisterSlot(reg, Immediate(0)); |
| 4671 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); |
| 4672 // Set the pointer to the new heap number in tmp. |
| 4673 if (!reg.is(rax)) __ movq(reg, rax); |
| 4674 |
| 4675 // Heap number allocated. Put the value in xmm0 into the value of the |
| 4676 // allocated heap number. |
| 4677 __ bind(&done); |
| 4678 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), xmm1); |
| 4679 __ StoreToSafepointRegisterSlot(reg, reg); |
| 4680 } |
| 4681 |
| 4682 |
| 4511 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { | 4683 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { |
| 4512 class DeferredNumberTagU: public LDeferredCode { | 4684 class DeferredNumberTagU: public LDeferredCode { |
| 4513 public: | 4685 public: |
| 4514 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) | 4686 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) |
| 4515 : LDeferredCode(codegen), instr_(instr) { } | 4687 : LDeferredCode(codegen), instr_(instr) { } |
| 4516 virtual void Generate() { | 4688 virtual void Generate() { |
| 4517 codegen()->DoDeferredNumberTagU(instr_); | 4689 codegen()->DoDeferredNumberTagU(instr_); |
| 4518 } | 4690 } |
| 4519 virtual LInstruction* instr() { return instr_; } | 4691 virtual LInstruction* instr() { return instr_; } |
| 4520 private: | 4692 private: |
| (...skipping 1056 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5577 FixedArray::kHeaderSize - kPointerSize)); | 5749 FixedArray::kHeaderSize - kPointerSize)); |
| 5578 __ bind(&done); | 5750 __ bind(&done); |
| 5579 } | 5751 } |
| 5580 | 5752 |
| 5581 | 5753 |
| 5582 #undef __ | 5754 #undef __ |
| 5583 | 5755 |
| 5584 } } // namespace v8::internal | 5756 } } // namespace v8::internal |
| 5585 | 5757 |
| 5586 #endif // V8_TARGET_ARCH_X64 | 5758 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |