Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: runtime/vm/assembler_arm.cc

Issue 2112043002: Land Ivan's change of 'Remove support for verified memory handling' (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address code review comments. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/assembler_ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // NOLINT 5 #include "vm/globals.h" // NOLINT
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/longjump.h" 10 #include "vm/longjump.h"
(...skipping 1669 matching lines...) Expand 10 before | Expand all | Expand 10 after
1680 // For the value we are only interested in the new/old bit and the tag bit. 1680 // For the value we are only interested in the new/old bit and the tag bit.
1681 // And the new bit with the tag bit. The resulting bit will be 0 for a Smi. 1681 // And the new bit with the tag bit. The resulting bit will be 0 for a Smi.
1682 and_(IP, value, Operand(value, LSL, kObjectAlignmentLog2 - 1)); 1682 and_(IP, value, Operand(value, LSL, kObjectAlignmentLog2 - 1));
1683 // And the result with the negated space bit of the object. 1683 // And the result with the negated space bit of the object.
1684 bic(IP, IP, Operand(object)); 1684 bic(IP, IP, Operand(object));
1685 tst(IP, Operand(kNewObjectAlignmentOffset)); 1685 tst(IP, Operand(kNewObjectAlignmentOffset));
1686 b(no_update, EQ); 1686 b(no_update, EQ);
1687 } 1687 }
1688 1688
1689 1689
1690 Operand Assembler::GetVerifiedMemoryShadow() {
1691 Operand offset;
1692 if (!Operand::CanHold(VerifiedMemory::offset(), &offset)) {
1693 FATAL1("Offset 0x%" Px " not representable", VerifiedMemory::offset());
1694 }
1695 return offset;
1696 }
1697
1698
1699 void Assembler::WriteShadowedField(Register base,
1700 intptr_t offset,
1701 Register value,
1702 Condition cond) {
1703 if (VerifiedMemory::enabled()) {
1704 ASSERT(base != value);
1705 Operand shadow(GetVerifiedMemoryShadow());
1706 add(base, base, shadow, cond);
1707 str(value, Address(base, offset), cond);
1708 sub(base, base, shadow, cond);
1709 }
1710 str(value, Address(base, offset), cond);
1711 }
1712
1713
1714 void Assembler::WriteShadowedFieldPair(Register base,
1715 intptr_t offset,
1716 Register value_even,
1717 Register value_odd,
1718 Condition cond) {
1719 ASSERT(value_odd == value_even + 1);
1720 ASSERT(value_even % 2 == 0);
1721 if (VerifiedMemory::enabled()) {
1722 ASSERT(base != value_even);
1723 ASSERT(base != value_odd);
1724 Operand shadow(GetVerifiedMemoryShadow());
1725 add(base, base, shadow, cond);
1726 strd(value_even, value_odd, base, offset, cond);
1727 sub(base, base, shadow, cond);
1728 }
1729 strd(value_even, value_odd, base, offset, cond);
1730 }
1731
1732
1733 Register UseRegister(Register reg, RegList* used) { 1690 Register UseRegister(Register reg, RegList* used) {
1734 ASSERT(reg != THR); 1691 ASSERT(reg != THR);
1735 ASSERT(reg != SP); 1692 ASSERT(reg != SP);
1736 ASSERT(reg != FP); 1693 ASSERT(reg != FP);
1737 ASSERT(reg != PC); 1694 ASSERT(reg != PC);
1738 ASSERT((*used & (1 << reg)) == 0); 1695 ASSERT((*used & (1 << reg)) == 0);
1739 *used |= (1 << reg); 1696 *used |= (1 << reg);
1740 return reg; 1697 return reg;
1741 } 1698 }
1742 1699
1743 1700
1744 Register AllocateRegister(RegList* used) { 1701 Register AllocateRegister(RegList* used) {
1745 const RegList free = ~*used; 1702 const RegList free = ~*used;
1746 return (free == 0) ? 1703 return (free == 0) ?
1747 kNoRegister : 1704 kNoRegister :
1748 UseRegister(static_cast<Register>(Utils::CountTrailingZeros(free)), used); 1705 UseRegister(static_cast<Register>(Utils::CountTrailingZeros(free)), used);
1749 } 1706 }
1750 1707
1751 1708
1752 void Assembler::VerifiedWrite(Register object,
1753 const Address& address,
1754 Register new_value,
1755 FieldContent old_content) {
1756 #if defined(DEBUG)
1757 ASSERT(address.mode() == Address::Offset ||
1758 address.mode() == Address::NegOffset);
1759 // Allocate temporary registers (and check for register collisions).
1760 RegList used = 0;
1761 UseRegister(new_value, &used);
1762 Register base = UseRegister(address.rn(), &used);
1763 if ((object != base) && (object != kNoRegister)) {
1764 UseRegister(object, &used);
1765 }
1766 if (address.rm() != kNoRegister) {
1767 UseRegister(address.rm(), &used);
1768 }
1769 Register old_value = AllocateRegister(&used);
1770 Register temp = AllocateRegister(&used);
1771 PushList(used);
1772 ldr(old_value, address);
1773 // First check that 'old_value' contains 'old_content'.
1774 // Smi test.
1775 tst(old_value, Operand(kHeapObjectTag));
1776 Label ok;
1777 switch (old_content) {
1778 case kOnlySmi:
1779 b(&ok, EQ); // Smi is OK.
1780 Stop("Expected smi.");
1781 break;
1782 case kHeapObjectOrSmi:
1783 b(&ok, EQ); // Smi is OK.
1784 // Non-smi case: Verify object pointer is word-aligned when untagged.
1785 COMPILE_ASSERT(kHeapObjectTag == 1);
1786 tst(old_value, Operand((kWordSize - 1) - kHeapObjectTag));
1787 b(&ok, EQ);
1788 Stop("Expected heap object or Smi");
1789 break;
1790 case kEmptyOrSmiOrNull:
1791 b(&ok, EQ); // Smi is OK.
1792 // Non-smi case: Check for the special zap word or null.
1793 // Note: Cannot use CompareImmediate, since IP may be in use.
1794 LoadImmediate(temp, Heap::kZap32Bits);
1795 cmp(old_value, Operand(temp));
1796 b(&ok, EQ);
1797 LoadObject(temp, Object::null_object());
1798 cmp(old_value, Operand(temp));
1799 b(&ok, EQ);
1800 Stop("Expected zapped, Smi or null");
1801 break;
1802 default:
1803 UNREACHABLE();
1804 }
1805 Bind(&ok);
1806 if (VerifiedMemory::enabled()) {
1807 Operand shadow_offset(GetVerifiedMemoryShadow());
1808 // Adjust the address to shadow.
1809 add(base, base, shadow_offset);
1810 ldr(temp, address);
1811 cmp(old_value, Operand(temp));
1812 Label match;
1813 b(&match, EQ);
1814 Stop("Write barrier verification failed");
1815 Bind(&match);
1816 // Write new value in shadow.
1817 str(new_value, address);
1818 // Restore original address.
1819 sub(base, base, shadow_offset);
1820 }
1821 str(new_value, address);
1822 PopList(used);
1823 #else
1824 str(new_value, address);
1825 #endif // DEBUG
1826 }
1827
1828
1829 void Assembler::StoreIntoObject(Register object, 1709 void Assembler::StoreIntoObject(Register object,
1830 const Address& dest, 1710 const Address& dest,
1831 Register value, 1711 Register value,
1832 bool can_value_be_smi) { 1712 bool can_value_be_smi) {
1833 ASSERT(object != value); 1713 ASSERT(object != value);
1834 VerifiedWrite(object, dest, value, kHeapObjectOrSmi); 1714 str(value, dest);
1835 Label done; 1715 Label done;
1836 if (can_value_be_smi) { 1716 if (can_value_be_smi) {
1837 StoreIntoObjectFilter(object, value, &done); 1717 StoreIntoObjectFilter(object, value, &done);
1838 } else { 1718 } else {
1839 StoreIntoObjectFilterNoSmi(object, value, &done); 1719 StoreIntoObjectFilterNoSmi(object, value, &done);
1840 } 1720 }
1841 // A store buffer update is required. 1721 // A store buffer update is required.
1842 RegList regs = (1 << CODE_REG) | (1 << LR); 1722 RegList regs = (1 << CODE_REG) | (1 << LR);
1843 if (value != R0) { 1723 if (value != R0) {
1844 regs |= (1 << R0); // Preserve R0. 1724 regs |= (1 << R0); // Preserve R0.
(...skipping 20 matching lines...) Expand all
1865 object, FieldAddress(object, offset), value, can_value_be_smi); 1745 object, FieldAddress(object, offset), value, can_value_be_smi);
1866 } else { 1746 } else {
1867 AddImmediate(IP, object, offset - kHeapObjectTag); 1747 AddImmediate(IP, object, offset - kHeapObjectTag);
1868 StoreIntoObject(object, Address(IP), value, can_value_be_smi); 1748 StoreIntoObject(object, Address(IP), value, can_value_be_smi);
1869 } 1749 }
1870 } 1750 }
1871 1751
1872 1752
1873 void Assembler::StoreIntoObjectNoBarrier(Register object, 1753 void Assembler::StoreIntoObjectNoBarrier(Register object,
1874 const Address& dest, 1754 const Address& dest,
1875 Register value, 1755 Register value) {
1876 FieldContent old_content) { 1756 str(value, dest);
1877 VerifiedWrite(object, dest, value, old_content);
1878 #if defined(DEBUG) 1757 #if defined(DEBUG)
1879 Label done; 1758 Label done;
1880 StoreIntoObjectFilter(object, value, &done); 1759 StoreIntoObjectFilter(object, value, &done);
1881 Stop("Store buffer update is required"); 1760 Stop("Store buffer update is required");
1882 Bind(&done); 1761 Bind(&done);
1883 #endif // defined(DEBUG) 1762 #endif // defined(DEBUG)
1884 // No store buffer update. 1763 // No store buffer update.
1885 } 1764 }
1886 1765
1887 1766
1888 void Assembler::StoreIntoObjectNoBarrierOffset(Register object,
1889 int32_t offset,
1890 Register value,
1891 FieldContent old_content) {
1892 int32_t ignored = 0;
1893 if (Address::CanHoldStoreOffset(kWord, offset - kHeapObjectTag, &ignored)) {
1894 StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value,
1895 old_content);
1896 } else {
1897 AddImmediate(IP, object, offset - kHeapObjectTag);
1898 StoreIntoObjectNoBarrier(object, Address(IP), value, old_content);
1899 }
1900 }
1901
1902
1903 void Assembler::StoreIntoObjectNoBarrier(Register object, 1767 void Assembler::StoreIntoObjectNoBarrier(Register object,
1904 const Address& dest, 1768 const Address& dest,
1905 const Object& value, 1769 const Object& value) {
1906 FieldContent old_content) {
1907 ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal()); 1770 ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal());
1908 ASSERT(!value.IsField() || Field::Cast(value).IsOriginal()); 1771 ASSERT(!value.IsField() || Field::Cast(value).IsOriginal());
1909 ASSERT(value.IsSmi() || value.InVMHeap() || 1772 ASSERT(value.IsSmi() || value.InVMHeap() ||
1910 (value.IsOld() && value.IsNotTemporaryScopedHandle())); 1773 (value.IsOld() && value.IsNotTemporaryScopedHandle()));
1911 // No store buffer update. 1774 // No store buffer update.
1912 LoadObject(IP, value); 1775 LoadObject(IP, value);
1913 VerifiedWrite(object, dest, IP, old_content); 1776 str(IP, dest);
1914 } 1777 }
1915 1778
1916 1779
1917 void Assembler::StoreIntoObjectNoBarrierOffset(Register object, 1780 void Assembler::StoreIntoObjectNoBarrierOffset(Register object,
1918 int32_t offset, 1781 int32_t offset,
1919 const Object& value, 1782 Register value) {
1920 FieldContent old_content) { 1783 int32_t ignored = 0;
1784 if (Address::CanHoldStoreOffset(kWord, offset - kHeapObjectTag, &ignored)) {
1785 StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value);
1786 } else {
1787 Register base = object == R9 ? R8 : R9;
1788 Push(base);
1789 AddImmediate(base, object, offset - kHeapObjectTag);
1790 StoreIntoObjectNoBarrier(object, Address(base), value);
1791 Pop(base);
1792 }
1793 }
1794
1795
1796 void Assembler::StoreIntoObjectNoBarrierOffset(Register object,
1797 int32_t offset,
1798 const Object& value) {
1921 ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal()); 1799 ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal());
1922 ASSERT(!value.IsField() || Field::Cast(value).IsOriginal()); 1800 ASSERT(!value.IsField() || Field::Cast(value).IsOriginal());
1923 int32_t ignored = 0; 1801 int32_t ignored = 0;
1924 if (Address::CanHoldStoreOffset(kWord, offset - kHeapObjectTag, &ignored)) { 1802 if (Address::CanHoldStoreOffset(kWord, offset - kHeapObjectTag, &ignored)) {
1925 StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value, 1803 StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value);
1926 old_content);
1927 } else { 1804 } else {
1928 Register base = object == R9 ? R8 : R9; 1805 Register base = object == R9 ? R8 : R9;
1929 Push(base); 1806 Push(base);
1930 AddImmediate(base, object, offset - kHeapObjectTag); 1807 AddImmediate(base, object, offset - kHeapObjectTag);
1931 StoreIntoObjectNoBarrier(object, Address(base), value, old_content); 1808 StoreIntoObjectNoBarrier(object, Address(base), value);
1932 Pop(base); 1809 Pop(base);
1933 } 1810 }
1934 } 1811 }
1935 1812
1936 1813
1937 void Assembler::InitializeFieldsNoBarrier(Register object, 1814 void Assembler::InitializeFieldsNoBarrier(Register object,
1938 Register begin, 1815 Register begin,
1939 Register end, 1816 Register end,
1940 Register value_even, 1817 Register value_even,
1941 Register value_odd) { 1818 Register value_odd) {
1942 ASSERT(value_odd == value_even + 1); 1819 ASSERT(value_odd == value_even + 1);
1943 Label init_loop; 1820 Label init_loop;
1944 Bind(&init_loop); 1821 Bind(&init_loop);
1945 AddImmediate(begin, 2 * kWordSize); 1822 AddImmediate(begin, 2 * kWordSize);
1946 cmp(begin, Operand(end)); 1823 cmp(begin, Operand(end));
1947 WriteShadowedFieldPair(begin, -2 * kWordSize, value_even, value_odd, LS); 1824 strd(value_even, value_odd, begin, -2 * kWordSize, LS);
1948 b(&init_loop, CC); 1825 b(&init_loop, CC);
1949 WriteShadowedField(begin, -2 * kWordSize, value_even, HI); 1826 str(value_even, Address(begin, -2 * kWordSize), HI);
1950 #if defined(DEBUG) 1827 #if defined(DEBUG)
1951 Label done; 1828 Label done;
1952 StoreIntoObjectFilter(object, value_even, &done); 1829 StoreIntoObjectFilter(object, value_even, &done);
1953 StoreIntoObjectFilter(object, value_odd, &done); 1830 StoreIntoObjectFilter(object, value_odd, &done);
1954 Stop("Store buffer update is required"); 1831 Stop("Store buffer update is required");
1955 Bind(&done); 1832 Bind(&done);
1956 #endif // defined(DEBUG) 1833 #endif // defined(DEBUG)
1957 // No store buffer update. 1834 // No store buffer update.
1958 } 1835 }
1959 1836
1960 1837
1961 void Assembler::InitializeFieldsNoBarrierUnrolled(Register object, 1838 void Assembler::InitializeFieldsNoBarrierUnrolled(Register object,
1962 Register base, 1839 Register base,
1963 intptr_t begin_offset, 1840 intptr_t begin_offset,
1964 intptr_t end_offset, 1841 intptr_t end_offset,
1965 Register value_even, 1842 Register value_even,
1966 Register value_odd) { 1843 Register value_odd) {
1967 ASSERT(value_odd == value_even + 1); 1844 ASSERT(value_odd == value_even + 1);
1968 intptr_t current_offset = begin_offset; 1845 intptr_t current_offset = begin_offset;
1969 while (current_offset + kWordSize < end_offset) { 1846 while (current_offset + kWordSize < end_offset) {
1970 WriteShadowedFieldPair(base, current_offset, value_even, value_odd); 1847 strd(value_even, value_odd, base, current_offset);
1971 current_offset += 2*kWordSize; 1848 current_offset += 2*kWordSize;
1972 } 1849 }
1973 while (current_offset < end_offset) { 1850 while (current_offset < end_offset) {
1974 WriteShadowedField(base, current_offset, value_even); 1851 str(value_even, Address(base, current_offset));
1975 current_offset += kWordSize; 1852 current_offset += kWordSize;
1976 } 1853 }
1977 #if defined(DEBUG) 1854 #if defined(DEBUG)
1978 Label done; 1855 Label done;
1979 StoreIntoObjectFilter(object, value_even, &done); 1856 StoreIntoObjectFilter(object, value_even, &done);
1980 StoreIntoObjectFilter(object, value_odd, &done); 1857 StoreIntoObjectFilter(object, value_odd, &done);
1981 Stop("Store buffer update is required"); 1858 Stop("Store buffer update is required");
1982 Bind(&done); 1859 Bind(&done);
1983 #endif // defined(DEBUG) 1860 #endif // defined(DEBUG)
1984 // No store buffer update. 1861 // No store buffer update.
1985 } 1862 }
1986 1863
1987 1864
1988 void Assembler::StoreIntoSmiField(const Address& dest, Register value) { 1865 void Assembler::StoreIntoSmiField(const Address& dest, Register value) {
1989 #if defined(DEBUG) 1866 #if defined(DEBUG)
1990 Label done; 1867 Label done;
1991 tst(value, Operand(kHeapObjectTag)); 1868 tst(value, Operand(kHeapObjectTag));
1992 b(&done, EQ); 1869 b(&done, EQ);
1993 Stop("New value must be Smi."); 1870 Stop("New value must be Smi.");
1994 Bind(&done); 1871 Bind(&done);
1995 #endif // defined(DEBUG) 1872 #endif // defined(DEBUG)
1996 VerifiedWrite(kNoRegister, dest, value, kOnlySmi); 1873 str(value, dest);
1997 } 1874 }
1998 1875
1999 1876
2000 void Assembler::LoadClassId(Register result, Register object, Condition cond) { 1877 void Assembler::LoadClassId(Register result, Register object, Condition cond) {
2001 ASSERT(RawObject::kClassIdTagPos == 16); 1878 ASSERT(RawObject::kClassIdTagPos == 16);
2002 ASSERT(RawObject::kClassIdTagSize == 16); 1879 ASSERT(RawObject::kClassIdTagSize == 16);
2003 const intptr_t class_id_offset = Object::tags_offset() + 1880 const intptr_t class_id_offset = Object::tags_offset() +
2004 RawObject::kClassIdTagPos / kBitsPerByte; 1881 RawObject::kClassIdTagPos / kBitsPerByte;
2005 ldrh(result, FieldAddress(object, class_id_offset), cond); 1882 ldrh(result, FieldAddress(object, class_id_offset), cond);
2006 } 1883 }
(...skipping 1663 matching lines...) Expand 10 before | Expand all | Expand 10 after
3670 3547
3671 3548
3672 const char* Assembler::FpuRegisterName(FpuRegister reg) { 3549 const char* Assembler::FpuRegisterName(FpuRegister reg) {
3673 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); 3550 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters));
3674 return fpu_reg_names[reg]; 3551 return fpu_reg_names[reg];
3675 } 3552 }
3676 3553
3677 } // namespace dart 3554 } // namespace dart
3678 3555
3679 #endif // defined TARGET_ARCH_ARM 3556 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/assembler_ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698