| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1664 b(hi, gc_required); | 1664 b(hi, gc_required); |
| 1665 str(scratch2, MemOperand(topaddr)); | 1665 str(scratch2, MemOperand(topaddr)); |
| 1666 | 1666 |
| 1667 // Tag object if requested. | 1667 // Tag object if requested. |
| 1668 if ((flags & TAG_OBJECT) != 0) { | 1668 if ((flags & TAG_OBJECT) != 0) { |
| 1669 add(result, result, Operand(kHeapObjectTag)); | 1669 add(result, result, Operand(kHeapObjectTag)); |
| 1670 } | 1670 } |
| 1671 } | 1671 } |
| 1672 | 1672 |
| 1673 | 1673 |
| 1674 void MacroAssembler::AllocateInNewSpace(Register object_size, | 1674 void MacroAssembler::Allocate(Register object_size, |
| 1675 Register result, | 1675 Register result, |
| 1676 Register scratch1, | 1676 Register scratch1, |
| 1677 Register scratch2, | 1677 Register scratch2, |
| 1678 Label* gc_required, | 1678 Label* gc_required, |
| 1679 AllocationFlags flags) { | 1679 AllocationFlags flags) { |
| 1680 ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0); | |
| 1681 if (!FLAG_inline_new) { | 1680 if (!FLAG_inline_new) { |
| 1682 if (emit_debug_code()) { | 1681 if (emit_debug_code()) { |
| 1683 // Trash the registers to simulate an allocation failure. | 1682 // Trash the registers to simulate an allocation failure. |
| 1684 mov(result, Operand(0x7091)); | 1683 mov(result, Operand(0x7091)); |
| 1685 mov(scratch1, Operand(0x7191)); | 1684 mov(scratch1, Operand(0x7191)); |
| 1686 mov(scratch2, Operand(0x7291)); | 1685 mov(scratch2, Operand(0x7291)); |
| 1687 } | 1686 } |
| 1688 jmp(gc_required); | 1687 jmp(gc_required); |
| 1689 return; | 1688 return; |
| 1690 } | 1689 } |
| 1691 | 1690 |
| 1692 // Assert that the register arguments are different and that none of | 1691 // Assert that the register arguments are different and that none of |
| 1693 // them are ip. ip is used explicitly in the code generated below. | 1692 // them are ip. ip is used explicitly in the code generated below. |
| 1694 ASSERT(!result.is(scratch1)); | 1693 ASSERT(!result.is(scratch1)); |
| 1695 ASSERT(!result.is(scratch2)); | 1694 ASSERT(!result.is(scratch2)); |
| 1696 ASSERT(!scratch1.is(scratch2)); | 1695 ASSERT(!scratch1.is(scratch2)); |
| 1697 ASSERT(!object_size.is(ip)); | 1696 ASSERT(!object_size.is(ip)); |
| 1698 ASSERT(!result.is(ip)); | 1697 ASSERT(!result.is(ip)); |
| 1699 ASSERT(!scratch1.is(ip)); | 1698 ASSERT(!scratch1.is(ip)); |
| 1700 ASSERT(!scratch2.is(ip)); | 1699 ASSERT(!scratch2.is(ip)); |
| 1701 | 1700 |
| 1702 // Check relative positions of allocation top and limit addresses. | 1701 // Check relative positions of allocation top and limit addresses. |
| 1703 // The values must be adjacent in memory to allow the use of LDM. | 1702 // The values must be adjacent in memory to allow the use of LDM. |
| 1704 // Also, assert that the registers are numbered such that the values | 1703 // Also, assert that the registers are numbered such that the values |
| 1705 // are loaded in the correct order. | 1704 // are loaded in the correct order. |
| 1706 ExternalReference new_space_allocation_top = | 1705 ExternalReference allocation_top = |
| 1707 ExternalReference::new_space_allocation_top_address(isolate()); | 1706 AllocationUtils::GetAllocationTopReference(isolate(), flags); |
| 1708 ExternalReference new_space_allocation_limit = | 1707 ExternalReference allocation_limit = |
| 1709 ExternalReference::new_space_allocation_limit_address(isolate()); | 1708 AllocationUtils::GetAllocationLimitReference(isolate(), flags); |
| 1710 intptr_t top = | 1709 intptr_t top = |
| 1711 reinterpret_cast<intptr_t>(new_space_allocation_top.address()); | 1710 reinterpret_cast<intptr_t>(allocation_top.address()); |
| 1712 intptr_t limit = | 1711 intptr_t limit = |
| 1713 reinterpret_cast<intptr_t>(new_space_allocation_limit.address()); | 1712 reinterpret_cast<intptr_t>(allocation_limit.address()); |
| 1714 ASSERT((limit - top) == kPointerSize); | 1713 ASSERT((limit - top) == kPointerSize); |
| 1715 ASSERT(result.code() < ip.code()); | 1714 ASSERT(result.code() < ip.code()); |
| 1716 | 1715 |
| 1717 // Set up allocation top address. | 1716 // Set up allocation top address. |
| 1718 Register topaddr = scratch1; | 1717 Register topaddr = scratch1; |
| 1719 mov(topaddr, Operand(new_space_allocation_top)); | 1718 mov(topaddr, Operand(allocation_top)); |
| 1720 | 1719 |
| 1721 // This code stores a temporary value in ip. This is OK, as the code below | 1720 // This code stores a temporary value in ip. This is OK, as the code below |
| 1722 // does not need ip for implicit literal generation. | 1721 // does not need ip for implicit literal generation. |
| 1723 if ((flags & RESULT_CONTAINS_TOP) == 0) { | 1722 if ((flags & RESULT_CONTAINS_TOP) == 0) { |
| 1724 // Load allocation top into result and allocation limit into ip. | 1723 // Load allocation top into result and allocation limit into ip. |
| 1725 ldm(ia, topaddr, result.bit() | ip.bit()); | 1724 ldm(ia, topaddr, result.bit() | ip.bit()); |
| 1726 } else { | 1725 } else { |
| 1727 if (emit_debug_code()) { | 1726 if (emit_debug_code()) { |
| 1728 // Assert that result actually contains top on entry. ip is used | 1727 // Assert that result actually contains top on entry. ip is used |
| 1729 // immediately below so this use of ip does not cause difference with | 1728 // immediately below so this use of ip does not cause difference with |
| 1730 // respect to register content between debug and release mode. | 1729 // respect to register content between debug and release mode. |
| 1731 ldr(ip, MemOperand(topaddr)); | 1730 ldr(ip, MemOperand(topaddr)); |
| 1732 cmp(result, ip); | 1731 cmp(result, ip); |
| 1733 Check(eq, "Unexpected allocation top"); | 1732 Check(eq, "Unexpected allocation top"); |
| 1734 } | 1733 } |
| 1735 // Load allocation limit into ip. Result already contains allocation top. | 1734 // Load allocation limit into ip. Result already contains allocation top. |
| 1736 ldr(ip, MemOperand(topaddr, limit - top)); | 1735 ldr(ip, MemOperand(topaddr, limit - top)); |
| 1737 } | 1736 } |
| 1738 | 1737 |
| 1739 if ((flags & DOUBLE_ALIGNMENT) != 0) { | 1738 if ((flags & DOUBLE_ALIGNMENT) != 0) { |
| 1740 // Align the next allocation. Storing the filler map without checking top is | 1739 // Align the next allocation. Storing the filler map without checking top is |
| 1741 // always safe because the limit of the heap is always aligned. | 1740 // always safe because the limit of the heap is always aligned. |
| 1741 ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0); |
| 1742 ASSERT(kPointerAlignment * 2 == kDoubleAlignment); | 1742 ASSERT(kPointerAlignment * 2 == kDoubleAlignment); |
| 1743 and_(scratch2, result, Operand(kDoubleAlignmentMask), SetCC); | 1743 and_(scratch2, result, Operand(kDoubleAlignmentMask), SetCC); |
| 1744 Label aligned; | 1744 Label aligned; |
| 1745 b(eq, &aligned); | 1745 b(eq, &aligned); |
| 1746 mov(scratch2, Operand(isolate()->factory()->one_pointer_filler_map())); | 1746 mov(scratch2, Operand(isolate()->factory()->one_pointer_filler_map())); |
| 1747 str(scratch2, MemOperand(result, kDoubleSize / 2, PostIndex)); | 1747 str(scratch2, MemOperand(result, kDoubleSize / 2, PostIndex)); |
| 1748 bind(&aligned); | 1748 bind(&aligned); |
| 1749 } | 1749 } |
| 1750 | 1750 |
| 1751 // Calculate new top and bail out if new space is exhausted. Use result | 1751 // Calculate new top and bail out if new space is exhausted. Use result |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1802 Label* gc_required) { | 1802 Label* gc_required) { |
| 1803 // Calculate the number of bytes needed for the characters in the string while | 1803 // Calculate the number of bytes needed for the characters in the string while |
| 1804 // observing object alignment. | 1804 // observing object alignment. |
| 1805 ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); | 1805 ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
| 1806 mov(scratch1, Operand(length, LSL, 1)); // Length in bytes, not chars. | 1806 mov(scratch1, Operand(length, LSL, 1)); // Length in bytes, not chars. |
| 1807 add(scratch1, scratch1, | 1807 add(scratch1, scratch1, |
| 1808 Operand(kObjectAlignmentMask + SeqTwoByteString::kHeaderSize)); | 1808 Operand(kObjectAlignmentMask + SeqTwoByteString::kHeaderSize)); |
| 1809 and_(scratch1, scratch1, Operand(~kObjectAlignmentMask)); | 1809 and_(scratch1, scratch1, Operand(~kObjectAlignmentMask)); |
| 1810 | 1810 |
| 1811 // Allocate two-byte string in new space. | 1811 // Allocate two-byte string in new space. |
| 1812 AllocateInNewSpace(scratch1, | 1812 Allocate(scratch1, |
| 1813 result, | 1813 result, |
| 1814 scratch2, | 1814 scratch2, |
| 1815 scratch3, | 1815 scratch3, |
| 1816 gc_required, | 1816 gc_required, |
| 1817 TAG_OBJECT); | 1817 TAG_OBJECT); |
| 1818 | 1818 |
| 1819 // Set the map, length and hash field. | 1819 // Set the map, length and hash field. |
| 1820 InitializeNewString(result, | 1820 InitializeNewString(result, |
| 1821 length, | 1821 length, |
| 1822 Heap::kStringMapRootIndex, | 1822 Heap::kStringMapRootIndex, |
| 1823 scratch1, | 1823 scratch1, |
| 1824 scratch2); | 1824 scratch2); |
| 1825 } | 1825 } |
| 1826 | 1826 |
| 1827 | 1827 |
| 1828 void MacroAssembler::AllocateAsciiString(Register result, | 1828 void MacroAssembler::AllocateAsciiString(Register result, |
| 1829 Register length, | 1829 Register length, |
| 1830 Register scratch1, | 1830 Register scratch1, |
| 1831 Register scratch2, | 1831 Register scratch2, |
| 1832 Register scratch3, | 1832 Register scratch3, |
| 1833 Label* gc_required) { | 1833 Label* gc_required) { |
| 1834 // Calculate the number of bytes needed for the characters in the string while | 1834 // Calculate the number of bytes needed for the characters in the string while |
| 1835 // observing object alignment. | 1835 // observing object alignment. |
| 1836 ASSERT((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); | 1836 ASSERT((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0); |
| 1837 ASSERT(kCharSize == 1); | 1837 ASSERT(kCharSize == 1); |
| 1838 add(scratch1, length, | 1838 add(scratch1, length, |
| 1839 Operand(kObjectAlignmentMask + SeqOneByteString::kHeaderSize)); | 1839 Operand(kObjectAlignmentMask + SeqOneByteString::kHeaderSize)); |
| 1840 and_(scratch1, scratch1, Operand(~kObjectAlignmentMask)); | 1840 and_(scratch1, scratch1, Operand(~kObjectAlignmentMask)); |
| 1841 | 1841 |
| 1842 // Allocate ASCII string in new space. | 1842 // Allocate ASCII string in new space. |
| 1843 AllocateInNewSpace(scratch1, | 1843 Allocate(scratch1, |
| 1844 result, | 1844 result, |
| 1845 scratch2, | 1845 scratch2, |
| 1846 scratch3, | 1846 scratch3, |
| 1847 gc_required, | 1847 gc_required, |
| 1848 TAG_OBJECT); | 1848 TAG_OBJECT); |
| 1849 | 1849 |
| 1850 // Set the map, length and hash field. | 1850 // Set the map, length and hash field. |
| 1851 InitializeNewString(result, | 1851 InitializeNewString(result, |
| 1852 length, | 1852 length, |
| 1853 Heap::kAsciiStringMapRootIndex, | 1853 Heap::kAsciiStringMapRootIndex, |
| 1854 scratch1, | 1854 scratch1, |
| 1855 scratch2); | 1855 scratch2); |
| 1856 } | 1856 } |
| 1857 | 1857 |
| 1858 | 1858 |
| (...skipping 2090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3949 void CodePatcher::EmitCondition(Condition cond) { | 3949 void CodePatcher::EmitCondition(Condition cond) { |
| 3950 Instr instr = Assembler::instr_at(masm_.pc_); | 3950 Instr instr = Assembler::instr_at(masm_.pc_); |
| 3951 instr = (instr & ~kCondMask) | cond; | 3951 instr = (instr & ~kCondMask) | cond; |
| 3952 masm_.emit(instr); | 3952 masm_.emit(instr); |
| 3953 } | 3953 } |
| 3954 | 3954 |
| 3955 | 3955 |
| 3956 } } // namespace v8::internal | 3956 } } // namespace v8::internal |
| 3957 | 3957 |
| 3958 #endif // V8_TARGET_ARCH_ARM | 3958 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |