| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 1599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1610 | 1610 |
| 1611 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) | 1611 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) |
| 1612 // tagged as a small integer. | 1612 // tagged as a small integer. |
| 1613 __ InvokeBuiltin(native, JUMP_FUNCTION); | 1613 __ InvokeBuiltin(native, JUMP_FUNCTION); |
| 1614 } | 1614 } |
| 1615 | 1615 |
| 1616 | 1616 |
| 1617 // This stub does not handle the inlined cases (Smis, Booleans, undefined). | 1617 // This stub does not handle the inlined cases (Smis, Booleans, undefined). |
| 1618 // The stub returns zero for false, and a non-zero value for true. | 1618 // The stub returns zero for false, and a non-zero value for true. |
| 1619 void ToBooleanStub::Generate(MacroAssembler* masm) { | 1619 void ToBooleanStub::Generate(MacroAssembler* masm) { |
| 1620 // This stub overrides SometimesSetsUpAFrame() to return false. That means |
| 1621 // we cannot call anything that could cause a GC from this stub. |
| 1620 // This stub uses VFP3 instructions. | 1622 // This stub uses VFP3 instructions. |
| 1621 CpuFeatures::Scope scope(VFP3); | 1623 CpuFeatures::Scope scope(VFP3); |
| 1622 | 1624 |
| 1623 Label false_result; | 1625 Label false_result; |
| 1624 Label not_heap_number; | 1626 Label not_heap_number; |
| 1625 Register scratch = r9.is(tos_) ? r7 : r9; | 1627 Register scratch = r9.is(tos_) ? r7 : r9; |
| 1626 | 1628 |
| 1627 // undefined -> false | 1629 // undefined -> false |
| 1628 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 1630 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 1629 __ cmp(tos_, ip); | 1631 __ cmp(tos_, ip); |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1875 if (mode_ == UNARY_OVERWRITE) { | 1877 if (mode_ == UNARY_OVERWRITE) { |
| 1876 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); | 1878 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); |
| 1877 __ eor(r2, r2, Operand(HeapNumber::kSignMask)); // Flip sign. | 1879 __ eor(r2, r2, Operand(HeapNumber::kSignMask)); // Flip sign. |
| 1878 __ str(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); | 1880 __ str(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); |
| 1879 } else { | 1881 } else { |
| 1880 Label slow_allocate_heapnumber, heapnumber_allocated; | 1882 Label slow_allocate_heapnumber, heapnumber_allocated; |
| 1881 __ AllocateHeapNumber(r1, r2, r3, r6, &slow_allocate_heapnumber); | 1883 __ AllocateHeapNumber(r1, r2, r3, r6, &slow_allocate_heapnumber); |
| 1882 __ jmp(&heapnumber_allocated); | 1884 __ jmp(&heapnumber_allocated); |
| 1883 | 1885 |
| 1884 __ bind(&slow_allocate_heapnumber); | 1886 __ bind(&slow_allocate_heapnumber); |
| 1885 __ EnterInternalFrame(); | 1887 { |
| 1886 __ push(r0); | 1888 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1887 __ CallRuntime(Runtime::kNumberAlloc, 0); | 1889 __ push(r0); |
| 1888 __ mov(r1, Operand(r0)); | 1890 __ CallRuntime(Runtime::kNumberAlloc, 0); |
| 1889 __ pop(r0); | 1891 __ mov(r1, Operand(r0)); |
| 1890 __ LeaveInternalFrame(); | 1892 __ pop(r0); |
| 1893 } |
| 1891 | 1894 |
| 1892 __ bind(&heapnumber_allocated); | 1895 __ bind(&heapnumber_allocated); |
| 1893 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); | 1896 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset)); |
| 1894 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); | 1897 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); |
| 1895 __ str(r3, FieldMemOperand(r1, HeapNumber::kMantissaOffset)); | 1898 __ str(r3, FieldMemOperand(r1, HeapNumber::kMantissaOffset)); |
| 1896 __ eor(r2, r2, Operand(HeapNumber::kSignMask)); // Flip sign. | 1899 __ eor(r2, r2, Operand(HeapNumber::kSignMask)); // Flip sign. |
| 1897 __ str(r2, FieldMemOperand(r1, HeapNumber::kExponentOffset)); | 1900 __ str(r2, FieldMemOperand(r1, HeapNumber::kExponentOffset)); |
| 1898 __ mov(r0, Operand(r1)); | 1901 __ mov(r0, Operand(r1)); |
| 1899 } | 1902 } |
| 1900 __ Ret(); | 1903 __ Ret(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1921 | 1924 |
| 1922 // Try to store the result in a heap number. | 1925 // Try to store the result in a heap number. |
| 1923 __ bind(&try_float); | 1926 __ bind(&try_float); |
| 1924 if (mode_ == UNARY_NO_OVERWRITE) { | 1927 if (mode_ == UNARY_NO_OVERWRITE) { |
| 1925 Label slow_allocate_heapnumber, heapnumber_allocated; | 1928 Label slow_allocate_heapnumber, heapnumber_allocated; |
| 1926 // Allocate a new heap number without zapping r0, which we need if it fails. | 1929 // Allocate a new heap number without zapping r0, which we need if it fails. |
| 1927 __ AllocateHeapNumber(r2, r3, r4, r6, &slow_allocate_heapnumber); | 1930 __ AllocateHeapNumber(r2, r3, r4, r6, &slow_allocate_heapnumber); |
| 1928 __ jmp(&heapnumber_allocated); | 1931 __ jmp(&heapnumber_allocated); |
| 1929 | 1932 |
| 1930 __ bind(&slow_allocate_heapnumber); | 1933 __ bind(&slow_allocate_heapnumber); |
| 1931 __ EnterInternalFrame(); | 1934 { |
| 1932 __ push(r0); // Push the heap number, not the untagged int32. | 1935 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1933 __ CallRuntime(Runtime::kNumberAlloc, 0); | 1936 __ push(r0); // Push the heap number, not the untagged int32. |
| 1934 __ mov(r2, r0); // Move the new heap number into r2. | 1937 __ CallRuntime(Runtime::kNumberAlloc, 0); |
| 1935 // Get the heap number into r0, now that the new heap number is in r2. | 1938 __ mov(r2, r0); // Move the new heap number into r2. |
| 1936 __ pop(r0); | 1939 // Get the heap number into r0, now that the new heap number is in r2. |
| 1937 __ LeaveInternalFrame(); | 1940 __ pop(r0); |
| 1941 } |
| 1938 | 1942 |
| 1939 // Convert the heap number in r0 to an untagged integer in r1. | 1943 // Convert the heap number in r0 to an untagged integer in r1. |
| 1940 // This can't go slow-case because it's the same number we already | 1944 // This can't go slow-case because it's the same number we already |
| 1941 // converted once again. | 1945 // converted once again. |
| 1942 __ ConvertToInt32(r0, r1, r3, r4, d0, &impossible); | 1946 __ ConvertToInt32(r0, r1, r3, r4, d0, &impossible); |
| 1943 __ mvn(r1, Operand(r1)); | 1947 __ mvn(r1, Operand(r1)); |
| 1944 | 1948 |
| 1945 __ bind(&heapnumber_allocated); | 1949 __ bind(&heapnumber_allocated); |
| 1946 __ mov(r0, r2); // Move newly allocated heap number to r0. | 1950 __ mov(r0, r2); // Move newly allocated heap number to r0. |
| 1947 } | 1951 } |
| (...skipping 1208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3156 __ vstr(d2, FieldMemOperand(r6, HeapNumber::kValueOffset)); | 3160 __ vstr(d2, FieldMemOperand(r6, HeapNumber::kValueOffset)); |
| 3157 __ stm(ia, cache_entry, r2.bit() | r3.bit() | r6.bit()); | 3161 __ stm(ia, cache_entry, r2.bit() | r3.bit() | r6.bit()); |
| 3158 __ Ret(); | 3162 __ Ret(); |
| 3159 | 3163 |
| 3160 __ bind(&invalid_cache); | 3164 __ bind(&invalid_cache); |
| 3161 // The cache is invalid. Call runtime which will recreate the | 3165 // The cache is invalid. Call runtime which will recreate the |
| 3162 // cache. | 3166 // cache. |
| 3163 __ LoadRoot(r5, Heap::kHeapNumberMapRootIndex); | 3167 __ LoadRoot(r5, Heap::kHeapNumberMapRootIndex); |
| 3164 __ AllocateHeapNumber(r0, scratch0, scratch1, r5, &skip_cache); | 3168 __ AllocateHeapNumber(r0, scratch0, scratch1, r5, &skip_cache); |
| 3165 __ vstr(d2, FieldMemOperand(r0, HeapNumber::kValueOffset)); | 3169 __ vstr(d2, FieldMemOperand(r0, HeapNumber::kValueOffset)); |
| 3166 __ EnterInternalFrame(); | 3170 { |
| 3167 __ push(r0); | 3171 FrameScope scope(masm, StackFrame::INTERNAL); |
| 3168 __ CallRuntime(RuntimeFunction(), 1); | 3172 __ push(r0); |
| 3169 __ LeaveInternalFrame(); | 3173 __ CallRuntime(RuntimeFunction(), 1); |
| 3174 } |
| 3170 __ vldr(d2, FieldMemOperand(r0, HeapNumber::kValueOffset)); | 3175 __ vldr(d2, FieldMemOperand(r0, HeapNumber::kValueOffset)); |
| 3171 __ Ret(); | 3176 __ Ret(); |
| 3172 | 3177 |
| 3173 __ bind(&skip_cache); | 3178 __ bind(&skip_cache); |
| 3174 // Call C function to calculate the result and answer directly | 3179 // Call C function to calculate the result and answer directly |
| 3175 // without updating the cache. | 3180 // without updating the cache. |
| 3176 GenerateCallCFunction(masm, scratch0); | 3181 GenerateCallCFunction(masm, scratch0); |
| 3177 __ GetCFunctionDoubleResult(d2); | 3182 __ GetCFunctionDoubleResult(d2); |
| 3178 __ bind(&no_update); | 3183 __ bind(&no_update); |
| 3179 | 3184 |
| 3180 // We return the value in d2 without adding it to the cache, but | 3185 // We return the value in d2 without adding it to the cache, but |
| 3181 // we cause a scavenging GC so that future allocations will succeed. | 3186 // we cause a scavenging GC so that future allocations will succeed. |
| 3182 __ EnterInternalFrame(); | 3187 { |
| 3188 FrameScope scope(masm, StackFrame::INTERNAL); |
| 3183 | 3189 |
| 3184 // Allocate an aligned object larger than a HeapNumber. | 3190 // Allocate an aligned object larger than a HeapNumber. |
| 3185 ASSERT(4 * kPointerSize >= HeapNumber::kSize); | 3191 ASSERT(4 * kPointerSize >= HeapNumber::kSize); |
| 3186 __ mov(scratch0, Operand(4 * kPointerSize)); | 3192 __ mov(scratch0, Operand(4 * kPointerSize)); |
| 3187 __ push(scratch0); | 3193 __ push(scratch0); |
| 3188 __ CallRuntimeSaveDoubles(Runtime::kAllocateInNewSpace); | 3194 __ CallRuntimeSaveDoubles(Runtime::kAllocateInNewSpace); |
| 3189 __ LeaveInternalFrame(); | 3195 } |
| 3190 __ Ret(); | 3196 __ Ret(); |
| 3191 } | 3197 } |
| 3192 } | 3198 } |
| 3193 | 3199 |
| 3194 | 3200 |
| 3195 void TranscendentalCacheStub::GenerateCallCFunction(MacroAssembler* masm, | 3201 void TranscendentalCacheStub::GenerateCallCFunction(MacroAssembler* masm, |
| 3196 Register scratch) { | 3202 Register scratch) { |
| 3197 Isolate* isolate = masm->isolate(); | 3203 Isolate* isolate = masm->isolate(); |
| 3198 | 3204 |
| 3199 __ push(lr); | 3205 __ push(lr); |
| (...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3862 __ Ret(HasArgsInRegisters() ? 0 : 2); | 3868 __ Ret(HasArgsInRegisters() ? 0 : 2); |
| 3863 | 3869 |
| 3864 // Slow-case. Tail call builtin. | 3870 // Slow-case. Tail call builtin. |
| 3865 __ bind(&slow); | 3871 __ bind(&slow); |
| 3866 if (!ReturnTrueFalseObject()) { | 3872 if (!ReturnTrueFalseObject()) { |
| 3867 if (HasArgsInRegisters()) { | 3873 if (HasArgsInRegisters()) { |
| 3868 __ Push(r0, r1); | 3874 __ Push(r0, r1); |
| 3869 } | 3875 } |
| 3870 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 3876 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
| 3871 } else { | 3877 } else { |
| 3872 __ EnterInternalFrame(); | 3878 { |
| 3873 __ Push(r0, r1); | 3879 FrameScope scope(masm, StackFrame::INTERNAL); |
| 3874 __ InvokeBuiltin(Builtins::INSTANCE_OF, CALL_FUNCTION); | 3880 __ Push(r0, r1); |
| 3875 __ LeaveInternalFrame(); | 3881 __ InvokeBuiltin(Builtins::INSTANCE_OF, CALL_FUNCTION); |
| 3882 } |
| 3876 __ cmp(r0, Operand(0)); | 3883 __ cmp(r0, Operand(0)); |
| 3877 __ LoadRoot(r0, Heap::kTrueValueRootIndex, eq); | 3884 __ LoadRoot(r0, Heap::kTrueValueRootIndex, eq); |
| 3878 __ LoadRoot(r0, Heap::kFalseValueRootIndex, ne); | 3885 __ LoadRoot(r0, Heap::kFalseValueRootIndex, ne); |
| 3879 __ Ret(HasArgsInRegisters() ? 0 : 2); | 3886 __ Ret(HasArgsInRegisters() ? 0 : 2); |
| 3880 } | 3887 } |
| 3881 } | 3888 } |
| 3882 | 3889 |
| 3883 | 3890 |
| 3884 Register InstanceofStub::left() { return r0; } | 3891 Register InstanceofStub::left() { return r0; } |
| 3885 | 3892 |
| (...skipping 2244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6130 } | 6137 } |
| 6131 | 6138 |
| 6132 | 6139 |
| 6133 void ICCompareStub::GenerateMiss(MacroAssembler* masm) { | 6140 void ICCompareStub::GenerateMiss(MacroAssembler* masm) { |
| 6134 __ Push(r1, r0); | 6141 __ Push(r1, r0); |
| 6135 __ push(lr); | 6142 __ push(lr); |
| 6136 | 6143 |
| 6137 // Call the runtime system in a fresh internal frame. | 6144 // Call the runtime system in a fresh internal frame. |
| 6138 ExternalReference miss = | 6145 ExternalReference miss = |
| 6139 ExternalReference(IC_Utility(IC::kCompareIC_Miss), masm->isolate()); | 6146 ExternalReference(IC_Utility(IC::kCompareIC_Miss), masm->isolate()); |
| 6140 __ EnterInternalFrame(); | 6147 { |
| 6141 __ Push(r1, r0); | 6148 FrameScope scope(masm, StackFrame::INTERNAL); |
| 6142 __ mov(ip, Operand(Smi::FromInt(op_))); | 6149 __ Push(r1, r0); |
| 6143 __ push(ip); | 6150 __ mov(ip, Operand(Smi::FromInt(op_))); |
| 6144 __ CallExternalReference(miss, 3); | 6151 __ push(ip); |
| 6145 __ LeaveInternalFrame(); | 6152 __ CallExternalReference(miss, 3); |
| 6153 } |
| 6146 // Compute the entry point of the rewritten stub. | 6154 // Compute the entry point of the rewritten stub. |
| 6147 __ add(r2, r0, Operand(Code::kHeaderSize - kHeapObjectTag)); | 6155 __ add(r2, r0, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 6148 // Restore registers. | 6156 // Restore registers. |
| 6149 __ pop(lr); | 6157 __ pop(lr); |
| 6150 __ pop(r0); | 6158 __ pop(r0); |
| 6151 __ pop(r1); | 6159 __ pop(r1); |
| 6152 __ Jump(r2); | 6160 __ Jump(r2); |
| 6153 } | 6161 } |
| 6154 | 6162 |
| 6155 | 6163 |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6316 __ tst(r0, Operand(r0)); | 6324 __ tst(r0, Operand(r0)); |
| 6317 __ mov(scratch2, Operand(r2)); | 6325 __ mov(scratch2, Operand(r2)); |
| 6318 __ ldm(ia_w, sp, spill_mask); | 6326 __ ldm(ia_w, sp, spill_mask); |
| 6319 | 6327 |
| 6320 __ b(ne, done); | 6328 __ b(ne, done); |
| 6321 __ b(eq, miss); | 6329 __ b(eq, miss); |
| 6322 } | 6330 } |
| 6323 | 6331 |
| 6324 | 6332 |
| 6325 void StringDictionaryLookupStub::Generate(MacroAssembler* masm) { | 6333 void StringDictionaryLookupStub::Generate(MacroAssembler* masm) { |
| 6334 // This stub overrides SometimesSetsUpAFrame() to return false. That means |
| 6335 // we cannot call anything that could cause a GC from this stub. |
| 6326 // Registers: | 6336 // Registers: |
| 6327 // result: StringDictionary to probe | 6337 // result: StringDictionary to probe |
| 6328 // r1: key | 6338 // r1: key |
| 6329 // : StringDictionary to probe. | 6339 // : StringDictionary to probe. |
| 6330 // index_: will hold an index of entry if lookup is successful. | 6340 // index_: will hold an index of entry if lookup is successful. |
| 6331 // might alias with result_. | 6341 // might alias with result_. |
| 6332 // Returns: | 6342 // Returns: |
| 6333 // result_ is zero if lookup failed, non zero otherwise. | 6343 // result_ is zero if lookup failed, non zero otherwise. |
| 6334 | 6344 |
| 6335 Register result = r0; | 6345 Register result = r0; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6410 __ mov(result, Operand(0)); | 6420 __ mov(result, Operand(0)); |
| 6411 __ Ret(); | 6421 __ Ret(); |
| 6412 } | 6422 } |
| 6413 | 6423 |
| 6414 | 6424 |
| 6415 #undef __ | 6425 #undef __ |
| 6416 | 6426 |
| 6417 } } // namespace v8::internal | 6427 } } // namespace v8::internal |
| 6418 | 6428 |
| 6419 #endif // V8_TARGET_ARCH_ARM | 6429 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |