| Index: src/arm/ic-arm.cc
|
| ===================================================================
|
| --- src/arm/ic-arm.cc (revision 4607)
|
| +++ src/arm/ic-arm.cc (working copy)
|
| @@ -683,11 +683,9 @@
|
| // ---------- S t a t e --------------
|
| // -- lr : return address
|
| // -- r0 : key
|
| - // -- sp[0] : key
|
| - // -- sp[4] : receiver
|
| + // -- r1 : receiver
|
| // -----------------------------------
|
|
|
| - __ ldr(r1, MemOperand(sp, kPointerSize));
|
| __ Push(r1, r0);
|
|
|
| ExternalReference ref = ExternalReference(IC_Utility(kKeyedLoadIC_Miss));
|
| @@ -699,11 +697,9 @@
|
| // ---------- S t a t e --------------
|
| // -- lr : return address
|
| // -- r0 : key
|
| - // -- sp[0] : key
|
| - // -- sp[4] : receiver
|
| + // -- r1 : receiver
|
| // -----------------------------------
|
|
|
| - __ ldr(r1, MemOperand(sp, kPointerSize));
|
| __ Push(r1, r0);
|
|
|
| __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
|
| @@ -714,18 +710,17 @@
|
| // ---------- S t a t e --------------
|
| // -- lr : return address
|
| // -- r0 : key
|
| - // -- sp[0] : key
|
| - // -- sp[4] : receiver
|
| + // -- r1 : receiver
|
| // -----------------------------------
|
| Label slow, fast, check_pixel_array, check_number_dictionary;
|
|
|
| - // Get the object from the stack.
|
| - __ ldr(r1, MemOperand(sp, kPointerSize));
|
| + Register key = r0;
|
| + Register receiver = r1;
|
|
|
| // Check that the object isn't a smi.
|
| - __ BranchOnSmi(r1, &slow);
|
| + __ BranchOnSmi(receiver, &slow);
|
| // Get the map of the receiver.
|
| - __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
|
| + __ ldr(r2, FieldMemOperand(receiver, HeapObject::kMapOffset));
|
| // Check bit field.
|
| __ ldrb(r3, FieldMemOperand(r2, Map::kBitFieldOffset));
|
| __ tst(r3, Operand(kSlowCaseBitFieldMask));
|
| @@ -740,60 +735,65 @@
|
| __ b(lt, &slow);
|
|
|
| // Check that the key is a smi.
|
| - __ BranchOnNotSmi(r0, &slow);
|
| - // Save key in r2 in case we want it for the number dictionary case.
|
| - __ mov(r2, r0);
|
| - __ mov(r0, Operand(r0, ASR, kSmiTagSize));
|
| + __ BranchOnNotSmi(key, &slow);
|
| + // Untag key into r2..
|
| + __ mov(r2, Operand(key, ASR, kSmiTagSize));
|
|
|
| // Get the elements array of the object.
|
| - __ ldr(r1, FieldMemOperand(r1, JSObject::kElementsOffset));
|
| + __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset));
|
| // Check that the object is in fast mode (not dictionary).
|
| - __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
|
| + __ ldr(r3, FieldMemOperand(r4, HeapObject::kMapOffset));
|
| __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
|
| __ cmp(r3, ip);
|
| __ b(ne, &check_pixel_array);
|
| // Check that the key (index) is within bounds.
|
| - __ ldr(r3, FieldMemOperand(r1, Array::kLengthOffset));
|
| - __ cmp(r0, r3);
|
| + __ ldr(r3, FieldMemOperand(r4, Array::kLengthOffset));
|
| + __ cmp(r2, r3);
|
| __ b(hs, &slow);
|
| // Fast case: Do the load.
|
| - __ add(r3, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
|
| - __ ldr(r0, MemOperand(r3, r0, LSL, kPointerSizeLog2));
|
| + __ add(r3, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
|
| + __ ldr(r2, MemOperand(r3, r2, LSL, kPointerSizeLog2));
|
| __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
|
| - __ cmp(r0, ip);
|
| + __ cmp(r2, ip);
|
| // In case the loaded value is the_hole we have to consult GetProperty
|
| // to ensure the prototype chain is searched.
|
| __ b(eq, &slow);
|
| + __ mov(r0, r2);
|
| __ Ret();
|
|
|
| // Check whether the elements is a pixel array.
|
| + // r0: key
|
| + // r2: untagged index
|
| + // r3: elements map
|
| + // r4: elements
|
| __ bind(&check_pixel_array);
|
| __ LoadRoot(ip, Heap::kPixelArrayMapRootIndex);
|
| __ cmp(r3, ip);
|
| __ b(ne, &check_number_dictionary);
|
| - __ ldr(ip, FieldMemOperand(r1, PixelArray::kLengthOffset));
|
| - __ cmp(r0, ip);
|
| + __ ldr(ip, FieldMemOperand(r4, PixelArray::kLengthOffset));
|
| + __ cmp(r2, ip);
|
| __ b(hs, &slow);
|
| - __ ldr(ip, FieldMemOperand(r1, PixelArray::kExternalPointerOffset));
|
| - __ ldrb(r0, MemOperand(ip, r0));
|
| - __ mov(r0, Operand(r0, LSL, kSmiTagSize)); // Tag result as smi.
|
| + __ ldr(ip, FieldMemOperand(r4, PixelArray::kExternalPointerOffset));
|
| + __ ldrb(r2, MemOperand(ip, r2));
|
| + __ mov(r0, Operand(r2, LSL, kSmiTagSize)); // Tag result as smi.
|
| __ Ret();
|
|
|
| __ bind(&check_number_dictionary);
|
| // Check whether the elements is a number dictionary.
|
| - // r0: untagged index
|
| - // r1: elements
|
| - // r2: key
|
| + // r0: key
|
| + // r2: untagged index
|
| + // r3: elements map
|
| + // r4: elements
|
| __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
|
| __ cmp(r3, ip);
|
| __ b(ne, &slow);
|
| - GenerateNumberDictionaryLoad(masm, &slow, r1, r2, r0, r3, r4);
|
| + GenerateNumberDictionaryLoad(masm, &slow, r4, r0, r2, r3, r5);
|
| + __ mov(r0, r2);
|
| __ Ret();
|
|
|
| - // Slow case: Push extra copies of the arguments (2).
|
| + // Slow case, key and receiver still in r0 and r1.
|
| __ bind(&slow);
|
| - __ IncrementCounter(&Counters::keyed_load_generic_slow, 1, r0, r1);
|
| - __ ldr(r0, MemOperand(sp, 0));
|
| + __ IncrementCounter(&Counters::keyed_load_generic_slow, 1, r2, r3);
|
| GenerateRuntimeGetProperty(masm);
|
| }
|
|
|
| @@ -802,8 +802,7 @@
|
| // ---------- S t a t e --------------
|
| // -- lr : return address
|
| // -- r0 : key
|
| - // -- sp[0] : key
|
| - // -- sp[4] : receiver
|
| + // -- r1 : receiver
|
| // -----------------------------------
|
| Label miss;
|
| Label index_not_smi;
|
| @@ -811,9 +810,6 @@
|
| Label slow_char_code;
|
| Label got_char_code;
|
|
|
| - // Get the object from the stack.
|
| - __ ldr(r1, MemOperand(sp, kPointerSize));
|
| -
|
| Register object = r1;
|
| Register index = r0;
|
| Register code = r2;
|
| @@ -845,6 +841,7 @@
|
| // string and a number), and call runtime.
|
| __ bind(&slow_char_code);
|
| __ EnterInternalFrame();
|
| + ASSERT(object.code() > index.code());
|
| __ Push(object, index);
|
| __ CallRuntime(Runtime::kStringCharCodeAt, 2);
|
| ASSERT(!code.is(r0));
|
| @@ -913,25 +910,21 @@
|
| // ---------- S t a t e --------------
|
| // -- lr : return address
|
| // -- r0 : key
|
| - // -- sp[0] : key
|
| - // -- sp[4] : receiver
|
| + // -- r1 : receiver
|
| // -----------------------------------
|
| Label slow, failed_allocation;
|
|
|
| - // Get the object from the stack.
|
| - __ ldr(r1, MemOperand(sp, kPointerSize));
|
| + Register key = r0;
|
| + Register receiver = r1;
|
|
|
| - // r0: key
|
| - // r1: receiver object
|
| -
|
| // Check that the object isn't a smi
|
| - __ BranchOnSmi(r1, &slow);
|
| + __ BranchOnSmi(receiver, &slow);
|
|
|
| // Check that the key is a smi.
|
| - __ BranchOnNotSmi(r0, &slow);
|
| + __ BranchOnNotSmi(key, &slow);
|
|
|
| // Check that the object is a JS object. Load map into r2.
|
| - __ CompareObjectType(r1, r2, r3, FIRST_JS_OBJECT_TYPE);
|
| + __ CompareObjectType(receiver, r2, r3, FIRST_JS_OBJECT_TYPE);
|
| __ b(lt, &slow);
|
|
|
| // Check that the receiver does not require access checks. We need
|
| @@ -943,53 +936,51 @@
|
|
|
| // Check that the elements array is the appropriate type of
|
| // ExternalArray.
|
| - // r0: index (as a smi)
|
| - // r1: JSObject
|
| - __ ldr(r1, FieldMemOperand(r1, JSObject::kElementsOffset));
|
| - __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
|
| + __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset));
|
| + __ ldr(r2, FieldMemOperand(r3, HeapObject::kMapOffset));
|
| __ LoadRoot(ip, Heap::RootIndexForExternalArrayType(array_type));
|
| __ cmp(r2, ip);
|
| __ b(ne, &slow);
|
|
|
| // Check that the index is in range.
|
| - __ ldr(ip, FieldMemOperand(r1, ExternalArray::kLengthOffset));
|
| - __ cmp(r1, Operand(r0, ASR, kSmiTagSize));
|
| + __ ldr(ip, FieldMemOperand(r3, ExternalArray::kLengthOffset));
|
| + __ cmp(ip, Operand(key, ASR, kSmiTagSize));
|
| // Unsigned comparison catches both negative and too-large values.
|
| __ b(lo, &slow);
|
|
|
| - // r0: index (smi)
|
| - // r1: elements array
|
| - __ ldr(r1, FieldMemOperand(r1, ExternalArray::kExternalPointerOffset));
|
| - // r1: base pointer of external storage
|
| + // r3: elements array
|
| + __ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset));
|
| + // r3: base pointer of external storage
|
|
|
| // We are not untagging smi key and instead work with it
|
| // as if it was premultiplied by 2.
|
| ASSERT((kSmiTag == 0) && (kSmiTagSize == 1));
|
|
|
| + Register value = r2;
|
| switch (array_type) {
|
| case kExternalByteArray:
|
| - __ ldrsb(r0, MemOperand(r1, r0, LSR, 1));
|
| + __ ldrsb(value, MemOperand(r3, key, LSR, 1));
|
| break;
|
| case kExternalUnsignedByteArray:
|
| - __ ldrb(r0, MemOperand(r1, r0, LSR, 1));
|
| + __ ldrb(value, MemOperand(r3, key, LSR, 1));
|
| break;
|
| case kExternalShortArray:
|
| - __ ldrsh(r0, MemOperand(r1, r0, LSL, 0));
|
| + __ ldrsh(value, MemOperand(r3, key, LSL, 0));
|
| break;
|
| case kExternalUnsignedShortArray:
|
| - __ ldrh(r0, MemOperand(r1, r0, LSL, 0));
|
| + __ ldrh(value, MemOperand(r3, key, LSL, 0));
|
| break;
|
| case kExternalIntArray:
|
| case kExternalUnsignedIntArray:
|
| - __ ldr(r0, MemOperand(r1, r0, LSL, 1));
|
| + __ ldr(value, MemOperand(r3, key, LSL, 1));
|
| break;
|
| case kExternalFloatArray:
|
| if (CpuFeatures::IsSupported(VFP3)) {
|
| CpuFeatures::Scope scope(VFP3);
|
| - __ add(r0, r1, Operand(r0, LSL, 1));
|
| - __ vldr(s0, r0, 0);
|
| + __ add(r2, r3, Operand(key, LSL, 1));
|
| + __ vldr(s0, r2, 0);
|
| } else {
|
| - __ ldr(r0, MemOperand(r1, r0, LSL, 1));
|
| + __ ldr(value, MemOperand(r3, key, LSL, 1));
|
| }
|
| break;
|
| default:
|
| @@ -998,37 +989,36 @@
|
| }
|
|
|
| // For integer array types:
|
| - // r0: value
|
| + // r2: value
|
| // For floating-point array type
|
| // s0: value (if VFP3 is supported)
|
| - // r0: value (if VFP3 is not supported)
|
| + // r2: value (if VFP3 is not supported)
|
|
|
| if (array_type == kExternalIntArray) {
|
| // For the Int and UnsignedInt array types, we need to see whether
|
| // the value can be represented in a Smi. If not, we need to convert
|
| // it to a HeapNumber.
|
| Label box_int;
|
| - __ cmp(r0, Operand(0xC0000000));
|
| + __ cmp(value, Operand(0xC0000000));
|
| __ b(mi, &box_int);
|
| - __ mov(r0, Operand(r0, LSL, kSmiTagSize));
|
| + // Tag integer as smi and return it.
|
| + __ mov(r0, Operand(value, LSL, kSmiTagSize));
|
| __ Ret();
|
|
|
| __ bind(&box_int);
|
| -
|
| - __ mov(r1, r0);
|
| - // Allocate a HeapNumber for the int and perform int-to-double
|
| - // conversion.
|
| + // Allocate a HeapNumber for the result and perform int-to-double
|
| + // conversion. Use r0 for result as key is not needed any more.
|
| __ AllocateHeapNumber(r0, r3, r4, &slow);
|
|
|
| if (CpuFeatures::IsSupported(VFP3)) {
|
| CpuFeatures::Scope scope(VFP3);
|
| - __ vmov(s0, r1);
|
| + __ vmov(s0, value);
|
| __ vcvt_f64_s32(d0, s0);
|
| - __ sub(r1, r0, Operand(kHeapObjectTag));
|
| - __ vstr(d0, r1, HeapNumber::kValueOffset);
|
| + __ sub(r3, r0, Operand(kHeapObjectTag));
|
| + __ vstr(d0, r3, HeapNumber::kValueOffset);
|
| __ Ret();
|
| } else {
|
| - WriteInt32ToHeapNumberStub stub(r1, r0, r3);
|
| + WriteInt32ToHeapNumberStub stub(value, r0, r3);
|
| __ TailCallStub(&stub);
|
| }
|
| } else if (array_type == kExternalUnsignedIntArray) {
|
| @@ -1038,51 +1028,60 @@
|
| if (CpuFeatures::IsSupported(VFP3)) {
|
| CpuFeatures::Scope scope(VFP3);
|
| Label box_int, done;
|
| - __ tst(r0, Operand(0xC0000000));
|
| + __ tst(value, Operand(0xC0000000));
|
| __ b(ne, &box_int);
|
| -
|
| - __ mov(r0, Operand(r0, LSL, kSmiTagSize));
|
| + // Tag integer as smi and return it.
|
| + __ mov(r0, Operand(value, LSL, kSmiTagSize));
|
| __ Ret();
|
|
|
| __ bind(&box_int);
|
| - __ vmov(s0, r0);
|
| - __ AllocateHeapNumber(r0, r1, r2, &slow);
|
| + __ vmov(s0, value);
|
| + // Allocate a HeapNumber for the result and perform int-to-double
|
| + // conversion. Don't use r0 and r1 as AllocateHeapNumber clobbers all
|
| + // registers - also when jumping due to exhausted young space.
|
| + __ AllocateHeapNumber(r2, r3, r4, &slow);
|
|
|
| __ vcvt_f64_u32(d0, s0);
|
| - __ sub(r1, r0, Operand(kHeapObjectTag));
|
| + __ sub(r1, r2, Operand(kHeapObjectTag));
|
| __ vstr(d0, r1, HeapNumber::kValueOffset);
|
| +
|
| + __ mov(r0, r2);
|
| __ Ret();
|
| } else {
|
| // Check whether unsigned integer fits into smi.
|
| Label box_int_0, box_int_1, done;
|
| - __ tst(r0, Operand(0x80000000));
|
| + __ tst(value, Operand(0x80000000));
|
| __ b(ne, &box_int_0);
|
| - __ tst(r0, Operand(0x40000000));
|
| + __ tst(value, Operand(0x40000000));
|
| __ b(ne, &box_int_1);
|
| -
|
| // Tag integer as smi and return it.
|
| - __ mov(r0, Operand(r0, LSL, kSmiTagSize));
|
| + __ mov(r0, Operand(value, LSL, kSmiTagSize));
|
| __ Ret();
|
|
|
| + Register hiword = value; // r2.
|
| + Register loword = r3;
|
| +
|
| __ bind(&box_int_0);
|
| // Integer does not have leading zeros.
|
| - GenerateUInt2Double(masm, r0, r1, r2, 0);
|
| + GenerateUInt2Double(masm, hiword, loword, r4, 0);
|
| __ b(&done);
|
|
|
| __ bind(&box_int_1);
|
| // Integer has one leading zero.
|
| - GenerateUInt2Double(masm, r0, r1, r2, 1);
|
| + GenerateUInt2Double(masm, hiword, loword, r4, 1);
|
|
|
| +
|
| __ bind(&done);
|
| - // Integer was converted to double in registers r0:r1.
|
| - // Wrap it into a HeapNumber.
|
| - __ AllocateHeapNumber(r2, r3, r5, &slow);
|
| + // Integer was converted to double in registers hiword:loword.
|
| + // Wrap it into a HeapNumber. Don't use r0 and r1 as AllocateHeapNumber
|
| + // clobbers all registers - also when jumping due to exhausted young
|
| + // space.
|
| + __ AllocateHeapNumber(r4, r5, r6, &slow);
|
|
|
| - __ str(r0, FieldMemOperand(r2, HeapNumber::kExponentOffset));
|
| - __ str(r1, FieldMemOperand(r2, HeapNumber::kMantissaOffset));
|
| + __ str(hiword, FieldMemOperand(r4, HeapNumber::kExponentOffset));
|
| + __ str(loword, FieldMemOperand(r4, HeapNumber::kMantissaOffset));
|
|
|
| - __ mov(r0, r2);
|
| -
|
| + __ mov(r0, r4);
|
| __ Ret();
|
| }
|
| } else if (array_type == kExternalFloatArray) {
|
| @@ -1090,40 +1089,52 @@
|
| // HeapNumber.
|
| if (CpuFeatures::IsSupported(VFP3)) {
|
| CpuFeatures::Scope scope(VFP3);
|
| - __ AllocateHeapNumber(r0, r1, r2, &slow);
|
| + // Allocate a HeapNumber for the result. Don't use r0 and r1 as
|
| + // AllocateHeapNumber clobbers all registers - also when jumping due to
|
| + // exhausted young space.
|
| + __ AllocateHeapNumber(r2, r3, r4, &slow);
|
| __ vcvt_f64_f32(d0, s0);
|
| - __ sub(r1, r0, Operand(kHeapObjectTag));
|
| + __ sub(r1, r2, Operand(kHeapObjectTag));
|
| __ vstr(d0, r1, HeapNumber::kValueOffset);
|
| +
|
| + __ mov(r0, r2);
|
| __ Ret();
|
| } else {
|
| - __ AllocateHeapNumber(r3, r1, r2, &slow);
|
| + // Allocate a HeapNumber for the result. Don't use r0 and r1 as
|
| + // AllocateHeapNumber clobbers all registers - also when jumping due to
|
| + // exhausted young space.
|
| + __ AllocateHeapNumber(r3, r4, r5, &slow);
|
| // VFP is not available, do manual single to double conversion.
|
|
|
| - // r0: floating point value (binary32)
|
| + // r2: floating point value (binary32)
|
| + // r3: heap number for result
|
|
|
| - // Extract mantissa to r1.
|
| - __ and_(r1, r0, Operand(kBinary32MantissaMask));
|
| + // Extract mantissa to r0. OK to clobber r0 now as there are no jumps to
|
| + // the slow case from here.
|
| + __ and_(r0, value, Operand(kBinary32MantissaMask));
|
|
|
| - // Extract exponent to r2.
|
| - __ mov(r2, Operand(r0, LSR, kBinary32MantissaBits));
|
| - __ and_(r2, r2, Operand(kBinary32ExponentMask >> kBinary32MantissaBits));
|
| + // Extract exponent to r1. OK to clobber r1 now as there are no jumps to
|
| + // the slow case from here.
|
| + __ mov(r1, Operand(value, LSR, kBinary32MantissaBits));
|
| + __ and_(r1, r1, Operand(kBinary32ExponentMask >> kBinary32MantissaBits));
|
|
|
| Label exponent_rebiased;
|
| - __ teq(r2, Operand(0x00));
|
| + __ teq(r1, Operand(0x00));
|
| __ b(eq, &exponent_rebiased);
|
|
|
| - __ teq(r2, Operand(0xff));
|
| - __ mov(r2, Operand(0x7ff), LeaveCC, eq);
|
| + __ teq(r1, Operand(0xff));
|
| + __ mov(r1, Operand(0x7ff), LeaveCC, eq);
|
| __ b(eq, &exponent_rebiased);
|
|
|
| // Rebias exponent.
|
| - __ add(r2,
|
| - r2,
|
| + __ add(r1,
|
| + r1,
|
| Operand(-kBinary32ExponentBias + HeapNumber::kExponentBias));
|
|
|
| __ bind(&exponent_rebiased);
|
| - __ and_(r0, r0, Operand(kBinary32SignMask));
|
| - __ orr(r0, r0, Operand(r2, LSL, HeapNumber::kMantissaBitsInTopWord));
|
| + __ and_(r2, value, Operand(kBinary32SignMask));
|
| + value = no_reg;
|
| + __ orr(r2, r2, Operand(r1, LSL, HeapNumber::kMantissaBitsInTopWord));
|
|
|
| // Shift mantissa.
|
| static const int kMantissaShiftForHiWord =
|
| @@ -1132,24 +1143,25 @@
|
| static const int kMantissaShiftForLoWord =
|
| kBitsPerInt - kMantissaShiftForHiWord;
|
|
|
| - __ orr(r0, r0, Operand(r1, LSR, kMantissaShiftForHiWord));
|
| - __ mov(r1, Operand(r1, LSL, kMantissaShiftForLoWord));
|
| + __ orr(r2, r2, Operand(r0, LSR, kMantissaShiftForHiWord));
|
| + __ mov(r0, Operand(r0, LSL, kMantissaShiftForLoWord));
|
|
|
| - __ str(r0, FieldMemOperand(r3, HeapNumber::kExponentOffset));
|
| - __ str(r1, FieldMemOperand(r3, HeapNumber::kMantissaOffset));
|
| + __ str(r2, FieldMemOperand(r3, HeapNumber::kExponentOffset));
|
| + __ str(r0, FieldMemOperand(r3, HeapNumber::kMantissaOffset));
|
| +
|
| __ mov(r0, r3);
|
| __ Ret();
|
| }
|
|
|
| } else {
|
| - __ mov(r0, Operand(r0, LSL, kSmiTagSize));
|
| + // Tag integer as smi and return it.
|
| + __ mov(r0, Operand(value, LSL, kSmiTagSize));
|
| __ Ret();
|
| }
|
|
|
| - // Slow case: Load name and receiver from stack and jump to runtime.
|
| + // Slow case, key and receiver still in r0 and r1.
|
| __ bind(&slow);
|
| - __ IncrementCounter(&Counters::keyed_load_external_array_slow, 1, r0, r1);
|
| - __ ldr(r0, MemOperand(sp, 0));
|
| + __ IncrementCounter(&Counters::keyed_load_external_array_slow, 1, r2, r3);
|
| GenerateRuntimeGetProperty(masm);
|
| }
|
|
|
| @@ -1158,14 +1170,10 @@
|
| // ---------- S t a t e --------------
|
| // -- lr : return address
|
| // -- r0 : key
|
| - // -- sp[0] : key
|
| - // -- sp[4] : receiver
|
| + // -- r1 : receiver
|
| // -----------------------------------
|
| Label slow;
|
|
|
| - // Get the object from the stack.
|
| - __ ldr(r1, MemOperand(sp, kPointerSize));
|
| -
|
| // Check that the receiver isn't a smi.
|
| __ BranchOnSmi(r1, &slow);
|
|
|
|
|