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 #if V8_TARGET_ARCH_ARM | 5 #if V8_TARGET_ARCH_ARM |
6 | 6 |
7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
537 // NOTICE! This code is only reached after a smi-fast-case check, so | 537 // NOTICE! This code is only reached after a smi-fast-case check, so |
538 // it is certain that at least one operand isn't a smi. | 538 // it is certain that at least one operand isn't a smi. |
539 | 539 |
540 // Handle the case where the objects are identical. Either returns the answer | 540 // Handle the case where the objects are identical. Either returns the answer |
541 // or goes to slow. Only falls through if the objects were not identical. | 541 // or goes to slow. Only falls through if the objects were not identical. |
542 EmitIdenticalObjectComparison(masm, &slow, cc); | 542 EmitIdenticalObjectComparison(masm, &slow, cc); |
543 | 543 |
544 // If either is a Smi (we know that not both are), then they can only | 544 // If either is a Smi (we know that not both are), then they can only |
545 // be strictly equal if the other is a HeapNumber. | 545 // be strictly equal if the other is a HeapNumber. |
546 STATIC_ASSERT(kSmiTag == 0); | 546 STATIC_ASSERT(kSmiTag == 0); |
547 DCHECK_EQ(static_cast<Smi*>(0), Smi::kZero); | 547 DCHECK_EQ(static_cast<Smi*>(0), Smi::FromInt(0)); |
548 __ and_(r2, lhs, Operand(rhs)); | 548 __ and_(r2, lhs, Operand(rhs)); |
549 __ JumpIfNotSmi(r2, ¬_smis); | 549 __ JumpIfNotSmi(r2, ¬_smis); |
550 // One operand is a smi. EmitSmiNonsmiComparison generates code that can: | 550 // One operand is a smi. EmitSmiNonsmiComparison generates code that can: |
551 // 1) Return the answer. | 551 // 1) Return the answer. |
552 // 2) Go to slow. | 552 // 2) Go to slow. |
553 // 3) Fall through to both_loaded_as_doubles. | 553 // 3) Fall through to both_loaded_as_doubles. |
554 // 4) Jump to lhs_not_nan. | 554 // 4) Jump to lhs_not_nan. |
555 // In cases 3 and 4 we have found out we were dealing with a number-number | 555 // In cases 3 and 4 we have found out we were dealing with a number-number |
556 // comparison. The double values of the numbers have been loaded into d7 (lhs) | 556 // comparison. The double values of the numbers have been loaded into d7 (lhs) |
557 // and d6 (rhs). | 557 // and d6 (rhs). |
(...skipping 3651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4209 __ cmp(r6, Operand(r5)); | 4209 __ cmp(r6, Operand(r5)); |
4210 __ mov(r6, Operand(r5), LeaveCC, gt); | 4210 __ mov(r6, Operand(r5), LeaveCC, gt); |
4211 | 4211 |
4212 __ bind(&try_allocate); | 4212 __ bind(&try_allocate); |
4213 | 4213 |
4214 // Compute the sizes of backing store, parameter map, and arguments object. | 4214 // Compute the sizes of backing store, parameter map, and arguments object. |
4215 // 1. Parameter map, has 2 extra words containing context and backing store. | 4215 // 1. Parameter map, has 2 extra words containing context and backing store. |
4216 const int kParameterMapHeaderSize = | 4216 const int kParameterMapHeaderSize = |
4217 FixedArray::kHeaderSize + 2 * kPointerSize; | 4217 FixedArray::kHeaderSize + 2 * kPointerSize; |
4218 // If there are no mapped parameters, we do not need the parameter_map. | 4218 // If there are no mapped parameters, we do not need the parameter_map. |
4219 __ cmp(r6, Operand(Smi::kZero)); | 4219 __ cmp(r6, Operand(Smi::FromInt(0))); |
4220 __ mov(r9, Operand::Zero(), LeaveCC, eq); | 4220 __ mov(r9, Operand::Zero(), LeaveCC, eq); |
4221 __ mov(r9, Operand(r6, LSL, 1), LeaveCC, ne); | 4221 __ mov(r9, Operand(r6, LSL, 1), LeaveCC, ne); |
4222 __ add(r9, r9, Operand(kParameterMapHeaderSize), LeaveCC, ne); | 4222 __ add(r9, r9, Operand(kParameterMapHeaderSize), LeaveCC, ne); |
4223 | 4223 |
4224 // 2. Backing store. | 4224 // 2. Backing store. |
4225 __ add(r9, r9, Operand(r5, LSL, 1)); | 4225 __ add(r9, r9, Operand(r5, LSL, 1)); |
4226 __ add(r9, r9, Operand(FixedArray::kHeaderSize)); | 4226 __ add(r9, r9, Operand(FixedArray::kHeaderSize)); |
4227 | 4227 |
4228 // 3. Arguments object. | 4228 // 3. Arguments object. |
4229 __ add(r9, r9, Operand(JSSloppyArgumentsObject::kSize)); | 4229 __ add(r9, r9, Operand(JSSloppyArgumentsObject::kSize)); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4266 // it will point to the backing store. | 4266 // it will point to the backing store. |
4267 __ add(r4, r0, Operand(JSSloppyArgumentsObject::kSize)); | 4267 __ add(r4, r0, Operand(JSSloppyArgumentsObject::kSize)); |
4268 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset)); | 4268 __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset)); |
4269 | 4269 |
4270 // r0 = address of new object (tagged) | 4270 // r0 = address of new object (tagged) |
4271 // r2 = argument count (tagged) | 4271 // r2 = argument count (tagged) |
4272 // r4 = address of parameter map or backing store (tagged) | 4272 // r4 = address of parameter map or backing store (tagged) |
4273 // r6 = mapped parameter count (tagged) | 4273 // r6 = mapped parameter count (tagged) |
4274 // Initialize parameter map. If there are no mapped arguments, we're done. | 4274 // Initialize parameter map. If there are no mapped arguments, we're done. |
4275 Label skip_parameter_map; | 4275 Label skip_parameter_map; |
4276 __ cmp(r6, Operand(Smi::kZero)); | 4276 __ cmp(r6, Operand(Smi::FromInt(0))); |
4277 // Move backing store address to r1, because it is | 4277 // Move backing store address to r1, because it is |
4278 // expected there when filling in the unmapped arguments. | 4278 // expected there when filling in the unmapped arguments. |
4279 __ mov(r1, r4, LeaveCC, eq); | 4279 __ mov(r1, r4, LeaveCC, eq); |
4280 __ b(eq, &skip_parameter_map); | 4280 __ b(eq, &skip_parameter_map); |
4281 | 4281 |
4282 __ LoadRoot(r5, Heap::kSloppyArgumentsElementsMapRootIndex); | 4282 __ LoadRoot(r5, Heap::kSloppyArgumentsElementsMapRootIndex); |
4283 __ str(r5, FieldMemOperand(r4, FixedArray::kMapOffset)); | 4283 __ str(r5, FieldMemOperand(r4, FixedArray::kMapOffset)); |
4284 __ add(r5, r6, Operand(Smi::FromInt(2))); | 4284 __ add(r5, r6, Operand(Smi::FromInt(2))); |
4285 __ str(r5, FieldMemOperand(r4, FixedArray::kLengthOffset)); | 4285 __ str(r5, FieldMemOperand(r4, FixedArray::kLengthOffset)); |
4286 __ str(cp, FieldMemOperand(r4, FixedArray::kHeaderSize + 0 * kPointerSize)); | 4286 __ str(cp, FieldMemOperand(r4, FixedArray::kHeaderSize + 0 * kPointerSize)); |
(...skipping 27 matching lines...) Expand all Loading... |
4314 | 4314 |
4315 __ bind(¶meters_loop); | 4315 __ bind(¶meters_loop); |
4316 __ sub(r5, r5, Operand(Smi::FromInt(1))); | 4316 __ sub(r5, r5, Operand(Smi::FromInt(1))); |
4317 __ mov(r0, Operand(r5, LSL, 1)); | 4317 __ mov(r0, Operand(r5, LSL, 1)); |
4318 __ add(r0, r0, Operand(kParameterMapHeaderSize - kHeapObjectTag)); | 4318 __ add(r0, r0, Operand(kParameterMapHeaderSize - kHeapObjectTag)); |
4319 __ str(r9, MemOperand(r4, r0)); | 4319 __ str(r9, MemOperand(r4, r0)); |
4320 __ sub(r0, r0, Operand(kParameterMapHeaderSize - FixedArray::kHeaderSize)); | 4320 __ sub(r0, r0, Operand(kParameterMapHeaderSize - FixedArray::kHeaderSize)); |
4321 __ str(ip, MemOperand(r1, r0)); | 4321 __ str(ip, MemOperand(r1, r0)); |
4322 __ add(r9, r9, Operand(Smi::FromInt(1))); | 4322 __ add(r9, r9, Operand(Smi::FromInt(1))); |
4323 __ bind(¶meters_test); | 4323 __ bind(¶meters_test); |
4324 __ cmp(r5, Operand(Smi::kZero)); | 4324 __ cmp(r5, Operand(Smi::FromInt(0))); |
4325 __ b(ne, ¶meters_loop); | 4325 __ b(ne, ¶meters_loop); |
4326 | 4326 |
4327 // Restore r0 = new object (tagged) and r5 = argument count (tagged). | 4327 // Restore r0 = new object (tagged) and r5 = argument count (tagged). |
4328 __ sub(r0, r4, Operand(JSSloppyArgumentsObject::kSize)); | 4328 __ sub(r0, r4, Operand(JSSloppyArgumentsObject::kSize)); |
4329 __ ldr(r5, FieldMemOperand(r0, JSSloppyArgumentsObject::kLengthOffset)); | 4329 __ ldr(r5, FieldMemOperand(r0, JSSloppyArgumentsObject::kLengthOffset)); |
4330 | 4330 |
4331 __ bind(&skip_parameter_map); | 4331 __ bind(&skip_parameter_map); |
4332 // r0 = address of new object (tagged) | 4332 // r0 = address of new object (tagged) |
4333 // r1 = address of backing store (tagged) | 4333 // r1 = address of backing store (tagged) |
4334 // r5 = argument count (tagged) | 4334 // r5 = argument count (tagged) |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4874 Register api_function_address = r2; | 4874 Register api_function_address = r2; |
4875 | 4875 |
4876 __ push(receiver); | 4876 __ push(receiver); |
4877 // Push data from AccessorInfo. | 4877 // Push data from AccessorInfo. |
4878 __ ldr(scratch, FieldMemOperand(callback, AccessorInfo::kDataOffset)); | 4878 __ ldr(scratch, FieldMemOperand(callback, AccessorInfo::kDataOffset)); |
4879 __ push(scratch); | 4879 __ push(scratch); |
4880 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); | 4880 __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex); |
4881 __ Push(scratch, scratch); | 4881 __ Push(scratch, scratch); |
4882 __ mov(scratch, Operand(ExternalReference::isolate_address(isolate()))); | 4882 __ mov(scratch, Operand(ExternalReference::isolate_address(isolate()))); |
4883 __ Push(scratch, holder); | 4883 __ Push(scratch, holder); |
4884 __ Push(Smi::kZero); // should_throw_on_error -> false | 4884 __ Push(Smi::FromInt(0)); // should_throw_on_error -> false |
4885 __ ldr(scratch, FieldMemOperand(callback, AccessorInfo::kNameOffset)); | 4885 __ ldr(scratch, FieldMemOperand(callback, AccessorInfo::kNameOffset)); |
4886 __ push(scratch); | 4886 __ push(scratch); |
4887 // v8::PropertyCallbackInfo::args_ array and name handle. | 4887 // v8::PropertyCallbackInfo::args_ array and name handle. |
4888 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; | 4888 const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; |
4889 | 4889 |
4890 // Load address of v8::PropertyAccessorInfo::args_ array and name handle. | 4890 // Load address of v8::PropertyAccessorInfo::args_ array and name handle. |
4891 __ mov(r0, sp); // r0 = Handle<Name> | 4891 __ mov(r0, sp); // r0 = Handle<Name> |
4892 __ add(r1, r0, Operand(1 * kPointerSize)); // r1 = v8::PCI::args_ | 4892 __ add(r1, r0, Operand(1 * kPointerSize)); // r1 = v8::PCI::args_ |
4893 | 4893 |
4894 const int kApiStackSpace = 1; | 4894 const int kApiStackSpace = 1; |
(...skipping 18 matching lines...) Expand all Loading... |
4913 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, | 4913 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, |
4914 kStackUnwindSpace, NULL, return_value_operand, NULL); | 4914 kStackUnwindSpace, NULL, return_value_operand, NULL); |
4915 } | 4915 } |
4916 | 4916 |
4917 #undef __ | 4917 #undef __ |
4918 | 4918 |
4919 } // namespace internal | 4919 } // namespace internal |
4920 } // namespace v8 | 4920 } // namespace v8 |
4921 | 4921 |
4922 #endif // V8_TARGET_ARCH_ARM | 4922 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |