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

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

Issue 841343002: ARM port of r42723. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/flow_graph_compiler_arm.cc » ('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 1682 matching lines...) Expand 10 before | Expand all | Expand 10 after
1693 1693
1694 1694
1695 Register AllocateRegister(RegList* used) { 1695 Register AllocateRegister(RegList* used) {
1696 const RegList free = ~*used; 1696 const RegList free = ~*used;
1697 return (free == 0) ? 1697 return (free == 0) ?
1698 kNoRegister : 1698 kNoRegister :
1699 UseRegister(static_cast<Register>(Utils::CountTrailingZeros(free)), used); 1699 UseRegister(static_cast<Register>(Utils::CountTrailingZeros(free)), used);
1700 } 1700 }
1701 1701
1702 1702
1703 void Assembler::VerifiedWrite(const Address& address, Register new_value) { 1703 void Assembler::VerifiedWrite(const Address& address,
1704 Register new_value,
1705 FieldContent old_content) {
1706 #if defined(DEBUG)
1707 ASSERT(address.mode() == Address::Offset ||
1708 address.mode() == Address::NegOffset);
1709 // Allocate temporary registers (and check for register collisions).
1710 RegList used = 0;
1711 UseRegister(new_value, &used);
1712 Register base = UseRegister(address.rn(), &used);
1713 if (address.rm() != kNoRegister) {
1714 UseRegister(address.rm(), &used);
1715 }
1716 Register old_value = AllocateRegister(&used);
1717 Register temp = AllocateRegister(&used);
1718 PushList(used);
1719 ldr(old_value, address);
1720 // First check that 'old_value' contains 'old_content'.
1721 // Smi test.
1722 tst(old_value, Operand(kHeapObjectTag));
1723 Label ok;
1724 switch (old_content) {
1725 case kOnlySmi:
1726 b(&ok, EQ); // Smi is OK.
1727 Stop("Expected smi.");
1728 break;
1729 case kHeapObjectOrSmi:
1730 b(&ok, EQ); // Smi is OK.
1731 // Non-smi case: Verify object pointer is word-aligned when untagged.
1732 COMPILE_ASSERT(kHeapObjectTag == 1);
1733 tst(old_value, Operand((kWordSize - 1) - kHeapObjectTag));
1734 b(&ok, EQ);
1735 Stop("Expected heap object or Smi");
1736 break;
1737 case kEmptyOrSmiOrNull:
1738 b(&ok, EQ); // Smi is OK.
1739 // Non-smi case: Check for the special zap word or null.
1740 // Note: Cannot use CompareImmediate, since IP may be in use.
1741 LoadImmediate(temp, Heap::kZap32Bits);
1742 cmp(old_value, Operand(temp));
1743 b(&ok, EQ);
1744 LoadImmediate(temp, reinterpret_cast<uint32_t>(Object::null()));
1745 cmp(old_value, Operand(temp));
1746 b(&ok, EQ);
1747 Stop("Expected zapped, Smi or null");
1748 break;
1749 default:
1750 UNREACHABLE();
1751 }
1752 Bind(&ok);
1704 if (VerifiedMemory::enabled()) { 1753 if (VerifiedMemory::enabled()) {
1705 ASSERT(address.mode() == Address::Offset ||
1706 address.mode() == Address::NegOffset);
1707 // Allocate temporary registers (and check for register collisions).
1708 RegList used = 0;
1709 UseRegister(new_value, &used);
1710 Register base = UseRegister(address.rn(), &used);
1711 if (address.rm() != kNoRegister) UseRegister(address.rm(), &used);
1712 Register old_value = AllocateRegister(&used);
1713 Register shadow_value = AllocateRegister(&used);
1714 PushList(used);
1715 // Verify old value.
1716 ldr(old_value, address);
1717 Operand shadow_offset(GetVerifiedMemoryShadow()); 1754 Operand shadow_offset(GetVerifiedMemoryShadow());
1755 // Adjust the address to shadow.
1718 add(base, base, shadow_offset); 1756 add(base, base, shadow_offset);
1719 ldr(shadow_value, address); 1757 ldr(temp, address);
1720 cmp(old_value, Operand(shadow_value)); 1758 cmp(old_value, Operand(temp));
1721 Label ok; 1759 Label match;
1722 b(&ok); 1760 b(&match, EQ);
1723 Stop("Write barrier verification failed"); 1761 Stop("Write barrier verification failed");
1724 Bind(&ok); 1762 Bind(&match);
1725 // Write new value. 1763 // Write new value in shadow.
1726 str(new_value, address); 1764 str(new_value, address);
1765 // Restore original address.
1727 sub(base, base, shadow_offset); 1766 sub(base, base, shadow_offset);
1728 str(new_value, address);
1729 PopList(used);
1730 } else {
1731 str(new_value, address);
1732 } 1767 }
1768 str(new_value, address);
1769 PopList(used);
1770 #else
1771 str(new_value, address);
1772 #endif // DEBUG
1733 } 1773 }
1734 1774
1735 1775
1736 void Assembler::StoreIntoObject(Register object, 1776 void Assembler::StoreIntoObject(Register object,
1737 const Address& dest, 1777 const Address& dest,
1738 Register value, 1778 Register value,
1739 bool can_value_be_smi) { 1779 bool can_value_be_smi) {
1740 ASSERT(object != value); 1780 ASSERT(object != value);
1741 VerifiedWrite(dest, value); 1781 VerifiedWrite(dest, value, kHeapObjectOrSmi);
1742 Label done; 1782 Label done;
1743 if (can_value_be_smi) { 1783 if (can_value_be_smi) {
1744 StoreIntoObjectFilter(object, value, &done); 1784 StoreIntoObjectFilter(object, value, &done);
1745 } else { 1785 } else {
1746 StoreIntoObjectFilterNoSmi(object, value, &done); 1786 StoreIntoObjectFilterNoSmi(object, value, &done);
1747 } 1787 }
1748 // A store buffer update is required. 1788 // A store buffer update is required.
1749 RegList regs = (1 << LR); 1789 RegList regs = (1 << LR);
1750 if (value != R0) { 1790 if (value != R0) {
1751 regs |= (1 << R0); // Preserve R0. 1791 regs |= (1 << R0); // Preserve R0.
(...skipping 19 matching lines...) Expand all
1771 object, FieldAddress(object, offset), value, can_value_be_smi); 1811 object, FieldAddress(object, offset), value, can_value_be_smi);
1772 } else { 1812 } else {
1773 AddImmediate(IP, object, offset - kHeapObjectTag); 1813 AddImmediate(IP, object, offset - kHeapObjectTag);
1774 StoreIntoObject(object, Address(IP), value, can_value_be_smi); 1814 StoreIntoObject(object, Address(IP), value, can_value_be_smi);
1775 } 1815 }
1776 } 1816 }
1777 1817
1778 1818
1779 void Assembler::StoreIntoObjectNoBarrier(Register object, 1819 void Assembler::StoreIntoObjectNoBarrier(Register object,
1780 const Address& dest, 1820 const Address& dest,
1781 Register value) { 1821 Register value,
1782 VerifiedWrite(dest, value); 1822 FieldContent old_content) {
1823 VerifiedWrite(dest, value, old_content);
1783 #if defined(DEBUG) 1824 #if defined(DEBUG)
1784 Label done; 1825 Label done;
1785 StoreIntoObjectFilter(object, value, &done); 1826 StoreIntoObjectFilter(object, value, &done);
1786 Stop("Store buffer update is required"); 1827 Stop("Store buffer update is required");
1787 Bind(&done); 1828 Bind(&done);
1788 #endif // defined(DEBUG) 1829 #endif // defined(DEBUG)
1789 // No store buffer update. 1830 // No store buffer update.
1790 } 1831 }
1791 1832
1792 1833
1793 void Assembler::StoreIntoObjectNoBarrierOffset(Register object, 1834 void Assembler::StoreIntoObjectNoBarrierOffset(Register object,
1794 int32_t offset, 1835 int32_t offset,
1795 Register value) { 1836 Register value,
1837 FieldContent old_content) {
1796 int32_t ignored = 0; 1838 int32_t ignored = 0;
1797 if (Address::CanHoldStoreOffset(kWord, offset - kHeapObjectTag, &ignored)) { 1839 if (Address::CanHoldStoreOffset(kWord, offset - kHeapObjectTag, &ignored)) {
1798 StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value); 1840 StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value,
1841 old_content);
1799 } else { 1842 } else {
1800 AddImmediate(IP, object, offset - kHeapObjectTag); 1843 AddImmediate(IP, object, offset - kHeapObjectTag);
1801 StoreIntoObjectNoBarrier(object, Address(IP), value); 1844 StoreIntoObjectNoBarrier(object, Address(IP), value, old_content);
1802 } 1845 }
1803 } 1846 }
1804 1847
1805 1848
1806 void Assembler::StoreIntoObjectNoBarrier(Register object, 1849 void Assembler::StoreIntoObjectNoBarrier(Register object,
1807 const Address& dest, 1850 const Address& dest,
1808 const Object& value) { 1851 const Object& value,
1852 FieldContent old_content) {
1809 ASSERT(value.IsSmi() || value.InVMHeap() || 1853 ASSERT(value.IsSmi() || value.InVMHeap() ||
1810 (value.IsOld() && value.IsNotTemporaryScopedHandle())); 1854 (value.IsOld() && value.IsNotTemporaryScopedHandle()));
1811 // No store buffer update. 1855 // No store buffer update.
1812 LoadObject(IP, value); 1856 LoadObject(IP, value);
1813 VerifiedWrite(dest, IP); 1857 VerifiedWrite(dest, IP, old_content);
1814 } 1858 }
1815 1859
1816 1860
1817 void Assembler::StoreIntoObjectNoBarrierOffset(Register object, 1861 void Assembler::StoreIntoObjectNoBarrierOffset(Register object,
1818 int32_t offset, 1862 int32_t offset,
1819 const Object& value) { 1863 const Object& value,
1864 FieldContent old_content) {
1820 int32_t ignored = 0; 1865 int32_t ignored = 0;
1821 if (Address::CanHoldStoreOffset(kWord, offset - kHeapObjectTag, &ignored)) { 1866 if (Address::CanHoldStoreOffset(kWord, offset - kHeapObjectTag, &ignored)) {
1822 StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value); 1867 StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value,
1868 old_content);
1823 } else { 1869 } else {
1824 AddImmediate(IP, object, offset - kHeapObjectTag); 1870 AddImmediate(IP, object, offset - kHeapObjectTag);
1825 StoreIntoObjectNoBarrier(object, Address(IP), value); 1871 StoreIntoObjectNoBarrier(object, Address(IP), value, old_content);
1826 } 1872 }
1827 } 1873 }
1828 1874
1829 1875
1830 void Assembler::InitializeFieldsNoBarrier(Register object, 1876 void Assembler::InitializeFieldsNoBarrier(Register object,
1831 Register begin, 1877 Register begin,
1832 Register end, 1878 Register end,
1833 Register value_even, 1879 Register value_even,
1834 Register value_odd) { 1880 Register value_odd) {
1835 ASSERT(value_odd == value_even + 1); 1881 ASSERT(value_odd == value_even + 1);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1872 StoreIntoObjectFilter(object, value_even, &done); 1918 StoreIntoObjectFilter(object, value_even, &done);
1873 StoreIntoObjectFilter(object, value_odd, &done); 1919 StoreIntoObjectFilter(object, value_odd, &done);
1874 Stop("Store buffer update is required"); 1920 Stop("Store buffer update is required");
1875 Bind(&done); 1921 Bind(&done);
1876 #endif // defined(DEBUG) 1922 #endif // defined(DEBUG)
1877 // No store buffer update. 1923 // No store buffer update.
1878 } 1924 }
1879 1925
1880 1926
1881 void Assembler::StoreIntoSmiField(const Address& dest, Register value) { 1927 void Assembler::StoreIntoSmiField(const Address& dest, Register value) {
1882 // TODO(koda): Verify previous value was Smi.
1883 VerifiedWrite(dest, value);
1884 #if defined(DEBUG) 1928 #if defined(DEBUG)
1885 Label done; 1929 Label done;
1886 tst(value, Operand(kHeapObjectTag)); 1930 tst(value, Operand(kHeapObjectTag));
1887 b(&done, EQ); 1931 b(&done, EQ);
1888 Stop("Smi expected"); 1932 Stop("New value must be Smi.");
1889 Bind(&done); 1933 Bind(&done);
1890 #endif // defined(DEBUG) 1934 #endif // defined(DEBUG)
1935 VerifiedWrite(dest, value, kOnlySmi);
1891 } 1936 }
1892 1937
1893 1938
1894 void Assembler::LoadClassId(Register result, Register object, Condition cond) { 1939 void Assembler::LoadClassId(Register result, Register object, Condition cond) {
1895 ASSERT(RawObject::kClassIdTagPos == 16); 1940 ASSERT(RawObject::kClassIdTagPos == 16);
1896 ASSERT(RawObject::kClassIdTagSize == 16); 1941 ASSERT(RawObject::kClassIdTagSize == 16);
1897 const intptr_t class_id_offset = Object::tags_offset() + 1942 const intptr_t class_id_offset = Object::tags_offset() +
1898 RawObject::kClassIdTagPos / kBitsPerByte; 1943 RawObject::kClassIdTagPos / kBitsPerByte;
1899 ldrh(result, FieldAddress(object, class_id_offset), cond); 1944 ldrh(result, FieldAddress(object, class_id_offset), cond);
1900 } 1945 }
(...skipping 1720 matching lines...) Expand 10 before | Expand all | Expand 10 after
3621 3666
3622 3667
3623 const char* Assembler::FpuRegisterName(FpuRegister reg) { 3668 const char* Assembler::FpuRegisterName(FpuRegister reg) {
3624 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); 3669 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters));
3625 return fpu_reg_names[reg]; 3670 return fpu_reg_names[reg];
3626 } 3671 }
3627 3672
3628 } // namespace dart 3673 } // namespace dart
3629 3674
3630 #endif // defined TARGET_ARCH_ARM 3675 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/flow_graph_compiler_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698