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_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
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 1560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1571 if (!top_reg.is(result)) { | 1571 if (!top_reg.is(result)) { |
1572 mov(top_reg, result); | 1572 mov(top_reg, result); |
1573 } | 1573 } |
1574 add(top_reg, Immediate(object_size)); | 1574 add(top_reg, Immediate(object_size)); |
1575 cmp(top_reg, Operand::StaticVariable(allocation_limit)); | 1575 cmp(top_reg, Operand::StaticVariable(allocation_limit)); |
1576 j(above, gc_required); | 1576 j(above, gc_required); |
1577 | 1577 |
1578 // Update allocation top. | 1578 // Update allocation top. |
1579 UpdateAllocationTopHelper(top_reg, scratch, flags); | 1579 UpdateAllocationTopHelper(top_reg, scratch, flags); |
1580 | 1580 |
1581 // Tag result if requested. | |
1582 bool tag_result = (flags & TAG_OBJECT) != 0; | |
1583 if (top_reg.is(result)) { | 1581 if (top_reg.is(result)) { |
1584 if (tag_result) { | 1582 sub(result, Immediate(object_size - kHeapObjectTag)); |
1585 sub(result, Immediate(object_size - kHeapObjectTag)); | 1583 } else { |
1586 } else { | 1584 // Tag the result. |
1587 sub(result, Immediate(object_size)); | |
1588 } | |
1589 } else if (tag_result) { | |
1590 DCHECK(kHeapObjectTag == 1); | 1585 DCHECK(kHeapObjectTag == 1); |
1591 inc(result); | 1586 inc(result); |
1592 } | 1587 } |
1593 } | 1588 } |
1594 | 1589 |
1595 | 1590 |
1596 void MacroAssembler::Allocate(int header_size, | 1591 void MacroAssembler::Allocate(int header_size, |
1597 ScaleFactor element_size, | 1592 ScaleFactor element_size, |
1598 Register element_count, | 1593 Register element_count, |
1599 RegisterValueType element_count_type, | 1594 RegisterValueType element_count_type, |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1653 element_size = static_cast<ScaleFactor>(element_size - 1); | 1648 element_size = static_cast<ScaleFactor>(element_size - 1); |
1654 } else { | 1649 } else { |
1655 DCHECK(element_count_type == REGISTER_VALUE_IS_INT32); | 1650 DCHECK(element_count_type == REGISTER_VALUE_IS_INT32); |
1656 } | 1651 } |
1657 lea(result_end, Operand(element_count, element_size, header_size)); | 1652 lea(result_end, Operand(element_count, element_size, header_size)); |
1658 add(result_end, result); | 1653 add(result_end, result); |
1659 j(carry, gc_required); | 1654 j(carry, gc_required); |
1660 cmp(result_end, Operand::StaticVariable(allocation_limit)); | 1655 cmp(result_end, Operand::StaticVariable(allocation_limit)); |
1661 j(above, gc_required); | 1656 j(above, gc_required); |
1662 | 1657 |
1663 if ((flags & TAG_OBJECT) != 0) { | 1658 // Tag result. |
1664 DCHECK(kHeapObjectTag == 1); | 1659 DCHECK(kHeapObjectTag == 1); |
1665 inc(result); | 1660 inc(result); |
1666 } | |
1667 | 1661 |
1668 // Update allocation top. | 1662 // Update allocation top. |
1669 UpdateAllocationTopHelper(result_end, scratch, flags); | 1663 UpdateAllocationTopHelper(result_end, scratch, flags); |
1670 } | 1664 } |
1671 | 1665 |
1672 | 1666 |
1673 void MacroAssembler::Allocate(Register object_size, | 1667 void MacroAssembler::Allocate(Register object_size, |
1674 Register result, | 1668 Register result, |
1675 Register result_end, | 1669 Register result_end, |
1676 Register scratch, | 1670 Register scratch, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1717 | 1711 |
1718 // Calculate new top and bail out if space is exhausted. | 1712 // Calculate new top and bail out if space is exhausted. |
1719 if (!object_size.is(result_end)) { | 1713 if (!object_size.is(result_end)) { |
1720 mov(result_end, object_size); | 1714 mov(result_end, object_size); |
1721 } | 1715 } |
1722 add(result_end, result); | 1716 add(result_end, result); |
1723 j(carry, gc_required); | 1717 j(carry, gc_required); |
1724 cmp(result_end, Operand::StaticVariable(allocation_limit)); | 1718 cmp(result_end, Operand::StaticVariable(allocation_limit)); |
1725 j(above, gc_required); | 1719 j(above, gc_required); |
1726 | 1720 |
1727 // Tag result if requested. | 1721 // Tag result. |
1728 if ((flags & TAG_OBJECT) != 0) { | 1722 DCHECK(kHeapObjectTag == 1); |
1729 DCHECK(kHeapObjectTag == 1); | 1723 inc(result); |
1730 inc(result); | |
1731 } | |
1732 | 1724 |
1733 // Update allocation top. | 1725 // Update allocation top. |
1734 UpdateAllocationTopHelper(result_end, scratch, flags); | 1726 UpdateAllocationTopHelper(result_end, scratch, flags); |
1735 } | 1727 } |
1736 | 1728 |
1737 | 1729 |
1738 void MacroAssembler::AllocateHeapNumber(Register result, | 1730 void MacroAssembler::AllocateHeapNumber(Register result, |
1739 Register scratch1, | 1731 Register scratch1, |
1740 Register scratch2, | 1732 Register scratch2, |
1741 Label* gc_required, | 1733 Label* gc_required, |
1742 MutableMode mode) { | 1734 MutableMode mode) { |
1743 // Allocate heap number in new space. | 1735 // Allocate heap number in new space. |
1744 Allocate(HeapNumber::kSize, result, scratch1, scratch2, gc_required, | 1736 Allocate(HeapNumber::kSize, result, scratch1, scratch2, gc_required, |
1745 TAG_OBJECT); | 1737 NO_ALLOCATION_FLAGS); |
1746 | 1738 |
1747 Handle<Map> map = mode == MUTABLE | 1739 Handle<Map> map = mode == MUTABLE |
1748 ? isolate()->factory()->mutable_heap_number_map() | 1740 ? isolate()->factory()->mutable_heap_number_map() |
1749 : isolate()->factory()->heap_number_map(); | 1741 : isolate()->factory()->heap_number_map(); |
1750 | 1742 |
1751 // Set the map. | 1743 // Set the map. |
1752 mov(FieldOperand(result, HeapObject::kMapOffset), Immediate(map)); | 1744 mov(FieldOperand(result, HeapObject::kMapOffset), Immediate(map)); |
1753 } | 1745 } |
1754 | 1746 |
1755 | 1747 |
1756 void MacroAssembler::AllocateTwoByteString(Register result, | 1748 void MacroAssembler::AllocateTwoByteString(Register result, |
1757 Register length, | 1749 Register length, |
1758 Register scratch1, | 1750 Register scratch1, |
1759 Register scratch2, | 1751 Register scratch2, |
1760 Register scratch3, | 1752 Register scratch3, |
1761 Label* gc_required) { | 1753 Label* gc_required) { |
1762 // Calculate the number of bytes needed for the characters in the string while | 1754 // Calculate the number of bytes needed for the characters in the string while |
1763 // observing object alignment. | 1755 // observing object alignment. |
1764 DCHECK((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); | 1756 DCHECK((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
1765 DCHECK(kShortSize == 2); | 1757 DCHECK(kShortSize == 2); |
1766 // scratch1 = length * 2 + kObjectAlignmentMask. | 1758 // scratch1 = length * 2 + kObjectAlignmentMask. |
1767 lea(scratch1, Operand(length, length, times_1, kObjectAlignmentMask)); | 1759 lea(scratch1, Operand(length, length, times_1, kObjectAlignmentMask)); |
1768 and_(scratch1, Immediate(~kObjectAlignmentMask)); | 1760 and_(scratch1, Immediate(~kObjectAlignmentMask)); |
1769 | 1761 |
1770 // Allocate two byte string in new space. | 1762 // Allocate two byte string in new space. |
1771 Allocate(SeqTwoByteString::kHeaderSize, | 1763 Allocate(SeqTwoByteString::kHeaderSize, times_1, scratch1, |
1772 times_1, | 1764 REGISTER_VALUE_IS_INT32, result, scratch2, scratch3, gc_required, |
1773 scratch1, | 1765 NO_ALLOCATION_FLAGS); |
1774 REGISTER_VALUE_IS_INT32, | |
1775 result, | |
1776 scratch2, | |
1777 scratch3, | |
1778 gc_required, | |
1779 TAG_OBJECT); | |
1780 | 1766 |
1781 // Set the map, length and hash field. | 1767 // Set the map, length and hash field. |
1782 mov(FieldOperand(result, HeapObject::kMapOffset), | 1768 mov(FieldOperand(result, HeapObject::kMapOffset), |
1783 Immediate(isolate()->factory()->string_map())); | 1769 Immediate(isolate()->factory()->string_map())); |
1784 mov(scratch1, length); | 1770 mov(scratch1, length); |
1785 SmiTag(scratch1); | 1771 SmiTag(scratch1); |
1786 mov(FieldOperand(result, String::kLengthOffset), scratch1); | 1772 mov(FieldOperand(result, String::kLengthOffset), scratch1); |
1787 mov(FieldOperand(result, String::kHashFieldOffset), | 1773 mov(FieldOperand(result, String::kHashFieldOffset), |
1788 Immediate(String::kEmptyHashField)); | 1774 Immediate(String::kEmptyHashField)); |
1789 } | 1775 } |
1790 | 1776 |
1791 | 1777 |
1792 void MacroAssembler::AllocateOneByteString(Register result, Register length, | 1778 void MacroAssembler::AllocateOneByteString(Register result, Register length, |
1793 Register scratch1, Register scratch2, | 1779 Register scratch1, Register scratch2, |
1794 Register scratch3, | 1780 Register scratch3, |
1795 Label* gc_required) { | 1781 Label* gc_required) { |
1796 // Calculate the number of bytes needed for the characters in the string while | 1782 // Calculate the number of bytes needed for the characters in the string while |
1797 // observing object alignment. | 1783 // observing object alignment. |
1798 DCHECK((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); | 1784 DCHECK((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
1799 mov(scratch1, length); | 1785 mov(scratch1, length); |
1800 DCHECK(kCharSize == 1); | 1786 DCHECK(kCharSize == 1); |
1801 add(scratch1, Immediate(kObjectAlignmentMask)); | 1787 add(scratch1, Immediate(kObjectAlignmentMask)); |
1802 and_(scratch1, Immediate(~kObjectAlignmentMask)); | 1788 and_(scratch1, Immediate(~kObjectAlignmentMask)); |
1803 | 1789 |
1804 // Allocate one-byte string in new space. | 1790 // Allocate one-byte string in new space. |
1805 Allocate(SeqOneByteString::kHeaderSize, | 1791 Allocate(SeqOneByteString::kHeaderSize, times_1, scratch1, |
1806 times_1, | 1792 REGISTER_VALUE_IS_INT32, result, scratch2, scratch3, gc_required, |
1807 scratch1, | 1793 NO_ALLOCATION_FLAGS); |
1808 REGISTER_VALUE_IS_INT32, | |
1809 result, | |
1810 scratch2, | |
1811 scratch3, | |
1812 gc_required, | |
1813 TAG_OBJECT); | |
1814 | 1794 |
1815 // Set the map, length and hash field. | 1795 // Set the map, length and hash field. |
1816 mov(FieldOperand(result, HeapObject::kMapOffset), | 1796 mov(FieldOperand(result, HeapObject::kMapOffset), |
1817 Immediate(isolate()->factory()->one_byte_string_map())); | 1797 Immediate(isolate()->factory()->one_byte_string_map())); |
1818 mov(scratch1, length); | 1798 mov(scratch1, length); |
1819 SmiTag(scratch1); | 1799 SmiTag(scratch1); |
1820 mov(FieldOperand(result, String::kLengthOffset), scratch1); | 1800 mov(FieldOperand(result, String::kLengthOffset), scratch1); |
1821 mov(FieldOperand(result, String::kHashFieldOffset), | 1801 mov(FieldOperand(result, String::kHashFieldOffset), |
1822 Immediate(String::kEmptyHashField)); | 1802 Immediate(String::kEmptyHashField)); |
1823 } | 1803 } |
1824 | 1804 |
1825 | 1805 |
1826 void MacroAssembler::AllocateOneByteString(Register result, int length, | 1806 void MacroAssembler::AllocateOneByteString(Register result, int length, |
1827 Register scratch1, Register scratch2, | 1807 Register scratch1, Register scratch2, |
1828 Label* gc_required) { | 1808 Label* gc_required) { |
1829 DCHECK(length > 0); | 1809 DCHECK(length > 0); |
1830 | 1810 |
1831 // Allocate one-byte string in new space. | 1811 // Allocate one-byte string in new space. |
1832 Allocate(SeqOneByteString::SizeFor(length), result, scratch1, scratch2, | 1812 Allocate(SeqOneByteString::SizeFor(length), result, scratch1, scratch2, |
1833 gc_required, TAG_OBJECT); | 1813 gc_required, NO_ALLOCATION_FLAGS); |
1834 | 1814 |
1835 // Set the map, length and hash field. | 1815 // Set the map, length and hash field. |
1836 mov(FieldOperand(result, HeapObject::kMapOffset), | 1816 mov(FieldOperand(result, HeapObject::kMapOffset), |
1837 Immediate(isolate()->factory()->one_byte_string_map())); | 1817 Immediate(isolate()->factory()->one_byte_string_map())); |
1838 mov(FieldOperand(result, String::kLengthOffset), | 1818 mov(FieldOperand(result, String::kLengthOffset), |
1839 Immediate(Smi::FromInt(length))); | 1819 Immediate(Smi::FromInt(length))); |
1840 mov(FieldOperand(result, String::kHashFieldOffset), | 1820 mov(FieldOperand(result, String::kHashFieldOffset), |
1841 Immediate(String::kEmptyHashField)); | 1821 Immediate(String::kEmptyHashField)); |
1842 } | 1822 } |
1843 | 1823 |
1844 | 1824 |
1845 void MacroAssembler::AllocateTwoByteConsString(Register result, | 1825 void MacroAssembler::AllocateTwoByteConsString(Register result, |
1846 Register scratch1, | 1826 Register scratch1, |
1847 Register scratch2, | 1827 Register scratch2, |
1848 Label* gc_required) { | 1828 Label* gc_required) { |
1849 // Allocate heap number in new space. | 1829 // Allocate heap number in new space. |
1850 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, | 1830 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, |
1851 TAG_OBJECT); | 1831 NO_ALLOCATION_FLAGS); |
1852 | 1832 |
1853 // Set the map. The other fields are left uninitialized. | 1833 // Set the map. The other fields are left uninitialized. |
1854 mov(FieldOperand(result, HeapObject::kMapOffset), | 1834 mov(FieldOperand(result, HeapObject::kMapOffset), |
1855 Immediate(isolate()->factory()->cons_string_map())); | 1835 Immediate(isolate()->factory()->cons_string_map())); |
1856 } | 1836 } |
1857 | 1837 |
1858 | 1838 |
1859 void MacroAssembler::AllocateOneByteConsString(Register result, | 1839 void MacroAssembler::AllocateOneByteConsString(Register result, |
1860 Register scratch1, | 1840 Register scratch1, |
1861 Register scratch2, | 1841 Register scratch2, |
1862 Label* gc_required) { | 1842 Label* gc_required) { |
1863 Allocate(ConsString::kSize, | 1843 Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, |
1864 result, | 1844 NO_ALLOCATION_FLAGS); |
1865 scratch1, | |
1866 scratch2, | |
1867 gc_required, | |
1868 TAG_OBJECT); | |
1869 | 1845 |
1870 // Set the map. The other fields are left uninitialized. | 1846 // Set the map. The other fields are left uninitialized. |
1871 mov(FieldOperand(result, HeapObject::kMapOffset), | 1847 mov(FieldOperand(result, HeapObject::kMapOffset), |
1872 Immediate(isolate()->factory()->cons_one_byte_string_map())); | 1848 Immediate(isolate()->factory()->cons_one_byte_string_map())); |
1873 } | 1849 } |
1874 | 1850 |
1875 | 1851 |
1876 void MacroAssembler::AllocateTwoByteSlicedString(Register result, | 1852 void MacroAssembler::AllocateTwoByteSlicedString(Register result, |
1877 Register scratch1, | 1853 Register scratch1, |
1878 Register scratch2, | 1854 Register scratch2, |
1879 Label* gc_required) { | 1855 Label* gc_required) { |
1880 // Allocate heap number in new space. | 1856 // Allocate heap number in new space. |
1881 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | 1857 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, |
1882 TAG_OBJECT); | 1858 NO_ALLOCATION_FLAGS); |
1883 | 1859 |
1884 // Set the map. The other fields are left uninitialized. | 1860 // Set the map. The other fields are left uninitialized. |
1885 mov(FieldOperand(result, HeapObject::kMapOffset), | 1861 mov(FieldOperand(result, HeapObject::kMapOffset), |
1886 Immediate(isolate()->factory()->sliced_string_map())); | 1862 Immediate(isolate()->factory()->sliced_string_map())); |
1887 } | 1863 } |
1888 | 1864 |
1889 | 1865 |
1890 void MacroAssembler::AllocateOneByteSlicedString(Register result, | 1866 void MacroAssembler::AllocateOneByteSlicedString(Register result, |
1891 Register scratch1, | 1867 Register scratch1, |
1892 Register scratch2, | 1868 Register scratch2, |
1893 Label* gc_required) { | 1869 Label* gc_required) { |
1894 // Allocate heap number in new space. | 1870 // Allocate heap number in new space. |
1895 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, | 1871 Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, |
1896 TAG_OBJECT); | 1872 NO_ALLOCATION_FLAGS); |
1897 | 1873 |
1898 // Set the map. The other fields are left uninitialized. | 1874 // Set the map. The other fields are left uninitialized. |
1899 mov(FieldOperand(result, HeapObject::kMapOffset), | 1875 mov(FieldOperand(result, HeapObject::kMapOffset), |
1900 Immediate(isolate()->factory()->sliced_one_byte_string_map())); | 1876 Immediate(isolate()->factory()->sliced_one_byte_string_map())); |
1901 } | 1877 } |
1902 | 1878 |
1903 | 1879 |
1904 void MacroAssembler::AllocateJSValue(Register result, Register constructor, | 1880 void MacroAssembler::AllocateJSValue(Register result, Register constructor, |
1905 Register value, Register scratch, | 1881 Register value, Register scratch, |
1906 Label* gc_required) { | 1882 Label* gc_required) { |
1907 DCHECK(!result.is(constructor)); | 1883 DCHECK(!result.is(constructor)); |
1908 DCHECK(!result.is(scratch)); | 1884 DCHECK(!result.is(scratch)); |
1909 DCHECK(!result.is(value)); | 1885 DCHECK(!result.is(value)); |
1910 | 1886 |
1911 // Allocate JSValue in new space. | 1887 // Allocate JSValue in new space. |
1912 Allocate(JSValue::kSize, result, scratch, no_reg, gc_required, TAG_OBJECT); | 1888 Allocate(JSValue::kSize, result, scratch, no_reg, gc_required, |
| 1889 NO_ALLOCATION_FLAGS); |
1913 | 1890 |
1914 // Initialize the JSValue. | 1891 // Initialize the JSValue. |
1915 LoadGlobalFunctionInitialMap(constructor, scratch); | 1892 LoadGlobalFunctionInitialMap(constructor, scratch); |
1916 mov(FieldOperand(result, HeapObject::kMapOffset), scratch); | 1893 mov(FieldOperand(result, HeapObject::kMapOffset), scratch); |
1917 LoadRoot(scratch, Heap::kEmptyFixedArrayRootIndex); | 1894 LoadRoot(scratch, Heap::kEmptyFixedArrayRootIndex); |
1918 mov(FieldOperand(result, JSObject::kPropertiesOffset), scratch); | 1895 mov(FieldOperand(result, JSObject::kPropertiesOffset), scratch); |
1919 mov(FieldOperand(result, JSObject::kElementsOffset), scratch); | 1896 mov(FieldOperand(result, JSObject::kElementsOffset), scratch); |
1920 mov(FieldOperand(result, JSValue::kValueOffset), value); | 1897 mov(FieldOperand(result, JSValue::kValueOffset), value); |
1921 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); | 1898 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); |
1922 } | 1899 } |
(...skipping 1500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3423 mov(eax, dividend); | 3400 mov(eax, dividend); |
3424 shr(eax, 31); | 3401 shr(eax, 31); |
3425 add(edx, eax); | 3402 add(edx, eax); |
3426 } | 3403 } |
3427 | 3404 |
3428 | 3405 |
3429 } // namespace internal | 3406 } // namespace internal |
3430 } // namespace v8 | 3407 } // namespace v8 |
3431 | 3408 |
3432 #endif // V8_TARGET_ARCH_IA32 | 3409 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |