| OLD | NEW |
| 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_PPC | 8 #if V8_TARGET_ARCH_PPC |
| 9 | 9 |
| 10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
| (...skipping 1711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1722 add(t0, t0, scratch); | 1722 add(t0, t0, scratch); |
| 1723 slwi(scratch, r0, Operand(11)); | 1723 slwi(scratch, r0, Operand(11)); |
| 1724 add(t0, t0, scratch); | 1724 add(t0, t0, scratch); |
| 1725 // hash = hash ^ (hash >> 16); | 1725 // hash = hash ^ (hash >> 16); |
| 1726 srwi(scratch, t0, Operand(16)); | 1726 srwi(scratch, t0, Operand(16)); |
| 1727 xor_(t0, t0, scratch); | 1727 xor_(t0, t0, scratch); |
| 1728 // hash & 0x3fffffff | 1728 // hash & 0x3fffffff |
| 1729 ExtractBitRange(t0, t0, 29, 0); | 1729 ExtractBitRange(t0, t0, 29, 0); |
| 1730 } | 1730 } |
| 1731 | 1731 |
| 1732 | |
| 1733 void MacroAssembler::LoadFromNumberDictionary(Label* miss, Register elements, | |
| 1734 Register key, Register result, | |
| 1735 Register t0, Register t1, | |
| 1736 Register t2) { | |
| 1737 // Register use: | |
| 1738 // | |
| 1739 // elements - holds the slow-case elements of the receiver on entry. | |
| 1740 // Unchanged unless 'result' is the same register. | |
| 1741 // | |
| 1742 // key - holds the smi key on entry. | |
| 1743 // Unchanged unless 'result' is the same register. | |
| 1744 // | |
| 1745 // result - holds the result on exit if the load succeeded. | |
| 1746 // Allowed to be the same as 'key' or 'result'. | |
| 1747 // Unchanged on bailout so 'key' or 'result' can be used | |
| 1748 // in further computation. | |
| 1749 // | |
| 1750 // Scratch registers: | |
| 1751 // | |
| 1752 // t0 - holds the untagged key on entry and holds the hash once computed. | |
| 1753 // | |
| 1754 // t1 - used to hold the capacity mask of the dictionary | |
| 1755 // | |
| 1756 // t2 - used for the index into the dictionary. | |
| 1757 Label done; | |
| 1758 | |
| 1759 GetNumberHash(t0, t1); | |
| 1760 | |
| 1761 // Compute the capacity mask. | |
| 1762 LoadP(t1, FieldMemOperand(elements, SeededNumberDictionary::kCapacityOffset)); | |
| 1763 SmiUntag(t1); | |
| 1764 subi(t1, t1, Operand(1)); | |
| 1765 | |
| 1766 // Generate an unrolled loop that performs a few probes before giving up. | |
| 1767 for (int i = 0; i < kNumberDictionaryProbes; i++) { | |
| 1768 // Use t2 for index calculations and keep the hash intact in t0. | |
| 1769 mr(t2, t0); | |
| 1770 // Compute the masked index: (hash + i + i * i) & mask. | |
| 1771 if (i > 0) { | |
| 1772 addi(t2, t2, Operand(SeededNumberDictionary::GetProbeOffset(i))); | |
| 1773 } | |
| 1774 and_(t2, t2, t1); | |
| 1775 | |
| 1776 // Scale the index by multiplying by the element size. | |
| 1777 DCHECK(SeededNumberDictionary::kEntrySize == 3); | |
| 1778 slwi(ip, t2, Operand(1)); | |
| 1779 add(t2, t2, ip); // t2 = t2 * 3 | |
| 1780 | |
| 1781 // Check if the key is identical to the name. | |
| 1782 slwi(t2, t2, Operand(kPointerSizeLog2)); | |
| 1783 add(t2, elements, t2); | |
| 1784 LoadP(ip, | |
| 1785 FieldMemOperand(t2, SeededNumberDictionary::kElementsStartOffset)); | |
| 1786 cmp(key, ip); | |
| 1787 if (i != kNumberDictionaryProbes - 1) { | |
| 1788 beq(&done); | |
| 1789 } else { | |
| 1790 bne(miss); | |
| 1791 } | |
| 1792 } | |
| 1793 | |
| 1794 bind(&done); | |
| 1795 // Check that the value is a field property. | |
| 1796 // t2: elements + (index * kPointerSize) | |
| 1797 const int kDetailsOffset = | |
| 1798 SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize; | |
| 1799 LoadP(t1, FieldMemOperand(t2, kDetailsOffset)); | |
| 1800 LoadSmiLiteral(ip, Smi::FromInt(PropertyDetails::TypeField::kMask)); | |
| 1801 DCHECK_EQ(DATA, 0); | |
| 1802 and_(r0, t1, ip, SetRC); | |
| 1803 bne(miss, cr0); | |
| 1804 | |
| 1805 // Get the value at the masked, scaled index and return. | |
| 1806 const int kValueOffset = | |
| 1807 SeededNumberDictionary::kElementsStartOffset + kPointerSize; | |
| 1808 LoadP(result, FieldMemOperand(t2, kValueOffset)); | |
| 1809 } | |
| 1810 | |
| 1811 | |
| 1812 void MacroAssembler::Allocate(int object_size, Register result, | 1732 void MacroAssembler::Allocate(int object_size, Register result, |
| 1813 Register scratch1, Register scratch2, | 1733 Register scratch1, Register scratch2, |
| 1814 Label* gc_required, AllocationFlags flags) { | 1734 Label* gc_required, AllocationFlags flags) { |
| 1815 DCHECK(object_size <= kMaxRegularHeapObjectSize); | 1735 DCHECK(object_size <= kMaxRegularHeapObjectSize); |
| 1816 DCHECK((flags & ALLOCATION_FOLDED) == 0); | 1736 DCHECK((flags & ALLOCATION_FOLDED) == 0); |
| 1817 if (!FLAG_inline_new) { | 1737 if (!FLAG_inline_new) { |
| 1818 if (emit_debug_code()) { | 1738 if (emit_debug_code()) { |
| 1819 // Trash the registers to simulate an allocation failure. | 1739 // Trash the registers to simulate an allocation failure. |
| 1820 li(result, Operand(0x7091)); | 1740 li(result, Operand(0x7091)); |
| 1821 li(scratch1, Operand(0x7191)); | 1741 li(scratch1, Operand(0x7191)); |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2227 cmpi(type_reg, Operand(type)); | 2147 cmpi(type_reg, Operand(type)); |
| 2228 } | 2148 } |
| 2229 | 2149 |
| 2230 | 2150 |
| 2231 void MacroAssembler::CompareRoot(Register obj, Heap::RootListIndex index) { | 2151 void MacroAssembler::CompareRoot(Register obj, Heap::RootListIndex index) { |
| 2232 DCHECK(!obj.is(r0)); | 2152 DCHECK(!obj.is(r0)); |
| 2233 LoadRoot(r0, index); | 2153 LoadRoot(r0, index); |
| 2234 cmp(obj, r0); | 2154 cmp(obj, r0); |
| 2235 } | 2155 } |
| 2236 | 2156 |
| 2237 | |
| 2238 void MacroAssembler::CheckFastElements(Register map, Register scratch, | |
| 2239 Label* fail) { | |
| 2240 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | |
| 2241 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | |
| 2242 STATIC_ASSERT(FAST_ELEMENTS == 2); | |
| 2243 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); | |
| 2244 lbz(scratch, FieldMemOperand(map, Map::kBitField2Offset)); | |
| 2245 STATIC_ASSERT(Map::kMaximumBitField2FastHoleyElementValue < 0x8000); | |
| 2246 cmpli(scratch, Operand(Map::kMaximumBitField2FastHoleyElementValue)); | |
| 2247 bgt(fail); | |
| 2248 } | |
| 2249 | |
| 2250 | |
| 2251 void MacroAssembler::CheckFastObjectElements(Register map, Register scratch, | 2157 void MacroAssembler::CheckFastObjectElements(Register map, Register scratch, |
| 2252 Label* fail) { | 2158 Label* fail) { |
| 2253 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | 2159 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); |
| 2254 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | 2160 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
| 2255 STATIC_ASSERT(FAST_ELEMENTS == 2); | 2161 STATIC_ASSERT(FAST_ELEMENTS == 2); |
| 2256 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); | 2162 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); |
| 2257 lbz(scratch, FieldMemOperand(map, Map::kBitField2Offset)); | 2163 lbz(scratch, FieldMemOperand(map, Map::kBitField2Offset)); |
| 2258 cmpli(scratch, Operand(Map::kMaximumBitField2FastHoleySmiElementValue)); | 2164 cmpli(scratch, Operand(Map::kMaximumBitField2FastHoleySmiElementValue)); |
| 2259 ble(fail); | 2165 ble(fail); |
| 2260 cmpli(scratch, Operand(Map::kMaximumBitField2FastHoleyElementValue)); | 2166 cmpli(scratch, Operand(Map::kMaximumBitField2FastHoleyElementValue)); |
| (...skipping 2614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4875 } | 4781 } |
| 4876 if (mag.shift > 0) srawi(result, result, mag.shift); | 4782 if (mag.shift > 0) srawi(result, result, mag.shift); |
| 4877 ExtractBit(r0, dividend, 31); | 4783 ExtractBit(r0, dividend, 31); |
| 4878 add(result, result, r0); | 4784 add(result, result, r0); |
| 4879 } | 4785 } |
| 4880 | 4786 |
| 4881 } // namespace internal | 4787 } // namespace internal |
| 4882 } // namespace v8 | 4788 } // namespace v8 |
| 4883 | 4789 |
| 4884 #endif // V8_TARGET_ARCH_PPC | 4790 #endif // V8_TARGET_ARCH_PPC |
| OLD | NEW |