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(); |
} |