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 |