| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #if V8_TARGET_ARCH_X87 | 5 #if V8_TARGET_ARCH_X87 |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 1503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1514 mov(top_reg, result); | 1514 mov(top_reg, result); |
| 1515 } | 1515 } |
| 1516 add(top_reg, Immediate(object_size)); | 1516 add(top_reg, Immediate(object_size)); |
| 1517 cmp(top_reg, Operand::StaticVariable(allocation_limit)); | 1517 cmp(top_reg, Operand::StaticVariable(allocation_limit)); |
| 1518 j(above, gc_required); | 1518 j(above, gc_required); |
| 1519 | 1519 |
| 1520 // Update allocation top. | 1520 // Update allocation top. |
| 1521 UpdateAllocationTopHelper(top_reg, scratch, flags); | 1521 UpdateAllocationTopHelper(top_reg, scratch, flags); |
| 1522 | 1522 |
| 1523 // Tag result if requested. | 1523 // Tag result if requested. |
| 1524 bool tag_result = (flags & TAG_OBJECT) != 0; | |
| 1525 if (top_reg.is(result)) { | 1524 if (top_reg.is(result)) { |
| 1526 if (tag_result) { | 1525 sub(result, Immediate(object_size - kHeapObjectTag)); |
| 1527 sub(result, Immediate(object_size - kHeapObjectTag)); | 1526 } else { |
| 1528 } else { | |
| 1529 sub(result, Immediate(object_size)); | |
| 1530 } | |
| 1531 } else if (tag_result) { | |
| 1532 DCHECK(kHeapObjectTag == 1); | 1527 DCHECK(kHeapObjectTag == 1); |
| 1533 inc(result); | 1528 inc(result); |
| 1534 } | 1529 } |
| 1535 } | 1530 } |
| 1536 | 1531 |
| 1537 | 1532 |
| 1538 void MacroAssembler::Allocate(int header_size, | 1533 void MacroAssembler::Allocate(int header_size, |
| 1539 ScaleFactor element_size, | 1534 ScaleFactor element_size, |
| 1540 Register element_count, | 1535 Register element_count, |
| 1541 RegisterValueType element_count_type, | 1536 RegisterValueType element_count_type, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1595 element_size = static_cast<ScaleFactor>(element_size - 1); | 1590 element_size = static_cast<ScaleFactor>(element_size - 1); |
| 1596 } else { | 1591 } else { |
| 1597 DCHECK(element_count_type == REGISTER_VALUE_IS_INT32); | 1592 DCHECK(element_count_type == REGISTER_VALUE_IS_INT32); |
| 1598 } | 1593 } |
| 1599 lea(result_end, Operand(element_count, element_size, header_size)); | 1594 lea(result_end, Operand(element_count, element_size, header_size)); |
| 1600 add(result_end, result); | 1595 add(result_end, result); |
| 1601 j(carry, gc_required); | 1596 j(carry, gc_required); |
| 1602 cmp(result_end, Operand::StaticVariable(allocation_limit)); | 1597 cmp(result_end, Operand::StaticVariable(allocation_limit)); |
| 1603 j(above, gc_required); | 1598 j(above, gc_required); |
| 1604 | 1599 |
| 1605 if ((flags & TAG_OBJECT) != 0) { | 1600 DCHECK(kHeapObjectTag == 1); |
| 1606 DCHECK(kHeapObjectTag == 1); | 1601 inc(result); |
| 1607 inc(result); | |
| 1608 } | |
| 1609 | 1602 |
| 1610 // Update allocation top. | 1603 // Update allocation top. |
| 1611 UpdateAllocationTopHelper(result_end, scratch, flags); | 1604 UpdateAllocationTopHelper(result_end, scratch, flags); |
| 1612 } | 1605 } |
| 1613 | 1606 |
| 1614 | 1607 |
| 1615 void MacroAssembler::Allocate(Register object_size, | 1608 void MacroAssembler::Allocate(Register object_size, |
| 1616 Register result, | 1609 Register result, |
| 1617 Register result_end, | 1610 Register result_end, |
| 1618 Register scratch, | 1611 Register scratch, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1659 | 1652 |
| 1660 // Calculate new top and bail out if space is exhausted. | 1653 // Calculate new top and bail out if space is exhausted. |
| 1661 if (!object_size.is(result_end)) { | 1654 if (!object_size.is(result_end)) { |
| 1662 mov(result_end, object_size); | 1655 mov(result_end, object_size); |
| 1663 } | 1656 } |
| 1664 add(result_end, result); | 1657 add(result_end, result); |
| 1665 j(carry, gc_required); | 1658 j(carry, gc_required); |
| 1666 cmp(result_end, Operand::StaticVariable(allocation_limit)); | 1659 cmp(result_end, Operand::StaticVariable(allocation_limit)); |
| 1667 j(above, gc_required); | 1660 j(above, gc_required); |
| 1668 | 1661 |
| 1669 // Tag result if requested. | 1662 // Tag result. |
| 1670 if ((flags & TAG_OBJECT) != 0) { | 1663 DCHECK(kHeapObjectTag == 1); |
| 1671 DCHECK(kHeapObjectTag == 1); | 1664 inc(result); |
| 1672 inc(result); | |
| 1673 } | |
| 1674 | 1665 |
| 1675 // Update allocation top. | 1666 // Update allocation top. |
| 1676 UpdateAllocationTopHelper(result_end, scratch, flags); | 1667 UpdateAllocationTopHelper(result_end, scratch, flags); |
| 1677 } | 1668 } |
| 1678 | 1669 |
| 1679 | 1670 |
| 1680 void MacroAssembler::AllocateHeapNumber(Register result, | 1671 void MacroAssembler::AllocateHeapNumber(Register result, |
| 1681 Register scratch1, | 1672 Register scratch1, |
| 1682 Register scratch2, | 1673 Register scratch2, |
| 1683 Label* gc_required, | 1674 Label* gc_required, |
| 1684 MutableMode mode) { | 1675 MutableMode mode) { |
| 1685 // Allocate heap number in new space. | 1676 // Allocate heap number in new space. |
| 1686 Allocate(HeapNumber::kSize, result, scratch1, scratch2, gc_required, | 1677 Allocate(HeapNumber::kSize, result, scratch1, scratch2, gc_required, |
| 1687 TAG_OBJECT); | 1678 NO_ALLOCATION_FLAGS); |
| 1688 | 1679 |
| 1689 Handle<Map> map = mode == MUTABLE | 1680 Handle<Map> map = mode == MUTABLE |
| 1690 ? isolate()->factory()->mutable_heap_number_map() | 1681 ? isolate()->factory()->mutable_heap_number_map() |
| 1691 : isolate()->factory()->heap_number_map(); | 1682 : isolate()->factory()->heap_number_map(); |
| 1692 | 1683 |
| 1693 // Set the map. | 1684 // Set the map. |
| 1694 mov(FieldOperand(result, HeapObject::kMapOffset), Immediate(map)); | 1685 mov(FieldOperand(result, HeapObject::kMapOffset), Immediate(map)); |
| 1695 } | 1686 } |
| 1696 | 1687 |
| 1697 | 1688 |
| 1698 void MacroAssembler::AllocateTwoByteString(Register result, | 1689 void MacroAssembler::AllocateTwoByteString(Register result, |
| 1699 Register length, | 1690 Register length, |
| 1700 Register scratch1, | 1691 Register scratch1, |
| 1701 Register scratch2, | 1692 Register scratch2, |
| 1702 Register scratch3, | 1693 Register scratch3, |
| 1703 Label* gc_required) { | 1694 Label* gc_required) { |
| 1704 // Calculate the number of bytes needed for the characters in the string while | 1695 // Calculate the number of bytes needed for the characters in the string while |
| 1705 // observing object alignment. | 1696 // observing object alignment. |
| 1706 DCHECK((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); | 1697 DCHECK((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
| 1707 DCHECK(kShortSize == 2); | 1698 DCHECK(kShortSize == 2); |
| 1708 // scratch1 = length * 2 + kObjectAlignmentMask. | 1699 // scratch1 = length * 2 + kObjectAlignmentMask. |
| 1709 lea(scratch1, Operand(length, length, times_1, kObjectAlignmentMask)); | 1700 lea(scratch1, Operand(length, length, times_1, kObjectAlignmentMask)); |
| 1710 and_(scratch1, Immediate(~kObjectAlignmentMask)); | 1701 and_(scratch1, Immediate(~kObjectAlignmentMask)); |
| 1711 | 1702 |
| 1712 // Allocate two byte string in new space. | 1703 // Allocate two byte string in new space. |
| 1713 Allocate(SeqTwoByteString::kHeaderSize, | 1704 Allocate(SeqTwoByteString::kHeaderSize, times_1, scratch1, |
| 1714 times_1, | 1705 REGISTER_VALUE_IS_INT32, result, scratch2, scratch3, gc_required, |
| 1715 scratch1, | 1706 NO_ALLOCATION_FLAGS); |
| 1716 REGISTER_VALUE_IS_INT32, | |
| 1717 result, | |
| 1718 scratch2, | |
| 1719 scratch3, | |
| 1720 gc_required, | |
| 1721 TAG_OBJECT); | |
| 1722 | 1707 |
| 1723 // Set the map, length and hash field. | 1708 // Set the map, length and hash field. |
| 1724 mov(FieldOperand(result, HeapObject::kMapOffset), | 1709 mov(FieldOperand(result, HeapObject::kMapOffset), |
| 1725 Immediate(isolate()->factory()->string_map())); | 1710 Immediate(isolate()->factory()->string_map())); |
| 1726 mov(scratch1, length); | 1711 mov(scratch1, length); |
| 1727 SmiTag(scratch1); | 1712 SmiTag(scratch1); |
| 1728 mov(FieldOperand(result, String::kLengthOffset), scratch1); | 1713 mov(FieldOperand(result, String::kLengthOffset), scratch1); |
| 1729 mov(FieldOperand(result, String::kHashFieldOffset), | 1714 mov(FieldOperand(result, String::kHashFieldOffset), |
| 1730 Immediate(String::kEmptyHashField)); | 1715 Immediate(String::kEmptyHashField)); |
| 1731 } | 1716 } |
| 1732 | 1717 |
| 1733 | 1718 |
| 1734 void MacroAssembler::AllocateOneByteString(Register result, Register length, | 1719 void MacroAssembler::AllocateOneByteString(Register result, Register length, |
| 1735 Register scratch1, Register scratch2, | 1720 Register scratch1, Register scratch2, |
| 1736 Register scratch3, | 1721 Register scratch3, |
| 1737 Label* gc_required) { | 1722 Label* gc_required) { |
| 1738 // Calculate the number of bytes needed for the characters in the string while | 1723 // Calculate the number of bytes needed for the characters in the string while |
| 1739 // observing object alignment. | 1724 // observing object alignment. |
| 1740 DCHECK((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); | 1725 DCHECK((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
| 1741 mov(scratch1, length); | 1726 mov(scratch1, length); |
| 1742 DCHECK(kCharSize == 1); | 1727 DCHECK(kCharSize == 1); |
| 1743 add(scratch1, Immediate(kObjectAlignmentMask)); | 1728 add(scratch1, Immediate(kObjectAlignmentMask)); |
| 1744 and_(scratch1, Immediate(~kObjectAlignmentMask)); | 1729 and_(scratch1, Immediate(~kObjectAlignmentMask)); |
| 1745 | 1730 |
| 1746 // Allocate one-byte string in new space. | 1731 // Allocate one-byte string in new space. |
| 1747 Allocate(SeqOneByteString::kHeaderSize, | 1732 Allocate(SeqOneByteString::kHeaderSize, times_1, scratch1, |
| 1748 times_1, | 1733 REGISTER_VALUE_IS_INT32, result, scratch2, scratch3, gc_required, |
| 1749 scratch1, | 1734 NO_ALLOCATION_FLAGS); |
| 1750 REGISTER_VALUE_IS_INT32, | |
| 1751 result, | |
| 1752 scratch2, | |
| 1753 scratch3, | |
| 1754 gc_required, | |
| 1755 TAG_OBJECT); | |
| 1756 | 1735 |
| 1757 // Set the map, length and hash field. | 1736 // Set the map, length and hash field. |
| 1758 mov(FieldOperand(result, HeapObject::kMapOffset), | 1737 mov(FieldOperand(result, HeapObject::kMapOffset), |
| 1759 Immediate(isolate()->factory()->one_byte_string_map())); | 1738 Immediate(isolate()->factory()->one_byte_string_map())); |
| 1760 mov(scratch1, length); | 1739 mov(scratch1, length); |
| 1761 SmiTag(scratch1); | 1740 SmiTag(scratch1); |
| 1762 mov(FieldOperand(result, String::kLengthOffset), scratch1); | 1741 mov(FieldOperand(result, String::kLengthOffset), scratch1); |
| 1763 mov(FieldOperand(result, String::kHashFieldOffset), | 1742 mov(FieldOperand(result, String::kHashFieldOffset), |
| 1764 Immediate(String::kEmptyHashField)); | 1743 Immediate(String::kEmptyHashField)); |
| 1765 } | 1744 } |
| 1766 | 1745 |
| 1767 | 1746 |
| 1768 void MacroAssembler::AllocateOneByteString(Register result, int length, | 1747 void MacroAssembler::AllocateOneByteString(Register result, int length, |
| 1769 Register scratch1, Register scratch2, | 1748 Register scratch1, Register scratch2, |
| 1770 Label* gc_required) { | 1749 Label* gc_required) { |
| 1771 DCHECK(length > 0); | 1750 DCHECK(length > 0); |
| 1772 | 1751 |
| 1773 // Allocate one-byte string in new space. | 1752 // Allocate one-byte string in new space. |
| 1774 Allocate(SeqOneByteString::SizeFor(length), result, scratch1, scratch2, | 1753 Allocate(SeqOneByteString::SizeFor(length), result, scratch1, scratch2, |
| 1775 gc_required, TAG_OBJECT); | 1754 gc_required, NO_ALLOCATION_FLAGS); |
| 1776 | 1755 |
| 1777 // Set the map, length and hash field. | 1756 // Set the map, length and hash field. |
| 1778 mov(FieldOperand(result, HeapObject::kMapOffset), | 1757 mov(FieldOperand(result, HeapObject::kMapOffset), |
| 1779 Immediate(isolate()->factory()->one_byte_string_map())); | 1758 Immediate(isolate()->factory()->one_byte_string_map())); |
| 1780 mov(FieldOperand(result, String::kLengthOffset), | 1759 mov(FieldOperand(result, String::kLengthOffset), |
| 1781 Immediate(Smi::FromInt(length))); | 1760 Immediate(Smi::FromInt(length))); |
| 1782 mov(FieldOperand(result, String::kHashFieldOffset), | 1761 mov(FieldOperand(result, String::kHashFieldOffset), |
| 1783 Immediate(String::kEmptyHashField)); | 1762 Immediate(String::kEmptyHashField)); |
| 1784 } | 1763 } |
| 1785 | 1764 |
| 1786 | 1765 |
| 1787 void MacroAssembler::AllocateTwoByteConsString(Register result, | 1766 void MacroAssembler::AllocateTwoByteConsString(Register result, |
| 1788 Register scratch1, | 1767 Register scratch1, |
| 1789 Register scratch2, | 1768 Register scratch2, |
| 1790 Label* gc_required) { | 1769 Label* gc_required) { |
| 1791 // Allocate heap number in new space. | 1770 // Allocate heap number in new space. |
| 1792 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, | 1771 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, |
| 1793 TAG_OBJECT); | 1772 NO_ALLOCATION_FLAGS); |
| 1794 | 1773 |
| 1795 // Set the map. The other fields are left uninitialized. | 1774 // Set the map. The other fields are left uninitialized. |
| 1796 mov(FieldOperand(result, HeapObject::kMapOffset), | 1775 mov(FieldOperand(result, HeapObject::kMapOffset), |
| 1797 Immediate(isolate()->factory()->cons_string_map())); | 1776 Immediate(isolate()->factory()->cons_string_map())); |
| 1798 } | 1777 } |
| 1799 | 1778 |
| 1800 | 1779 |
| 1801 void MacroAssembler::AllocateOneByteConsString(Register result, | 1780 void MacroAssembler::AllocateOneByteConsString(Register result, |
| 1802 Register scratch1, | 1781 Register scratch1, |
| 1803 Register scratch2, | 1782 Register scratch2, |
| 1804 Label* gc_required) { | 1783 Label* gc_required) { |
| 1805 Allocate(ConsString::kSize, | 1784 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, |
| 1806 result, | 1785 NO_ALLOCATION_FLAGS); |
| 1807 scratch1, | |
| 1808 scratch2, | |
| 1809 gc_required, | |
| 1810 TAG_OBJECT); | |
| 1811 | 1786 |
| 1812 // Set the map. The other fields are left uninitialized. | 1787 // Set the map. The other fields are left uninitialized. |
| 1813 mov(FieldOperand(result, HeapObject::kMapOffset), | 1788 mov(FieldOperand(result, HeapObject::kMapOffset), |
| 1814 Immediate(isolate()->factory()->cons_one_byte_string_map())); | 1789 Immediate(isolate()->factory()->cons_one_byte_string_map())); |
| 1815 } | 1790 } |
| 1816 | 1791 |
| 1817 | 1792 |
| 1818 void MacroAssembler::AllocateTwoByteSlicedString(Register result, | 1793 void MacroAssembler::AllocateTwoByteSlicedString(Register result, |
| 1819 Register scratch1, | 1794 Register scratch1, |
| 1820 Register scratch2, | 1795 Register scratch2, |
| 1821 Label* gc_required) { | 1796 Label* gc_required) { |
| 1822 // Allocate heap number in new space. | 1797 // Allocate heap number in new space. |
| 1823 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | 1798 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, |
| 1824 TAG_OBJECT); | 1799 NO_ALLOCATION_FLAGS); |
| 1825 | 1800 |
| 1826 // Set the map. The other fields are left uninitialized. | 1801 // Set the map. The other fields are left uninitialized. |
| 1827 mov(FieldOperand(result, HeapObject::kMapOffset), | 1802 mov(FieldOperand(result, HeapObject::kMapOffset), |
| 1828 Immediate(isolate()->factory()->sliced_string_map())); | 1803 Immediate(isolate()->factory()->sliced_string_map())); |
| 1829 } | 1804 } |
| 1830 | 1805 |
| 1831 | 1806 |
| 1832 void MacroAssembler::AllocateOneByteSlicedString(Register result, | 1807 void MacroAssembler::AllocateOneByteSlicedString(Register result, |
| 1833 Register scratch1, | 1808 Register scratch1, |
| 1834 Register scratch2, | 1809 Register scratch2, |
| 1835 Label* gc_required) { | 1810 Label* gc_required) { |
| 1836 // Allocate heap number in new space. | 1811 // Allocate heap number in new space. |
| 1837 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | 1812 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, |
| 1838 TAG_OBJECT); | 1813 NO_ALLOCATION_FLAGS); |
| 1839 | 1814 |
| 1840 // Set the map. The other fields are left uninitialized. | 1815 // Set the map. The other fields are left uninitialized. |
| 1841 mov(FieldOperand(result, HeapObject::kMapOffset), | 1816 mov(FieldOperand(result, HeapObject::kMapOffset), |
| 1842 Immediate(isolate()->factory()->sliced_one_byte_string_map())); | 1817 Immediate(isolate()->factory()->sliced_one_byte_string_map())); |
| 1843 } | 1818 } |
| 1844 | 1819 |
| 1845 | 1820 |
| 1846 void MacroAssembler::AllocateJSValue(Register result, Register constructor, | 1821 void MacroAssembler::AllocateJSValue(Register result, Register constructor, |
| 1847 Register value, Register scratch, | 1822 Register value, Register scratch, |
| 1848 Label* gc_required) { | 1823 Label* gc_required) { |
| 1849 DCHECK(!result.is(constructor)); | 1824 DCHECK(!result.is(constructor)); |
| 1850 DCHECK(!result.is(scratch)); | 1825 DCHECK(!result.is(scratch)); |
| 1851 DCHECK(!result.is(value)); | 1826 DCHECK(!result.is(value)); |
| 1852 | 1827 |
| 1853 // Allocate JSValue in new space. | 1828 // Allocate JSValue in new space. |
| 1854 Allocate(JSValue::kSize, result, scratch, no_reg, gc_required, TAG_OBJECT); | 1829 Allocate(JSValue::kSize, result, scratch, no_reg, gc_required, |
| 1830 NO_ALLOCATION_FLAGS); |
| 1855 | 1831 |
| 1856 // Initialize the JSValue. | 1832 // Initialize the JSValue. |
| 1857 LoadGlobalFunctionInitialMap(constructor, scratch); | 1833 LoadGlobalFunctionInitialMap(constructor, scratch); |
| 1858 mov(FieldOperand(result, HeapObject::kMapOffset), scratch); | 1834 mov(FieldOperand(result, HeapObject::kMapOffset), scratch); |
| 1859 LoadRoot(scratch, Heap::kEmptyFixedArrayRootIndex); | 1835 LoadRoot(scratch, Heap::kEmptyFixedArrayRootIndex); |
| 1860 mov(FieldOperand(result, JSObject::kPropertiesOffset), scratch); | 1836 mov(FieldOperand(result, JSObject::kPropertiesOffset), scratch); |
| 1861 mov(FieldOperand(result, JSObject::kElementsOffset), scratch); | 1837 mov(FieldOperand(result, JSObject::kElementsOffset), scratch); |
| 1862 mov(FieldOperand(result, JSValue::kValueOffset), value); | 1838 mov(FieldOperand(result, JSValue::kValueOffset), value); |
| 1863 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); | 1839 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); |
| 1864 } | 1840 } |
| (...skipping 1406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3271 mov(eax, dividend); | 3247 mov(eax, dividend); |
| 3272 shr(eax, 31); | 3248 shr(eax, 31); |
| 3273 add(edx, eax); | 3249 add(edx, eax); |
| 3274 } | 3250 } |
| 3275 | 3251 |
| 3276 | 3252 |
| 3277 } // namespace internal | 3253 } // namespace internal |
| 3278 } // namespace v8 | 3254 } // namespace v8 |
| 3279 | 3255 |
| 3280 #endif // V8_TARGET_ARCH_X87 | 3256 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |