| Index: src/arm/ic-arm.cc
|
| diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc
|
| index 1fd70982542a2a2058c72790d0fbbc13c7ea0040..ca7cc13c65b84e5ee8a5ebda63a298ed5150462a 100644
|
| --- a/src/arm/ic-arm.cc
|
| +++ b/src/arm/ic-arm.cc
|
| @@ -414,17 +414,17 @@ void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) {
|
| // Falls through for regular JS object.
|
| static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm,
|
| Register receiver,
|
| - Register scratch1,
|
| - Register scratch2,
|
| + Register map,
|
| + Register scratch,
|
| int interceptor_bit,
|
| Label* slow) {
|
| // Check that the object isn't a smi.
|
| __ BranchOnSmi(receiver, slow);
|
| // Get the map of the receiver.
|
| - __ ldr(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset));
|
| + __ ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
|
| // Check bit field.
|
| - __ ldrb(scratch2, FieldMemOperand(scratch1, Map::kBitFieldOffset));
|
| - __ tst(scratch2,
|
| + __ ldrb(scratch, FieldMemOperand(map, Map::kBitFieldOffset));
|
| + __ tst(scratch,
|
| Operand((1 << Map::kIsAccessCheckNeeded) | (1 << interceptor_bit)));
|
| __ b(nz, slow);
|
| // Check that the object is some kind of JS object EXCEPT JS Value type.
|
| @@ -432,13 +432,14 @@ static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm,
|
| // we enter the runtime system to make sure that indexing into string
|
| // objects work as intended.
|
| ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE);
|
| - __ ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset));
|
| - __ cmp(scratch1, Operand(JS_OBJECT_TYPE));
|
| + __ ldrb(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
|
| + __ cmp(scratch, Operand(JS_OBJECT_TYPE));
|
| __ b(lt, slow);
|
| }
|
|
|
|
|
| // Loads an indexed element from a fast case array.
|
| +// If not_fast_array is NULL, doesn't perform the elements map check.
|
| static void GenerateFastArrayLoad(MacroAssembler* masm,
|
| Register receiver,
|
| Register key,
|
| @@ -471,11 +472,15 @@ static void GenerateFastArrayLoad(MacroAssembler* masm,
|
| // scratch2 - used to hold the loaded value.
|
|
|
| __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
|
| - // Check that the object is in fast mode (not dictionary).
|
| - __ ldr(scratch1, FieldMemOperand(elements, HeapObject::kMapOffset));
|
| - __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
|
| - __ cmp(scratch1, ip);
|
| - __ b(ne, not_fast_array);
|
| + if (not_fast_array != NULL) {
|
| + // Check that the object is in fast mode and writable.
|
| + __ ldr(scratch1, FieldMemOperand(elements, HeapObject::kMapOffset));
|
| + __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
|
| + __ cmp(scratch1, ip);
|
| + __ b(ne, not_fast_array);
|
| + } else {
|
| + __ AssertFastElements(elements);
|
| + }
|
| // Check that the key (index) is within bounds.
|
| __ ldr(scratch1, FieldMemOperand(elements, FixedArray::kLengthOffset));
|
| __ cmp(key, Operand(scratch1));
|
| @@ -1120,16 +1125,23 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
| GenerateKeyedLoadReceiverCheck(
|
| masm, receiver, r2, r3, Map::kHasIndexedInterceptor, &slow);
|
|
|
| + // Check the "has fast elements" bit in the receiver's map which is
|
| + // now in r2.
|
| + __ ldrb(r3, FieldMemOperand(r2, Map::kBitField2Offset));
|
| + __ tst(r3, Operand(1 << Map::kHasFastElements));
|
| + __ b(eq, &check_pixel_array);
|
| +
|
| GenerateFastArrayLoad(
|
| - masm, receiver, key, r4, r3, r2, r0, &check_pixel_array, &slow);
|
| + masm, receiver, key, r4, r3, r2, r0, NULL, &slow);
|
| __ IncrementCounter(&Counters::keyed_load_generic_smi, 1, r2, r3);
|
| __ Ret();
|
|
|
| // Check whether the elements is a pixel array.
|
| // r0: key
|
| - // r3: elements map
|
| - // r4: elements
|
| + // r1: receiver
|
| __ bind(&check_pixel_array);
|
| + __ ldr(r4, FieldMemOperand(r1, JSObject::kElementsOffset));
|
| + __ ldr(r3, FieldMemOperand(r4, HeapObject::kMapOffset));
|
| __ LoadRoot(ip, Heap::kPixelArrayMapRootIndex);
|
| __ cmp(r3, ip);
|
| __ b(ne, &check_number_dictionary);
|
| @@ -1690,7 +1702,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
|
|
|
| // Object case: Check key against length in the elements array.
|
| __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
|
| - // Check that the object is in fast mode (not dictionary).
|
| + // Check that the object is in fast mode and writable.
|
| __ ldr(r4, FieldMemOperand(elements, HeapObject::kMapOffset));
|
| __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
|
| __ cmp(r4, ip);
|
| @@ -1748,8 +1760,8 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
|
| __ b(&fast);
|
|
|
| // Array case: Get the length and the elements array from the JS
|
| - // array. Check that the array is in fast mode; if it is the
|
| - // length is always a smi.
|
| + // array. Check that the array is in fast mode (and writable); if it
|
| + // is the length is always a smi.
|
| __ bind(&array);
|
| __ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
|
| __ ldr(r4, FieldMemOperand(elements, HeapObject::kMapOffset));
|
| @@ -2217,6 +2229,8 @@ void StoreIC::GenerateArrayLength(MacroAssembler* masm) {
|
| __ b(ne, &miss);
|
|
|
| // Check that elements are FixedArray.
|
| + // We rely on StoreIC_ArrayLength below to deal with all types of
|
| + // fast elements (including COW).
|
| __ ldr(scratch, FieldMemOperand(receiver, JSArray::kElementsOffset));
|
| __ CompareObjectType(scratch, scratch, scratch, FIXED_ARRAY_TYPE);
|
| __ b(ne, &miss);
|
|
|