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

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