| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 <limits.h> // For LONG_MIN, LONG_MAX. | 5 #include <limits.h> // For LONG_MIN, LONG_MAX. |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM | 7 #if V8_TARGET_ARCH_ARM |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/base/division-by-constant.h" | 10 #include "src/base/division-by-constant.h" |
| (...skipping 1865 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1876 eor(t0, t0, Operand(t0, LSR, 4)); | 1876 eor(t0, t0, Operand(t0, LSR, 4)); |
| 1877 // hash = hash * 2057; | 1877 // hash = hash * 2057; |
| 1878 mov(scratch, Operand(t0, LSL, 11)); | 1878 mov(scratch, Operand(t0, LSL, 11)); |
| 1879 add(t0, t0, Operand(t0, LSL, 3)); | 1879 add(t0, t0, Operand(t0, LSL, 3)); |
| 1880 add(t0, t0, scratch); | 1880 add(t0, t0, scratch); |
| 1881 // hash = hash ^ (hash >> 16); | 1881 // hash = hash ^ (hash >> 16); |
| 1882 eor(t0, t0, Operand(t0, LSR, 16)); | 1882 eor(t0, t0, Operand(t0, LSR, 16)); |
| 1883 bic(t0, t0, Operand(0xc0000000u)); | 1883 bic(t0, t0, Operand(0xc0000000u)); |
| 1884 } | 1884 } |
| 1885 | 1885 |
| 1886 | |
| 1887 void MacroAssembler::LoadFromNumberDictionary(Label* miss, | |
| 1888 Register elements, | |
| 1889 Register key, | |
| 1890 Register result, | |
| 1891 Register t0, | |
| 1892 Register t1, | |
| 1893 Register t2) { | |
| 1894 // Register use: | |
| 1895 // | |
| 1896 // elements - holds the slow-case elements of the receiver on entry. | |
| 1897 // Unchanged unless 'result' is the same register. | |
| 1898 // | |
| 1899 // key - holds the smi key on entry. | |
| 1900 // Unchanged unless 'result' is the same register. | |
| 1901 // | |
| 1902 // result - holds the result on exit if the load succeeded. | |
| 1903 // Allowed to be the same as 'key' or 'result'. | |
| 1904 // Unchanged on bailout so 'key' or 'result' can be used | |
| 1905 // in further computation. | |
| 1906 // | |
| 1907 // Scratch registers: | |
| 1908 // | |
| 1909 // t0 - holds the untagged key on entry and holds the hash once computed. | |
| 1910 // | |
| 1911 // t1 - used to hold the capacity mask of the dictionary | |
| 1912 // | |
| 1913 // t2 - used for the index into the dictionary. | |
| 1914 Label done; | |
| 1915 | |
| 1916 GetNumberHash(t0, t1); | |
| 1917 | |
| 1918 // Compute the capacity mask. | |
| 1919 ldr(t1, FieldMemOperand(elements, SeededNumberDictionary::kCapacityOffset)); | |
| 1920 SmiUntag(t1); | |
| 1921 sub(t1, t1, Operand(1)); | |
| 1922 | |
| 1923 // Generate an unrolled loop that performs a few probes before giving up. | |
| 1924 for (int i = 0; i < kNumberDictionaryProbes; i++) { | |
| 1925 // Use t2 for index calculations and keep the hash intact in t0. | |
| 1926 mov(t2, t0); | |
| 1927 // Compute the masked index: (hash + i + i * i) & mask. | |
| 1928 if (i > 0) { | |
| 1929 add(t2, t2, Operand(SeededNumberDictionary::GetProbeOffset(i))); | |
| 1930 } | |
| 1931 and_(t2, t2, Operand(t1)); | |
| 1932 | |
| 1933 // Scale the index by multiplying by the element size. | |
| 1934 DCHECK(SeededNumberDictionary::kEntrySize == 3); | |
| 1935 add(t2, t2, Operand(t2, LSL, 1)); // t2 = t2 * 3 | |
| 1936 | |
| 1937 // Check if the key is identical to the name. | |
| 1938 add(t2, elements, Operand(t2, LSL, kPointerSizeLog2)); | |
| 1939 ldr(ip, FieldMemOperand(t2, SeededNumberDictionary::kElementsStartOffset)); | |
| 1940 cmp(key, Operand(ip)); | |
| 1941 if (i != kNumberDictionaryProbes - 1) { | |
| 1942 b(eq, &done); | |
| 1943 } else { | |
| 1944 b(ne, miss); | |
| 1945 } | |
| 1946 } | |
| 1947 | |
| 1948 bind(&done); | |
| 1949 // Check that the value is a field property. | |
| 1950 // t2: elements + (index * kPointerSize) | |
| 1951 const int kDetailsOffset = | |
| 1952 SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize; | |
| 1953 ldr(t1, FieldMemOperand(t2, kDetailsOffset)); | |
| 1954 DCHECK_EQ(DATA, 0); | |
| 1955 tst(t1, Operand(Smi::FromInt(PropertyDetails::TypeField::kMask))); | |
| 1956 b(ne, miss); | |
| 1957 | |
| 1958 // Get the value at the masked, scaled index and return. | |
| 1959 const int kValueOffset = | |
| 1960 SeededNumberDictionary::kElementsStartOffset + kPointerSize; | |
| 1961 ldr(result, FieldMemOperand(t2, kValueOffset)); | |
| 1962 } | |
| 1963 | |
| 1964 | |
| 1965 void MacroAssembler::Allocate(int object_size, | 1886 void MacroAssembler::Allocate(int object_size, |
| 1966 Register result, | 1887 Register result, |
| 1967 Register scratch1, | 1888 Register scratch1, |
| 1968 Register scratch2, | 1889 Register scratch2, |
| 1969 Label* gc_required, | 1890 Label* gc_required, |
| 1970 AllocationFlags flags) { | 1891 AllocationFlags flags) { |
| 1971 DCHECK(object_size <= kMaxRegularHeapObjectSize); | 1892 DCHECK(object_size <= kMaxRegularHeapObjectSize); |
| 1972 DCHECK((flags & ALLOCATION_FOLDED) == 0); | 1893 DCHECK((flags & ALLOCATION_FOLDED) == 0); |
| 1973 if (!FLAG_inline_new) { | 1894 if (!FLAG_inline_new) { |
| 1974 if (emit_debug_code()) { | 1895 if (emit_debug_code()) { |
| (...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2411 } | 2332 } |
| 2412 | 2333 |
| 2413 | 2334 |
| 2414 void MacroAssembler::CompareRoot(Register obj, | 2335 void MacroAssembler::CompareRoot(Register obj, |
| 2415 Heap::RootListIndex index) { | 2336 Heap::RootListIndex index) { |
| 2416 DCHECK(!obj.is(ip)); | 2337 DCHECK(!obj.is(ip)); |
| 2417 LoadRoot(ip, index); | 2338 LoadRoot(ip, index); |
| 2418 cmp(obj, ip); | 2339 cmp(obj, ip); |
| 2419 } | 2340 } |
| 2420 | 2341 |
| 2421 | |
| 2422 void MacroAssembler::CheckFastElements(Register map, | |
| 2423 Register scratch, | |
| 2424 Label* fail) { | |
| 2425 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | |
| 2426 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | |
| 2427 STATIC_ASSERT(FAST_ELEMENTS == 2); | |
| 2428 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); | |
| 2429 ldrb(scratch, FieldMemOperand(map, Map::kBitField2Offset)); | |
| 2430 cmp(scratch, Operand(Map::kMaximumBitField2FastHoleyElementValue)); | |
| 2431 b(hi, fail); | |
| 2432 } | |
| 2433 | |
| 2434 | |
| 2435 void MacroAssembler::CheckFastObjectElements(Register map, | 2342 void MacroAssembler::CheckFastObjectElements(Register map, |
| 2436 Register scratch, | 2343 Register scratch, |
| 2437 Label* fail) { | 2344 Label* fail) { |
| 2438 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | 2345 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); |
| 2439 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | 2346 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
| 2440 STATIC_ASSERT(FAST_ELEMENTS == 2); | 2347 STATIC_ASSERT(FAST_ELEMENTS == 2); |
| 2441 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); | 2348 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); |
| 2442 ldrb(scratch, FieldMemOperand(map, Map::kBitField2Offset)); | 2349 ldrb(scratch, FieldMemOperand(map, Map::kBitField2Offset)); |
| 2443 cmp(scratch, Operand(Map::kMaximumBitField2FastHoleySmiElementValue)); | 2350 cmp(scratch, Operand(Map::kMaximumBitField2FastHoleySmiElementValue)); |
| 2444 b(ls, fail); | 2351 b(ls, fail); |
| (...skipping 1722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4167 } | 4074 } |
| 4168 } | 4075 } |
| 4169 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); | 4076 if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift)); |
| 4170 add(result, result, Operand(dividend, LSR, 31)); | 4077 add(result, result, Operand(dividend, LSR, 31)); |
| 4171 } | 4078 } |
| 4172 | 4079 |
| 4173 } // namespace internal | 4080 } // namespace internal |
| 4174 } // namespace v8 | 4081 } // namespace v8 |
| 4175 | 4082 |
| 4176 #endif // V8_TARGET_ARCH_ARM | 4083 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |