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

Side by Side Diff: src/s390/macro-assembler-s390.cc

Issue 1973883003: S390: [crankshaft] Fragmentation-free allocation folding. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: use kNear more Created 4 years, 7 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 | « src/s390/macro-assembler-s390.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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 #include <assert.h> // For assert 5 #include <assert.h> // For assert
6 #include <limits.h> // For LONG_MIN, LONG_MAX. 6 #include <limits.h> // For LONG_MIN, LONG_MAX.
7 7
8 #if V8_TARGET_ARCH_S390 8 #if V8_TARGET_ARCH_S390
9 9
10 #include "src/base/bits.h" 10 #include "src/base/bits.h"
(...skipping 1688 matching lines...) Expand 10 before | Expand all | Expand 10 after
1699 // Get the value at the masked, scaled index and return. 1699 // Get the value at the masked, scaled index and return.
1700 const int kValueOffset = 1700 const int kValueOffset =
1701 SeededNumberDictionary::kElementsStartOffset + kPointerSize; 1701 SeededNumberDictionary::kElementsStartOffset + kPointerSize;
1702 LoadP(result, FieldMemOperand(t2, kValueOffset)); 1702 LoadP(result, FieldMemOperand(t2, kValueOffset));
1703 } 1703 }
1704 1704
1705 void MacroAssembler::Allocate(int object_size, Register result, 1705 void MacroAssembler::Allocate(int object_size, Register result,
1706 Register scratch1, Register scratch2, 1706 Register scratch1, Register scratch2,
1707 Label* gc_required, AllocationFlags flags) { 1707 Label* gc_required, AllocationFlags flags) {
1708 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); 1708 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize);
1709 DCHECK((flags & ALLOCATION_FOLDED) == 0);
1709 if (!FLAG_inline_new) { 1710 if (!FLAG_inline_new) {
1710 if (emit_debug_code()) { 1711 if (emit_debug_code()) {
1711 // Trash the registers to simulate an allocation failure. 1712 // Trash the registers to simulate an allocation failure.
1712 LoadImmP(result, Operand(0x7091)); 1713 LoadImmP(result, Operand(0x7091));
1713 LoadImmP(scratch1, Operand(0x7191)); 1714 LoadImmP(scratch1, Operand(0x7191));
1714 LoadImmP(scratch2, Operand(0x7291)); 1715 LoadImmP(scratch2, Operand(0x7291));
1715 } 1716 }
1716 b(gc_required); 1717 b(gc_required);
1717 return; 1718 return;
1718 } 1719 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1760 1761
1761 if ((flags & DOUBLE_ALIGNMENT) != 0) { 1762 if ((flags & DOUBLE_ALIGNMENT) != 0) {
1762 // Align the next allocation. Storing the filler map without checking top is 1763 // Align the next allocation. Storing the filler map without checking top is
1763 // safe in new-space because the limit of the heap is aligned there. 1764 // safe in new-space because the limit of the heap is aligned there.
1764 #if V8_TARGET_ARCH_S390X 1765 #if V8_TARGET_ARCH_S390X
1765 STATIC_ASSERT(kPointerAlignment == kDoubleAlignment); 1766 STATIC_ASSERT(kPointerAlignment == kDoubleAlignment);
1766 #else 1767 #else
1767 STATIC_ASSERT(kPointerAlignment * 2 == kDoubleAlignment); 1768 STATIC_ASSERT(kPointerAlignment * 2 == kDoubleAlignment);
1768 AndP(result_end, result, Operand(kDoubleAlignmentMask)); 1769 AndP(result_end, result, Operand(kDoubleAlignmentMask));
1769 Label aligned; 1770 Label aligned;
1770 beq(&aligned); 1771 beq(&aligned, Label::kNear);
1771 if ((flags & PRETENURE) != 0) { 1772 if ((flags & PRETENURE) != 0) {
1772 CmpLogicalP(result, alloc_limit); 1773 CmpLogicalP(result, alloc_limit);
1773 bge(gc_required); 1774 bge(gc_required);
1774 } 1775 }
1775 mov(result_end, Operand(isolate()->factory()->one_pointer_filler_map())); 1776 mov(result_end, Operand(isolate()->factory()->one_pointer_filler_map()));
1776 StoreW(result_end, MemOperand(result)); 1777 StoreW(result_end, MemOperand(result));
1777 AddP(result, result, Operand(kDoubleSize / 2)); 1778 AddP(result, result, Operand(kDoubleSize / 2));
1778 bind(&aligned); 1779 bind(&aligned);
1779 #endif 1780 #endif
1780 } 1781 }
1781 1782
1782 // Calculate new top and bail out if new space is exhausted. Use result 1783 // Calculate new top and bail out if new space is exhausted. Use result
1783 // to calculate the new top. 1784 // to calculate the new top.
1784 SubP(r0, alloc_limit, result); 1785 SubP(r0, alloc_limit, result);
1785 if (is_int16(object_size)) { 1786 if (is_int16(object_size)) {
1786 CmpP(r0, Operand(object_size)); 1787 CmpP(r0, Operand(object_size));
1787 blt(gc_required); 1788 blt(gc_required);
1788 AddP(result_end, result, Operand(object_size)); 1789 AddP(result_end, result, Operand(object_size));
1789 } else { 1790 } else {
1790 mov(result_end, Operand(object_size)); 1791 mov(result_end, Operand(object_size));
1791 CmpP(r0, result_end); 1792 CmpP(r0, result_end);
1792 blt(gc_required); 1793 blt(gc_required);
1793 AddP(result_end, result, result_end); 1794 AddP(result_end, result, result_end);
1794 } 1795 }
1795 StoreP(result_end, MemOperand(top_address)); 1796
1797 if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) {
1798 // The top pointer is not updated for allocation folding dominators.
1799 StoreP(result_end, MemOperand(top_address));
1800 }
1796 1801
1797 // Tag object. 1802 // Tag object.
1798 AddP(result, result, Operand(kHeapObjectTag)); 1803 AddP(result, result, Operand(kHeapObjectTag));
1799 } 1804 }
1800 1805
1801 void MacroAssembler::Allocate(Register object_size, Register result, 1806 void MacroAssembler::Allocate(Register object_size, Register result,
1802 Register result_end, Register scratch, 1807 Register result_end, Register scratch,
1803 Label* gc_required, AllocationFlags flags) { 1808 Label* gc_required, AllocationFlags flags) {
1809 DCHECK((flags & ALLOCATION_FOLDED) == 0);
1804 if (!FLAG_inline_new) { 1810 if (!FLAG_inline_new) {
1805 if (emit_debug_code()) { 1811 if (emit_debug_code()) {
1806 // Trash the registers to simulate an allocation failure. 1812 // Trash the registers to simulate an allocation failure.
1807 LoadImmP(result, Operand(0x7091)); 1813 LoadImmP(result, Operand(0x7091));
1808 LoadImmP(scratch, Operand(0x7191)); 1814 LoadImmP(scratch, Operand(0x7191));
1809 LoadImmP(result_end, Operand(0x7291)); 1815 LoadImmP(result_end, Operand(0x7291));
1810 } 1816 }
1811 b(gc_required); 1817 b(gc_required);
1812 return; 1818 return;
1813 } 1819 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1851 1857
1852 if ((flags & DOUBLE_ALIGNMENT) != 0) { 1858 if ((flags & DOUBLE_ALIGNMENT) != 0) {
1853 // Align the next allocation. Storing the filler map without checking top is 1859 // Align the next allocation. Storing the filler map without checking top is
1854 // safe in new-space because the limit of the heap is aligned there. 1860 // safe in new-space because the limit of the heap is aligned there.
1855 #if V8_TARGET_ARCH_S390X 1861 #if V8_TARGET_ARCH_S390X
1856 STATIC_ASSERT(kPointerAlignment == kDoubleAlignment); 1862 STATIC_ASSERT(kPointerAlignment == kDoubleAlignment);
1857 #else 1863 #else
1858 STATIC_ASSERT(kPointerAlignment * 2 == kDoubleAlignment); 1864 STATIC_ASSERT(kPointerAlignment * 2 == kDoubleAlignment);
1859 AndP(result_end, result, Operand(kDoubleAlignmentMask)); 1865 AndP(result_end, result, Operand(kDoubleAlignmentMask));
1860 Label aligned; 1866 Label aligned;
1861 beq(&aligned); 1867 beq(&aligned, Label::kNear);
1862 if ((flags & PRETENURE) != 0) { 1868 if ((flags & PRETENURE) != 0) {
1863 CmpLogicalP(result, alloc_limit); 1869 CmpLogicalP(result, alloc_limit);
1864 bge(gc_required); 1870 bge(gc_required);
1865 } 1871 }
1866 mov(result_end, Operand(isolate()->factory()->one_pointer_filler_map())); 1872 mov(result_end, Operand(isolate()->factory()->one_pointer_filler_map()));
1867 StoreW(result_end, MemOperand(result)); 1873 StoreW(result_end, MemOperand(result));
1868 AddP(result, result, Operand(kDoubleSize / 2)); 1874 AddP(result, result, Operand(kDoubleSize / 2));
1869 bind(&aligned); 1875 bind(&aligned);
1870 #endif 1876 #endif
1871 } 1877 }
(...skipping 11 matching lines...) Expand all
1883 CmpP(r0, object_size); 1889 CmpP(r0, object_size);
1884 blt(gc_required); 1890 blt(gc_required);
1885 AddP(result_end, result, object_size); 1891 AddP(result_end, result, object_size);
1886 } 1892 }
1887 1893
1888 // Update allocation top. result temporarily holds the new top. 1894 // Update allocation top. result temporarily holds the new top.
1889 if (emit_debug_code()) { 1895 if (emit_debug_code()) {
1890 AndP(r0, result_end, Operand(kObjectAlignmentMask)); 1896 AndP(r0, result_end, Operand(kObjectAlignmentMask));
1891 Check(eq, kUnalignedAllocationInNewSpace, cr0); 1897 Check(eq, kUnalignedAllocationInNewSpace, cr0);
1892 } 1898 }
1899 if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) {
1900 // The top pointer is not updated for allocation folding dominators.
1901 StoreP(result_end, MemOperand(top_address));
1902 }
1903
1904 // Tag object.
1905 AddP(result, result, Operand(kHeapObjectTag));
1906 }
1907
1908 void MacroAssembler::FastAllocate(Register object_size, Register result,
1909 Register result_end, Register scratch,
1910 AllocationFlags flags) {
1911 // |object_size| and |result_end| may overlap if the DOUBLE_ALIGNMENT flag
1912 // is not specified. Other registers must not overlap.
1913 DCHECK(!AreAliased(object_size, result, scratch, ip));
1914 DCHECK(!AreAliased(result_end, result, scratch, ip));
1915 DCHECK((flags & DOUBLE_ALIGNMENT) == 0 || !object_size.is(result_end));
1916
1917 ExternalReference allocation_top =
1918 AllocationUtils::GetAllocationTopReference(isolate(), flags);
1919
1920 Register top_address = scratch;
1921 mov(top_address, Operand(allocation_top));
1922 LoadP(result, MemOperand(top_address));
1923
1924 if ((flags & DOUBLE_ALIGNMENT) != 0) {
1925 // Align the next allocation. Storing the filler map without checking top is
1926 // safe in new-space because the limit of the heap is aligned there.
1927 #if V8_TARGET_ARCH_S390X
1928 STATIC_ASSERT(kPointerAlignment == kDoubleAlignment);
1929 #else
1930 DCHECK(kPointerAlignment * 2 == kDoubleAlignment);
1931 AndP(result_end, result, Operand(kDoubleAlignmentMask));
1932 Label aligned;
1933 beq(&aligned, Label::kNear);
1934 mov(result_end, Operand(isolate()->factory()->one_pointer_filler_map()));
1935 StoreW(result_end, MemOperand(result));
1936 AddP(result, result, Operand(kDoubleSize / 2));
1937 bind(&aligned);
1938 #endif
1939 }
1940
1941 // Calculate new top using result. Object size may be in words so a shift is
1942 // required to get the number of bytes.
1943 if ((flags & SIZE_IN_WORDS) != 0) {
1944 ShiftLeftP(result_end, object_size, Operand(kPointerSizeLog2));
1945 AddP(result_end, result, result_end);
1946 } else {
1947 AddP(result_end, result, object_size);
1948 }
1949
1950 // Update allocation top. result temporarily holds the new top.
1951 if (emit_debug_code()) {
1952 AndP(r0, result_end, Operand(kObjectAlignmentMask));
1953 Check(eq, kUnalignedAllocationInNewSpace, cr0);
1954 }
1893 StoreP(result_end, MemOperand(top_address)); 1955 StoreP(result_end, MemOperand(top_address));
1894 1956
1895 // Tag object. 1957 // Tag object.
1958 AddP(result, result, Operand(kHeapObjectTag));
1959 }
1960
1961 void MacroAssembler::FastAllocate(int object_size, Register result,
1962 Register scratch1, Register scratch2,
1963 AllocationFlags flags) {
1964 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize);
1965 DCHECK(!AreAliased(result, scratch1, scratch2, ip));
1966
1967 // Make object size into bytes.
1968 if ((flags & SIZE_IN_WORDS) != 0) {
1969 object_size *= kPointerSize;
1970 }
1971 DCHECK_EQ(0, object_size & kObjectAlignmentMask);
1972
1973 ExternalReference allocation_top =
1974 AllocationUtils::GetAllocationTopReference(isolate(), flags);
1975
1976 // Set up allocation top address register.
1977 Register top_address = scratch1;
1978 Register result_end = scratch2;
1979 mov(top_address, Operand(allocation_top));
1980 LoadP(result, MemOperand(top_address));
1981
1982 if ((flags & DOUBLE_ALIGNMENT) != 0) {
1983 // Align the next allocation. Storing the filler map without checking top is
1984 // safe in new-space because the limit of the heap is aligned there.
1985 #if V8_TARGET_ARCH_S390X
1986 STATIC_ASSERT(kPointerAlignment == kDoubleAlignment);
1987 #else
1988 DCHECK(kPointerAlignment * 2 == kDoubleAlignment);
1989 AndP(result_end, result, Operand(kDoubleAlignmentMask));
1990 Label aligned;
1991 beq(&aligned, Label::kNear);
1992 mov(result_end, Operand(isolate()->factory()->one_pointer_filler_map()));
1993 StoreW(result_end, MemOperand(result));
1994 AddP(result, result, Operand(kDoubleSize / 2));
1995 bind(&aligned);
1996 #endif
1997 }
1998
1999 // Calculate new top using result.
2000 AddP(result_end, result, Operand(object_size));
2001
2002 // The top pointer is not updated for allocation folding dominators.
2003 StoreP(result_end, MemOperand(top_address));
2004
2005 // Tag object.
1896 AddP(result, result, Operand(kHeapObjectTag)); 2006 AddP(result, result, Operand(kHeapObjectTag));
1897 } 2007 }
1898 2008
1899 void MacroAssembler::AllocateTwoByteString(Register result, Register length, 2009 void MacroAssembler::AllocateTwoByteString(Register result, Register length,
1900 Register scratch1, Register scratch2, 2010 Register scratch1, Register scratch2,
1901 Register scratch3, 2011 Register scratch3,
1902 Label* gc_required) { 2012 Label* gc_required) {
1903 // Calculate the number of bytes needed for the characters in the string while 2013 // Calculate the number of bytes needed for the characters in the string while
1904 // observing object alignment. 2014 // observing object alignment.
1905 DCHECK((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0); 2015 DCHECK((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0);
(...skipping 3508 matching lines...) Expand 10 before | Expand all | Expand 10 after
5414 } 5524 }
5415 if (mag.shift > 0) ShiftRightArith(result, result, Operand(mag.shift)); 5525 if (mag.shift > 0) ShiftRightArith(result, result, Operand(mag.shift));
5416 ExtractBit(r0, dividend, 31); 5526 ExtractBit(r0, dividend, 31);
5417 AddP(result, r0); 5527 AddP(result, r0);
5418 } 5528 }
5419 5529
5420 } // namespace internal 5530 } // namespace internal
5421 } // namespace v8 5531 } // namespace v8
5422 5532
5423 #endif // V8_TARGET_ARCH_S390 5533 #endif // V8_TARGET_ARCH_S390
OLDNEW
« no previous file with comments | « src/s390/macro-assembler-s390.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698