Chromium Code Reviews| Index: src/arm/ic-arm.cc |
| diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc |
| index 68a20cc0a6947bfdaff99613afc9b47477d462bd..ed358af0a16b04541bc68adf815235fd8df577fe 100644 |
| --- a/src/arm/ic-arm.cc |
| +++ b/src/arm/ic-arm.cc |
| @@ -1272,13 +1272,17 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, |
| // -- r2 : receiver |
| // -- lr : return address |
| // ----------------------------------- |
| - Label slow, fast, array, extra; |
| + Label slow, array, extra, check_if_double_array; |
| + Label fast_object_with_map_check, fast_object_without_map_check; |
| + Label fast_double_with_map_check, fast_double_without_map_check; |
| // Register usage. |
| Register value = r0; |
| Register key = r1; |
| Register receiver = r2; |
| Register elements = r3; // Elements array of the receiver. |
| + Register elements_map = r6; |
| + Register receiver_map = r7; |
| // r4 and r5 are used as general scratch registers. |
| // Check that the key is a smi. |
| @@ -1286,14 +1290,14 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, |
| // Check that the object isn't a smi. |
| __ JumpIfSmi(receiver, &slow); |
| // Get the map of the object. |
| - __ ldr(r4, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
| + __ ldr(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
| // Check that the receiver does not require access checks. We need |
| // to do this because this generic stub does not perform map checks. |
| - __ ldrb(ip, FieldMemOperand(r4, Map::kBitFieldOffset)); |
| + __ ldrb(ip, FieldMemOperand(receiver_map, Map::kBitFieldOffset)); |
| __ tst(ip, Operand(1 << Map::kIsAccessCheckNeeded)); |
| __ b(ne, &slow); |
| // Check if the object is a JS array or not. |
| - __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset)); |
| + __ ldrb(r4, FieldMemOperand(receiver_map, Map::kInstanceTypeOffset)); |
| __ cmp(r4, Operand(JS_ARRAY_TYPE)); |
| __ b(eq, &array); |
| // Check that the object is some kind of JSObject. |
| @@ -1306,15 +1310,10 @@ 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 and writable. |
| - __ ldr(r4, FieldMemOperand(elements, HeapObject::kMapOffset)); |
| - __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); |
| - __ cmp(r4, ip); |
| - __ b(ne, &slow); |
| // Check array bounds. Both the key and the length of FixedArray are smis. |
| __ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset)); |
| __ cmp(key, Operand(ip)); |
| - __ b(lo, &fast); |
| + __ b(lo, &fast_object_with_map_check); |
| // Slow case, handle jump to runtime. |
| __ bind(&slow); |
| @@ -1335,21 +1334,31 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, |
| __ ldr(ip, FieldMemOperand(elements, FixedArray::kLengthOffset)); |
| __ cmp(key, Operand(ip)); |
| __ b(hs, &slow); |
| + __ ldr(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset)); |
| + __ cmp(elements_map, |
| + Operand(masm->isolate()->factory()->fixed_array_map())); |
| + __ b(ne, &check_if_double_array); |
| // Calculate key + 1 as smi. |
| STATIC_ASSERT(kSmiTag == 0); |
| __ add(r4, key, Operand(Smi::FromInt(1))); |
| __ str(r4, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
| - __ b(&fast); |
| + __ b(&fast_object_without_map_check); |
| + |
| + __ bind(&check_if_double_array); |
| + __ cmp(elements_map, |
| + Operand(masm->isolate()->factory()->fixed_double_array_map())); |
| + __ b(ne, &slow); |
| + // Add 1 to key, and go to common element store code for doubles. |
| + STATIC_ASSERT(kSmiTag == 0); |
| + __ add(r4, key, Operand(Smi::FromInt(1))); |
| + __ str(r4, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
| + __ bind(&fast_double_without_map_check); |
| // Array case: Get the length and the elements array from the JS |
| // 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)); |
| - __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); |
| - __ cmp(r4, ip); |
| - __ b(ne, &slow); |
| // Check the key against the length in the array. |
| __ ldr(ip, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
| @@ -1357,10 +1366,15 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, |
| __ b(hs, &extra); |
| // Fall through to fast case. |
| - __ bind(&fast); |
| + __ bind(&fast_object_with_map_check); |
| Register scratch_value = r4; |
| Register address = r5; |
| - |
| + __ ldr(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset)); |
| + __ cmp(elements_map, |
| + Operand(masm->isolate()->factory()->fixed_array_map())); |
| + __ b(ne, &fast_double_with_map_check); |
| + __ bind(&fast_object_without_map_check); |
| + // Smi stores don't require further checks. |
| Label non_smi_value; |
| __ JumpIfNotSmi(value, &non_smi_value); |
| // It's irrelevant whether array is smi-only or not when writing a smi. |
| @@ -1372,8 +1386,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, |
| __ bind(&non_smi_value); |
| if (FLAG_smi_only_arrays) { |
| // Escape to slow case when writing non-smi into smi-only array. |
| - __ ldr(scratch_value, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
| - __ CheckFastObjectElements(scratch_value, scratch_value, &slow); |
| + __ CheckFastObjectElements(receiver_map, scratch_value, &slow); |
| } |
| // Fast elements array, store the value to the elements backing store. |
| __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
| @@ -1389,6 +1402,17 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, |
| EMIT_REMEMBERED_SET, |
| OMIT_SMI_CHECK); |
| __ Ret(); |
| + |
| + __ bind(&fast_double_with_map_check); |
| + // Check for fast double array case. If this fails, call through to the |
| + // runtime. |
| + __ cmp(elements_map, |
| + Operand(masm->isolate()->factory()->fixed_double_array_map())); |
| + __ b(ne, &slow); |
| + __ bind(&fast_double_without_map_check); |
| + __ StoreNumberToDoubleElements(value, key, receiver, elements, |
|
Rico
2011/10/05 08:39:19
all arguments on one line or each on seperate line
|
| + r4, r5, r6, r7, &slow); |
| + __ Ret(); |
| } |