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

Side by Side Diff: src/arm/stub-cache-arm.cc

Issue 15085026: ARM: Smi refactoring and improvements. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1662 matching lines...) Expand 10 before | Expand all | Expand 10 after
1673 1673
1674 // Check that the elements are in fast mode and writable. 1674 // Check that the elements are in fast mode and writable.
1675 __ CheckMap(elements, 1675 __ CheckMap(elements,
1676 r0, 1676 r0,
1677 Heap::kFixedArrayMapRootIndex, 1677 Heap::kFixedArrayMapRootIndex,
1678 &check_double, 1678 &check_double,
1679 DONT_DO_SMI_CHECK); 1679 DONT_DO_SMI_CHECK);
1680 1680
1681 // Get the array's length into r0 and calculate new length. 1681 // Get the array's length into r0 and calculate new length.
1682 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1682 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset));
1683 STATIC_ASSERT(kSmiTagSize == 1);
1684 STATIC_ASSERT(kSmiTag == 0);
1685 __ add(r0, r0, Operand(Smi::FromInt(argc))); 1683 __ add(r0, r0, Operand(Smi::FromInt(argc)));
1686 1684
1687 // Get the elements' length. 1685 // Get the elements' length.
1688 __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1686 __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset));
1689 1687
1690 // Check if we could survive without allocation. 1688 // Check if we could survive without allocation.
1691 __ cmp(r0, r4); 1689 __ cmp(r0, r4);
1692 __ b(gt, &attempt_to_grow_elements); 1690 __ b(gt, &attempt_to_grow_elements);
1693 1691
1694 // Check if value is a smi. 1692 // Check if value is a smi.
1695 __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize)); 1693 __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize));
1696 __ JumpIfNotSmi(r4, &with_write_barrier); 1694 __ JumpIfNotSmi(r4, &with_write_barrier);
1697 1695
1698 // Save new length. 1696 // Save new length.
1699 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1697 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset));
1700 1698
1701 // Store the value. 1699 // Store the value.
1702 // We may need a register containing the address end_elements below, 1700 // We may need a register containing the address end_elements below,
1703 // so write back the value in end_elements. 1701 // so write back the value in end_elements.
1704 __ add(end_elements, elements, 1702 __ add(end_elements, elements, Operand::PointerOffsetFromSmiKey(r0));
1705 Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize));
1706 const int kEndElementsOffset = 1703 const int kEndElementsOffset =
1707 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize; 1704 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize;
1708 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex)); 1705 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex));
1709 1706
1710 // Check for a smi. 1707 // Check for a smi.
1711 __ Drop(argc + 1); 1708 __ Drop(argc + 1);
1712 __ Ret(); 1709 __ Ret();
1713 1710
1714 __ bind(&check_double); 1711 __ bind(&check_double);
1715 1712
1716 // Check that the elements are in fast mode and writable. 1713 // Check that the elements are in fast mode and writable.
1717 __ CheckMap(elements, 1714 __ CheckMap(elements,
1718 r0, 1715 r0,
1719 Heap::kFixedDoubleArrayMapRootIndex, 1716 Heap::kFixedDoubleArrayMapRootIndex,
1720 &call_builtin, 1717 &call_builtin,
1721 DONT_DO_SMI_CHECK); 1718 DONT_DO_SMI_CHECK);
1722 1719
1723 // Get the array's length into r0 and calculate new length. 1720 // Get the array's length into r0 and calculate new length.
1724 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1721 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset));
1725 STATIC_ASSERT(kSmiTagSize == 1);
1726 STATIC_ASSERT(kSmiTag == 0);
1727 __ add(r0, r0, Operand(Smi::FromInt(argc))); 1722 __ add(r0, r0, Operand(Smi::FromInt(argc)));
1728 1723
1729 // Get the elements' length. 1724 // Get the elements' length.
1730 __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1725 __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset));
1731 1726
1732 // Check if we could survive without allocation. 1727 // Check if we could survive without allocation.
1733 __ cmp(r0, r4); 1728 __ cmp(r0, r4);
1734 __ b(gt, &call_builtin); 1729 __ b(gt, &call_builtin);
1735 1730
1736 __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize)); 1731 __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize));
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1790 } else { 1785 } else {
1791 __ CheckFastObjectElements(r3, r3, &call_builtin); 1786 __ CheckFastObjectElements(r3, r3, &call_builtin);
1792 } 1787 }
1793 1788
1794 // Save new length. 1789 // Save new length.
1795 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1790 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset));
1796 1791
1797 // Store the value. 1792 // Store the value.
1798 // We may need a register containing the address end_elements below, 1793 // We may need a register containing the address end_elements below,
1799 // so write back the value in end_elements. 1794 // so write back the value in end_elements.
1800 __ add(end_elements, elements, 1795 __ add(end_elements, elements, Operand::PointerOffsetFromSmiKey(r0));
1801 Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize));
1802 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex)); 1796 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex));
1803 1797
1804 __ RecordWrite(elements, 1798 __ RecordWrite(elements,
1805 end_elements, 1799 end_elements,
1806 r4, 1800 r4,
1807 kLRHasNotBeenSaved, 1801 kLRHasNotBeenSaved,
1808 kDontSaveFPRegs, 1802 kDontSaveFPRegs,
1809 EMIT_REMEMBERED_SET, 1803 EMIT_REMEMBERED_SET,
1810 OMIT_SMI_CHECK); 1804 OMIT_SMI_CHECK);
1811 __ Drop(argc + 1); 1805 __ Drop(argc + 1);
(...skipping 16 matching lines...) Expand all
1828 __ CheckFastObjectElements(r7, r7, &call_builtin); 1822 __ CheckFastObjectElements(r7, r7, &call_builtin);
1829 __ bind(&no_fast_elements_check); 1823 __ bind(&no_fast_elements_check);
1830 1824
1831 ExternalReference new_space_allocation_top = 1825 ExternalReference new_space_allocation_top =
1832 ExternalReference::new_space_allocation_top_address(isolate()); 1826 ExternalReference::new_space_allocation_top_address(isolate());
1833 ExternalReference new_space_allocation_limit = 1827 ExternalReference new_space_allocation_limit =
1834 ExternalReference::new_space_allocation_limit_address(isolate()); 1828 ExternalReference::new_space_allocation_limit_address(isolate());
1835 1829
1836 const int kAllocationDelta = 4; 1830 const int kAllocationDelta = 4;
1837 // Load top and check if it is the end of elements. 1831 // Load top and check if it is the end of elements.
1838 __ add(end_elements, elements, 1832 __ add(end_elements, elements, Operand::PointerOffsetFromSmiKey(r0));
1839 Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize));
1840 __ add(end_elements, end_elements, Operand(kEndElementsOffset)); 1833 __ add(end_elements, end_elements, Operand(kEndElementsOffset));
1841 __ mov(r7, Operand(new_space_allocation_top)); 1834 __ mov(r7, Operand(new_space_allocation_top));
1842 __ ldr(r3, MemOperand(r7)); 1835 __ ldr(r3, MemOperand(r7));
1843 __ cmp(end_elements, r3); 1836 __ cmp(end_elements, r3);
1844 __ b(ne, &call_builtin); 1837 __ b(ne, &call_builtin);
1845 1838
1846 __ mov(r9, Operand(new_space_allocation_limit)); 1839 __ mov(r9, Operand(new_space_allocation_limit));
1847 __ ldr(r9, MemOperand(r9)); 1840 __ ldr(r9, MemOperand(r9));
1848 __ add(r3, r3, Operand(kAllocationDelta * kPointerSize)); 1841 __ add(r3, r3, Operand(kAllocationDelta * kPointerSize));
1849 __ cmp(r3, r9); 1842 __ cmp(r3, r9);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1925 &call_builtin, 1918 &call_builtin,
1926 DONT_DO_SMI_CHECK); 1919 DONT_DO_SMI_CHECK);
1927 1920
1928 // Get the array's length into r4 and calculate new length. 1921 // Get the array's length into r4 and calculate new length.
1929 __ ldr(r4, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1922 __ ldr(r4, FieldMemOperand(receiver, JSArray::kLengthOffset));
1930 __ sub(r4, r4, Operand(Smi::FromInt(1)), SetCC); 1923 __ sub(r4, r4, Operand(Smi::FromInt(1)), SetCC);
1931 __ b(lt, &return_undefined); 1924 __ b(lt, &return_undefined);
1932 1925
1933 // Get the last element. 1926 // Get the last element.
1934 __ LoadRoot(r6, Heap::kTheHoleValueRootIndex); 1927 __ LoadRoot(r6, Heap::kTheHoleValueRootIndex);
1935 STATIC_ASSERT(kSmiTagSize == 1);
1936 STATIC_ASSERT(kSmiTag == 0);
1937 // We can't address the last element in one operation. Compute the more 1928 // We can't address the last element in one operation. Compute the more
1938 // expensive shift first, and use an offset later on. 1929 // expensive shift first, and use an offset later on.
1939 __ add(elements, elements, Operand(r4, LSL, kPointerSizeLog2 - kSmiTagSize)); 1930 __ add(elements, elements, Operand::PointerOffsetFromSmiKey(r4));
1940 __ ldr(r0, FieldMemOperand(elements, FixedArray::kHeaderSize)); 1931 __ ldr(r0, FieldMemOperand(elements, FixedArray::kHeaderSize));
1941 __ cmp(r0, r6); 1932 __ cmp(r0, r6);
1942 __ b(eq, &call_builtin); 1933 __ b(eq, &call_builtin);
1943 1934
1944 // Set the array's length. 1935 // Set the array's length.
1945 __ str(r4, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1936 __ str(r4, FieldMemOperand(receiver, JSArray::kLengthOffset));
1946 1937
1947 // Fill with the hole. 1938 // Fill with the hole.
1948 __ str(r6, FieldMemOperand(elements, FixedArray::kHeaderSize)); 1939 __ str(r6, FieldMemOperand(elements, FixedArray::kHeaderSize));
1949 __ Drop(argc + 1); 1940 __ Drop(argc + 1);
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
2151 // If the object is not a JSObject or we got an unexpected number of 2142 // If the object is not a JSObject or we got an unexpected number of
2152 // arguments, bail out to the regular call. 2143 // arguments, bail out to the regular call.
2153 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2144 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2154 2145
2155 Label miss; 2146 Label miss;
2156 GenerateNameCheck(name, &miss); 2147 GenerateNameCheck(name, &miss);
2157 2148
2158 if (cell.is_null()) { 2149 if (cell.is_null()) {
2159 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); 2150 __ ldr(r1, MemOperand(sp, 1 * kPointerSize));
2160 2151
2161 STATIC_ASSERT(kSmiTag == 0);
2162 __ JumpIfSmi(r1, &miss); 2152 __ JumpIfSmi(r1, &miss);
2163 2153
2164 CheckPrototypes(Handle<JSObject>::cast(object), r1, holder, r0, r3, r4, 2154 CheckPrototypes(Handle<JSObject>::cast(object), r1, holder, r0, r3, r4,
2165 name, &miss); 2155 name, &miss);
2166 } else { 2156 } else {
2167 ASSERT(cell->value() == *function); 2157 ASSERT(cell->value() == *function);
2168 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 2158 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2169 &miss); 2159 &miss);
2170 GenerateLoadFunctionFromCell(cell, function, &miss); 2160 GenerateLoadFunctionFromCell(cell, function, &miss);
2171 } 2161 }
2172 2162
2173 // Load the char code argument. 2163 // Load the char code argument.
2174 Register code = r1; 2164 Register code = r1;
2175 __ ldr(code, MemOperand(sp, 0 * kPointerSize)); 2165 __ ldr(code, MemOperand(sp, 0 * kPointerSize));
2176 2166
2177 // Check the code is a smi. 2167 // Check the code is a smi.
2178 Label slow; 2168 Label slow;
2179 STATIC_ASSERT(kSmiTag == 0);
2180 __ JumpIfNotSmi(code, &slow); 2169 __ JumpIfNotSmi(code, &slow);
2181 2170
2182 // Convert the smi code to uint16. 2171 // Convert the smi code to uint16.
2183 __ and_(code, code, Operand(Smi::FromInt(0xffff))); 2172 __ and_(code, code, Operand(Smi::FromInt(0xffff)));
2184 2173
2185 StringCharFromCodeGenerator generator(code, r0); 2174 StringCharFromCodeGenerator generator(code, r0);
2186 generator.GenerateFast(masm()); 2175 generator.GenerateFast(masm());
2187 __ Drop(argc + 1); 2176 __ Drop(argc + 1);
2188 __ Ret(); 2177 __ Ret();
2189 2178
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2223 const int argc = arguments().immediate(); 2212 const int argc = arguments().immediate();
2224 // If the object is not a JSObject or we got an unexpected number of 2213 // If the object is not a JSObject or we got an unexpected number of
2225 // arguments, bail out to the regular call. 2214 // arguments, bail out to the regular call.
2226 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2215 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2227 2216
2228 Label miss, slow; 2217 Label miss, slow;
2229 GenerateNameCheck(name, &miss); 2218 GenerateNameCheck(name, &miss);
2230 2219
2231 if (cell.is_null()) { 2220 if (cell.is_null()) {
2232 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); 2221 __ ldr(r1, MemOperand(sp, 1 * kPointerSize));
2233 STATIC_ASSERT(kSmiTag == 0);
2234 __ JumpIfSmi(r1, &miss); 2222 __ JumpIfSmi(r1, &miss);
2235 CheckPrototypes(Handle<JSObject>::cast(object), r1, holder, r0, r3, r4, 2223 CheckPrototypes(Handle<JSObject>::cast(object), r1, holder, r0, r3, r4,
2236 name, &miss); 2224 name, &miss);
2237 } else { 2225 } else {
2238 ASSERT(cell->value() == *function); 2226 ASSERT(cell->value() == *function);
2239 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 2227 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2240 &miss); 2228 &miss);
2241 GenerateLoadFunctionFromCell(cell, function, &miss); 2229 GenerateLoadFunctionFromCell(cell, function, &miss);
2242 } 2230 }
2243 2231
2244 // Load the (only) argument into r0. 2232 // Load the (only) argument into r0.
2245 __ ldr(r0, MemOperand(sp, 0 * kPointerSize)); 2233 __ ldr(r0, MemOperand(sp, 0 * kPointerSize));
2246 2234
2247 // If the argument is a smi, just return. 2235 // If the argument is a smi, just return.
2248 STATIC_ASSERT(kSmiTag == 0); 2236 __ SmiTst(r0);
2249 __ tst(r0, Operand(kSmiTagMask));
2250 __ Drop(argc + 1, eq); 2237 __ Drop(argc + 1, eq);
2251 __ Ret(eq); 2238 __ Ret(eq);
2252 2239
2253 __ CheckMap(r0, r1, Heap::kHeapNumberMapRootIndex, &slow, DONT_DO_SMI_CHECK); 2240 __ CheckMap(r0, r1, Heap::kHeapNumberMapRootIndex, &slow, DONT_DO_SMI_CHECK);
2254 2241
2255 Label smi_check, just_return; 2242 Label smi_check, just_return;
2256 2243
2257 // Load the HeapNumber value. 2244 // Load the HeapNumber value.
2258 // We will need access to the value in the core registers, so we load it 2245 // We will need access to the value in the core registers, so we load it
2259 // with ldrd and move it to the fpu. It also spares a sub instruction for 2246 // with ldrd and move it to the fpu. It also spares a sub instruction for
(...skipping 25 matching lines...) Expand all
2285 // If input is in ]-inf, -0[, sub one and, go to slow if we have 2272 // If input is in ]-inf, -0[, sub one and, go to slow if we have
2286 // an overflow. Else we fall through smi check. 2273 // an overflow. Else we fall through smi check.
2287 // Hint: if x is a negative, non integer number, 2274 // Hint: if x is a negative, non integer number,
2288 // floor(x) <=> round_to_zero(x) - 1. 2275 // floor(x) <=> round_to_zero(x) - 1.
2289 __ sub(r0, r0, Operand(1), SetCC, mi); 2276 __ sub(r0, r0, Operand(1), SetCC, mi);
2290 __ b(vs, &slow); 2277 __ b(vs, &slow);
2291 2278
2292 __ bind(&smi_check); 2279 __ bind(&smi_check);
2293 // Check if the result can fit into an smi. If we had an overflow, 2280 // Check if the result can fit into an smi. If we had an overflow,
2294 // the result is either 0x80000000 or 0x7FFFFFFF and won't fit into an smi. 2281 // the result is either 0x80000000 or 0x7FFFFFFF and won't fit into an smi.
2295 __ add(r1, r0, Operand(0x40000000), SetCC);
2296 // If result doesn't fit into an smi, branch to slow. 2282 // If result doesn't fit into an smi, branch to slow.
2297 __ b(&slow, mi); 2283 __ SmiTag(r0, SetCC);
2298 // Tag the result. 2284 __ b(vs, &slow);
2299 __ mov(r0, Operand(r0, LSL, kSmiTagSize));
2300 2285
2301 __ bind(&just_return); 2286 __ bind(&just_return);
2302 __ Drop(argc + 1); 2287 __ Drop(argc + 1);
2303 __ Ret(); 2288 __ Ret();
2304 2289
2305 __ bind(&slow); 2290 __ bind(&slow);
2306 // Tail call the full function. We do not have to patch the receiver 2291 // Tail call the full function. We do not have to patch the receiver
2307 // because the function makes no use of it. 2292 // because the function makes no use of it.
2308 ParameterCount expected(function); 2293 ParameterCount expected(function);
2309 __ InvokeFunction(function, expected, arguments(), 2294 __ InvokeFunction(function, expected, arguments(),
(...skipping 24 matching lines...) Expand all
2334 2319
2335 const int argc = arguments().immediate(); 2320 const int argc = arguments().immediate();
2336 // If the object is not a JSObject or we got an unexpected number of 2321 // If the object is not a JSObject or we got an unexpected number of
2337 // arguments, bail out to the regular call. 2322 // arguments, bail out to the regular call.
2338 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2323 if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
2339 2324
2340 Label miss; 2325 Label miss;
2341 GenerateNameCheck(name, &miss); 2326 GenerateNameCheck(name, &miss);
2342 if (cell.is_null()) { 2327 if (cell.is_null()) {
2343 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); 2328 __ ldr(r1, MemOperand(sp, 1 * kPointerSize));
2344 STATIC_ASSERT(kSmiTag == 0);
2345 __ JumpIfSmi(r1, &miss); 2329 __ JumpIfSmi(r1, &miss);
2346 CheckPrototypes(Handle<JSObject>::cast(object), r1, holder, r0, r3, r4, 2330 CheckPrototypes(Handle<JSObject>::cast(object), r1, holder, r0, r3, r4,
2347 name, &miss); 2331 name, &miss);
2348 } else { 2332 } else {
2349 ASSERT(cell->value() == *function); 2333 ASSERT(cell->value() == *function);
2350 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 2334 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
2351 &miss); 2335 &miss);
2352 GenerateLoadFunctionFromCell(cell, function, &miss); 2336 GenerateLoadFunctionFromCell(cell, function, &miss);
2353 } 2337 }
2354 2338
2355 // Load the (only) argument into r0. 2339 // Load the (only) argument into r0.
2356 __ ldr(r0, MemOperand(sp, 0 * kPointerSize)); 2340 __ ldr(r0, MemOperand(sp, 0 * kPointerSize));
2357 2341
2358 // Check if the argument is a smi. 2342 // Check if the argument is a smi.
2359 Label not_smi; 2343 Label not_smi;
2360 STATIC_ASSERT(kSmiTag == 0);
2361 __ JumpIfNotSmi(r0, &not_smi); 2344 __ JumpIfNotSmi(r0, &not_smi);
2362 2345
2363 // Do bitwise not or do nothing depending on the sign of the 2346 // Do bitwise not or do nothing depending on the sign of the
2364 // argument. 2347 // argument.
2365 __ eor(r1, r0, Operand(r0, ASR, kBitsPerInt - 1)); 2348 __ eor(r1, r0, Operand(r0, ASR, kBitsPerInt - 1));
2366 2349
2367 // Add 1 or do nothing depending on the sign of the argument. 2350 // Add 1 or do nothing depending on the sign of the argument.
2368 __ sub(r0, r1, Operand(r0, ASR, kBitsPerInt - 1), SetCC); 2351 __ sub(r0, r1, Operand(r0, ASR, kBitsPerInt - 1), SetCC);
2369 2352
2370 // If the result is still negative, go to the slow case. 2353 // If the result is still negative, go to the slow case.
(...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after
3230 // ---------- S t a t e -------------- 3213 // ---------- S t a t e --------------
3231 // -- lr : return address 3214 // -- lr : return address
3232 // -- r0 : key 3215 // -- r0 : key
3233 // -- r1 : receiver 3216 // -- r1 : receiver
3234 // ----------------------------------- 3217 // -----------------------------------
3235 Label slow, miss_force_generic; 3218 Label slow, miss_force_generic;
3236 3219
3237 Register key = r0; 3220 Register key = r0;
3238 Register receiver = r1; 3221 Register receiver = r1;
3239 3222
3240 __ JumpIfNotSmi(key, &miss_force_generic); 3223 __ UntagAndJumpIfNotSmi(r2, key, &miss_force_generic);
3241 __ mov(r2, Operand(key, ASR, kSmiTagSize));
3242 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset)); 3224 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset));
3243 __ LoadFromNumberDictionary(&slow, r4, key, r0, r2, r3, r5); 3225 __ LoadFromNumberDictionary(&slow, r4, key, r0, r2, r3, r5);
3244 __ Ret(); 3226 __ Ret();
3245 3227
3246 __ bind(&slow); 3228 __ bind(&slow);
3247 __ IncrementCounter( 3229 __ IncrementCounter(
3248 masm->isolate()->counters()->keyed_load_external_array_slow(), 3230 masm->isolate()->counters()->keyed_load_external_array_slow(),
3249 1, r2, r3); 3231 1, r2, r3);
3250 3232
3251 // ---------- S t a t e -------------- 3233 // ---------- S t a t e --------------
(...skipping 11 matching lines...) Expand all
3263 // -- r0 : key 3245 // -- r0 : key
3264 // -- r1 : receiver 3246 // -- r1 : receiver
3265 // ----------------------------------- 3247 // -----------------------------------
3266 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); 3248 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
3267 } 3249 }
3268 3250
3269 3251
3270 static void GenerateSmiKeyCheck(MacroAssembler* masm, 3252 static void GenerateSmiKeyCheck(MacroAssembler* masm,
3271 Register key, 3253 Register key,
3272 Register scratch0, 3254 Register scratch0,
3273 Register scratch1,
3274 DwVfpRegister double_scratch0, 3255 DwVfpRegister double_scratch0,
3275 DwVfpRegister double_scratch1, 3256 DwVfpRegister double_scratch1,
3276 Label* fail) { 3257 Label* fail) {
3277 Label key_ok; 3258 Label key_ok;
3278 // Check for smi or a smi inside a heap number. We convert the heap 3259 // Check for smi or a smi inside a heap number. We convert the heap
3279 // number and check if the conversion is exact and fits into the smi 3260 // number and check if the conversion is exact and fits into the smi
3280 // range. 3261 // range.
3281 __ JumpIfSmi(key, &key_ok); 3262 __ JumpIfSmi(key, &key_ok);
3282 __ CheckMap(key, 3263 __ CheckMap(key,
3283 scratch0, 3264 scratch0,
3284 Heap::kHeapNumberMapRootIndex, 3265 Heap::kHeapNumberMapRootIndex,
3285 fail, 3266 fail,
3286 DONT_DO_SMI_CHECK); 3267 DONT_DO_SMI_CHECK);
3287 __ sub(ip, key, Operand(kHeapObjectTag)); 3268 __ sub(ip, key, Operand(kHeapObjectTag));
3288 __ vldr(double_scratch0, ip, HeapNumber::kValueOffset); 3269 __ vldr(double_scratch0, ip, HeapNumber::kValueOffset);
3289 __ TryDoubleToInt32Exact(scratch0, double_scratch0, double_scratch1); 3270 __ TryDoubleToInt32Exact(scratch0, double_scratch0, double_scratch1);
3290 __ b(ne, fail); 3271 __ b(ne, fail);
3291 __ TrySmiTag(scratch0, fail, scratch1); 3272 __ TrySmiTag(key, scratch0, fail);
3292 __ mov(key, scratch0);
3293 __ bind(&key_ok); 3273 __ bind(&key_ok);
3294 } 3274 }
3295 3275
3296 3276
3297 void KeyedStoreStubCompiler::GenerateStoreExternalArray( 3277 void KeyedStoreStubCompiler::GenerateStoreExternalArray(
3298 MacroAssembler* masm, 3278 MacroAssembler* masm,
3299 ElementsKind elements_kind) { 3279 ElementsKind elements_kind) {
3300 // ---------- S t a t e -------------- 3280 // ---------- S t a t e --------------
3301 // -- r0 : value 3281 // -- r0 : value
3302 // -- r1 : key 3282 // -- r1 : key
3303 // -- r2 : receiver 3283 // -- r2 : receiver
3304 // -- lr : return address 3284 // -- lr : return address
3305 // ----------------------------------- 3285 // -----------------------------------
3306 Label slow, check_heap_number, miss_force_generic; 3286 Label slow, check_heap_number, miss_force_generic;
3307 3287
3308 // Register usage. 3288 // Register usage.
3309 Register value = r0; 3289 Register value = r0;
3310 Register key = r1; 3290 Register key = r1;
3311 Register receiver = r2; 3291 Register receiver = r2;
3312 // r3 mostly holds the elements array or the destination external array. 3292 // r3 mostly holds the elements array or the destination external array.
3313 3293
3314 // This stub is meant to be tail-jumped to, the receiver must already 3294 // This stub is meant to be tail-jumped to, the receiver must already
3315 // have been verified by the caller to not be a smi. 3295 // have been verified by the caller to not be a smi.
3316 3296
3317 // Check that the key is a smi or a heap number convertible to a smi. 3297 // Check that the key is a smi or a heap number convertible to a smi.
3318 GenerateSmiKeyCheck(masm, key, r4, r5, d1, d2, &miss_force_generic); 3298 GenerateSmiKeyCheck(masm, key, r4, d1, d2, &miss_force_generic);
3319 3299
3320 __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset)); 3300 __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset));
3321 3301
3322 // Check that the index is in range 3302 // Check that the index is in range
3323 __ ldr(ip, FieldMemOperand(r3, ExternalArray::kLengthOffset)); 3303 __ ldr(ip, FieldMemOperand(r3, ExternalArray::kLengthOffset));
3324 __ cmp(key, ip); 3304 __ cmp(key, ip);
3325 // Unsigned comparison catches both negative and too-large values. 3305 // Unsigned comparison catches both negative and too-large values.
3326 __ b(hs, &miss_force_generic); 3306 __ b(hs, &miss_force_generic);
3327 3307
3328 // Handle both smis and HeapNumbers in the fast path. Go to the 3308 // Handle both smis and HeapNumbers in the fast path. Go to the
3329 // runtime for all other kinds of values. 3309 // runtime for all other kinds of values.
3330 // r3: external array. 3310 // r3: external array.
3331 if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) { 3311 if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) {
3332 // Double to pixel conversion is only implemented in the runtime for now. 3312 // Double to pixel conversion is only implemented in the runtime for now.
3333 __ JumpIfNotSmi(value, &slow); 3313 __ UntagAndJumpIfNotSmi(r5, value, &slow);
3334 } else { 3314 } else {
3335 __ JumpIfNotSmi(value, &check_heap_number); 3315 __ UntagAndJumpIfNotSmi(r5, value, &check_heap_number);
3336 } 3316 }
3337 __ SmiUntag(r5, value);
3338 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset)); 3317 __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset));
3339 3318
3340 // r3: base pointer of external storage. 3319 // r3: base pointer of external storage.
3341 // r5: value (integer). 3320 // r5: value (integer).
3342 switch (elements_kind) { 3321 switch (elements_kind) {
3343 case EXTERNAL_PIXEL_ELEMENTS: 3322 case EXTERNAL_PIXEL_ELEMENTS:
3344 // Clamp the value to [0..255]. 3323 // Clamp the value to [0..255].
3345 __ Usat(r5, 8, Operand(r5)); 3324 __ Usat(r5, 8, Operand(r5));
3346 __ strb(r5, MemOperand(r3, key, LSR, 1)); 3325 __ strb(r5, MemOperand(r3, key, LSR, 1));
3347 break; 3326 break;
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
3498 Register receiver_reg = r2; 3477 Register receiver_reg = r2;
3499 Register scratch = r4; 3478 Register scratch = r4;
3500 Register elements_reg = r3; 3479 Register elements_reg = r3;
3501 Register length_reg = r5; 3480 Register length_reg = r5;
3502 Register scratch2 = r6; 3481 Register scratch2 = r6;
3503 3482
3504 // This stub is meant to be tail-jumped to, the receiver must already 3483 // This stub is meant to be tail-jumped to, the receiver must already
3505 // have been verified by the caller to not be a smi. 3484 // have been verified by the caller to not be a smi.
3506 3485
3507 // Check that the key is a smi or a heap number convertible to a smi. 3486 // Check that the key is a smi or a heap number convertible to a smi.
3508 GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, d2, &miss_force_generic); 3487 GenerateSmiKeyCheck(masm, key_reg, r4, d1, d2, &miss_force_generic);
3509 3488
3510 if (IsFastSmiElementsKind(elements_kind)) { 3489 if (IsFastSmiElementsKind(elements_kind)) {
3511 __ JumpIfNotSmi(value_reg, &transition_elements_kind); 3490 __ JumpIfNotSmi(value_reg, &transition_elements_kind);
3512 } 3491 }
3513 3492
3514 // Check that the key is within bounds. 3493 // Check that the key is within bounds.
3515 __ ldr(elements_reg, 3494 __ ldr(elements_reg,
3516 FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); 3495 FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
3517 if (is_js_array) { 3496 if (is_js_array) {
3518 __ ldr(scratch, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); 3497 __ ldr(scratch, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
(...skipping 13 matching lines...) Expand all
3532 scratch, 3511 scratch,
3533 Heap::kFixedArrayMapRootIndex, 3512 Heap::kFixedArrayMapRootIndex,
3534 &miss_force_generic, 3513 &miss_force_generic,
3535 DONT_DO_SMI_CHECK); 3514 DONT_DO_SMI_CHECK);
3536 3515
3537 __ bind(&finish_store); 3516 __ bind(&finish_store);
3538 if (IsFastSmiElementsKind(elements_kind)) { 3517 if (IsFastSmiElementsKind(elements_kind)) {
3539 __ add(scratch, 3518 __ add(scratch,
3540 elements_reg, 3519 elements_reg,
3541 Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 3520 Operand(FixedArray::kHeaderSize - kHeapObjectTag));
3542 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); 3521 __ add(scratch, scratch, Operand::PointerOffsetFromSmiKey(key_reg));
3543 __ add(scratch,
3544 scratch,
3545 Operand(key_reg, LSL, kPointerSizeLog2 - kSmiTagSize));
3546 __ str(value_reg, MemOperand(scratch)); 3522 __ str(value_reg, MemOperand(scratch));
3547 } else { 3523 } else {
3548 ASSERT(IsFastObjectElementsKind(elements_kind)); 3524 ASSERT(IsFastObjectElementsKind(elements_kind));
3549 __ add(scratch, 3525 __ add(scratch,
3550 elements_reg, 3526 elements_reg,
3551 Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 3527 Operand(FixedArray::kHeaderSize - kHeapObjectTag));
3552 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2); 3528 __ add(scratch, scratch, Operand::PointerOffsetFromSmiKey(key_reg));
3553 __ add(scratch,
3554 scratch,
3555 Operand(key_reg, LSL, kPointerSizeLog2 - kSmiTagSize));
3556 __ str(value_reg, MemOperand(scratch)); 3529 __ str(value_reg, MemOperand(scratch));
3557 __ mov(receiver_reg, value_reg); 3530 __ mov(receiver_reg, value_reg);
3558 __ RecordWrite(elements_reg, // Object. 3531 __ RecordWrite(elements_reg, // Object.
3559 scratch, // Address. 3532 scratch, // Address.
3560 receiver_reg, // Value. 3533 receiver_reg, // Value.
3561 kLRHasNotBeenSaved, 3534 kLRHasNotBeenSaved,
3562 kDontSaveFPRegs); 3535 kDontSaveFPRegs);
3563 } 3536 }
3564 // value_reg (r0) is preserved. 3537 // value_reg (r0) is preserved.
3565 // Done. 3538 // Done.
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
3659 Register receiver_reg = r2; 3632 Register receiver_reg = r2;
3660 Register elements_reg = r3; 3633 Register elements_reg = r3;
3661 Register scratch1 = r4; 3634 Register scratch1 = r4;
3662 Register scratch2 = r5; 3635 Register scratch2 = r5;
3663 Register length_reg = r7; 3636 Register length_reg = r7;
3664 3637
3665 // This stub is meant to be tail-jumped to, the receiver must already 3638 // This stub is meant to be tail-jumped to, the receiver must already
3666 // have been verified by the caller to not be a smi. 3639 // have been verified by the caller to not be a smi.
3667 3640
3668 // Check that the key is a smi or a heap number convertible to a smi. 3641 // Check that the key is a smi or a heap number convertible to a smi.
3669 GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, d2, &miss_force_generic); 3642 GenerateSmiKeyCheck(masm, key_reg, r4, d1, d2, &miss_force_generic);
3670 3643
3671 __ ldr(elements_reg, 3644 __ ldr(elements_reg,
3672 FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); 3645 FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
3673 3646
3674 // Check that the key is within bounds. 3647 // Check that the key is within bounds.
3675 if (is_js_array) { 3648 if (is_js_array) {
3676 __ ldr(scratch1, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); 3649 __ ldr(scratch1, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
3677 } else { 3650 } else {
3678 __ ldr(scratch1, 3651 __ ldr(scratch1,
3679 FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); 3652 FieldMemOperand(elements_reg, FixedArray::kLengthOffset));
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
3777 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); 3750 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3778 } 3751 }
3779 } 3752 }
3780 3753
3781 3754
3782 #undef __ 3755 #undef __
3783 3756
3784 } } // namespace v8::internal 3757 } } // namespace v8::internal
3785 3758
3786 #endif // V8_TARGET_ARCH_ARM 3759 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698