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 |