| Index: src/ia32/ic-ia32.cc
|
| diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
|
| index 65ecaeced037e1e2e069d6e6be92a0365de0866f..3c95356642b42a2d90c6a1ec1e9679e870bb1580 100644
|
| --- a/src/ia32/ic-ia32.cc
|
| +++ b/src/ia32/ic-ia32.cc
|
| @@ -734,7 +734,9 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
|
| // -- edx : receiver
|
| // -- esp[0] : return address
|
| // -----------------------------------
|
| - Label slow, fast, array, extra;
|
| + Label slow, fast_object_with_map_check, fast_object_without_map_check;
|
| + Label fast_double_with_map_check, fast_double_without_map_check;
|
| + Label check_if_double_array, array, extra;
|
|
|
| // Check that the object isn't a smi.
|
| __ JumpIfSmi(edx, &slow);
|
| @@ -761,11 +763,11 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
|
| // eax: value
|
| // edx: JSObject
|
| // ecx: key (a smi)
|
| - __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
|
| + // edi: receiver map
|
| + __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
|
| // Check that the object is in fast mode and writable.
|
| - __ CheckMap(edi, FACTORY->fixed_array_map(), &slow, DONT_DO_SMI_CHECK);
|
| - __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset));
|
| - __ j(below, &fast);
|
| + __ cmp(ecx, FieldOperand(ebx, FixedArray::kLengthOffset));
|
| + __ j(below, &fast_object_with_map_check);
|
|
|
| // Slow case: call runtime.
|
| __ bind(&slow);
|
| @@ -778,16 +780,26 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
|
| // eax: value
|
| // edx: receiver, a JSArray
|
| // ecx: key, a smi.
|
| - // edi: receiver->elements, a FixedArray
|
| + // ebx: receiver->elements, a FixedArray
|
| + // edi: receiver map
|
| // flags: compare (ecx, edx.length())
|
| // do not leave holes in the array:
|
| __ j(not_equal, &slow);
|
| - __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset));
|
| + __ cmp(ecx, FieldOperand(ebx, FixedArray::kLengthOffset));
|
| __ j(above_equal, &slow);
|
| - // Add 1 to receiver->length, and go to fast array write.
|
| + __ CheckMap(ebx, FACTORY->fixed_array_map(),
|
| + &check_if_double_array, DONT_DO_SMI_CHECK);
|
| + // Add 1 to receiver->length, and go to common element store code for Objects.
|
| __ add(FieldOperand(edx, JSArray::kLengthOffset),
|
| Immediate(Smi::FromInt(1)));
|
| - __ jmp(&fast);
|
| + __ jmp(&fast_object_without_map_check);
|
| +
|
| + __ bind(&check_if_double_array);
|
| + __ CheckMap(ebx, FACTORY->fixed_double_array_map(), &slow, DONT_DO_SMI_CHECK);
|
| + // Add 1 to receiver->length, and go to common element store code for doubles.
|
| + __ add(FieldOperand(edx, JSArray::kLengthOffset),
|
| + Immediate(Smi::FromInt(1)));
|
| + __ jmp(&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
|
| @@ -796,39 +808,59 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
|
| // eax: value
|
| // edx: receiver, a JSArray
|
| // ecx: key, a smi.
|
| - __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
|
| - __ CheckMap(edi, FACTORY->fixed_array_map(), &slow, DONT_DO_SMI_CHECK);
|
| + // edi: receiver map
|
| + __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
|
|
|
| - // Check the key against the length in the array, compute the
|
| - // address to store into and fall through to fast case.
|
| + // Check the key against the length in the array and fall through to the
|
| + // common store code.
|
| __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis.
|
| __ j(above_equal, &extra);
|
|
|
| - // Fast case: Do the store.
|
| - __ bind(&fast);
|
| + // Fast case: Do the store, could either Object or double.
|
| + __ bind(&fast_object_with_map_check);
|
| // eax: value
|
| // ecx: key (a smi)
|
| // edx: receiver
|
| - // edi: FixedArray receiver->elements
|
| -
|
| + // ebx: FixedArray receiver->elements
|
| + // edi: receiver map
|
| + __ CheckMap(ebx, FACTORY->fixed_array_map(),
|
| + &fast_double_with_map_check, DONT_DO_SMI_CHECK);
|
| + __ bind(&fast_object_without_map_check);
|
| + // Smi stores don't require further checks.
|
| Label non_smi_value;
|
| __ JumpIfNotSmi(eax, &non_smi_value);
|
| // It's irrelevant whether array is smi-only or not when writing a smi.
|
| - __ mov(CodeGenerator::FixedArrayElementOperand(edi, ecx), eax);
|
| + __ mov(CodeGenerator::FixedArrayElementOperand(ebx, ecx), eax);
|
| __ ret(0);
|
|
|
| __ bind(&non_smi_value);
|
| if (FLAG_smi_only_arrays) {
|
| // Escape to slow case when writing non-smi into smi-only array.
|
| - __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
|
| - __ CheckFastObjectElements(ebx, &slow, Label::kNear);
|
| + __ CheckFastObjectElements(edi, &slow, Label::kNear);
|
| }
|
| +
|
| // Fast elements array, store the value to the elements backing store.
|
| - __ mov(CodeGenerator::FixedArrayElementOperand(edi, ecx), eax);
|
| + __ mov(CodeGenerator::FixedArrayElementOperand(ebx, ecx), eax);
|
| // Update write barrier for the elements array address.
|
| __ mov(edx, Operand(eax)); // Preserve the value which is returned.
|
| __ RecordWriteArray(
|
| - edi, edx, ecx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
|
| + ebx, edx, ecx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
|
| + __ ret(0);
|
| +
|
| + __ bind(&fast_double_with_map_check);
|
| + // Check for fast double array case. If this fails, call through to the
|
| + // runtime.
|
| + __ CheckMap(ebx, FACTORY->fixed_double_array_map(), &slow, DONT_DO_SMI_CHECK);
|
| + __ bind(&fast_double_without_map_check);
|
| + // If the value is a number, store it as a double in the FastDoubleElements
|
| + // array.
|
| + __ StoreNumberToDoubleElements(eax,
|
| + ebx,
|
| + ecx,
|
| + edx,
|
| + xmm0,
|
| + &slow,
|
| + false);
|
| __ ret(0);
|
| }
|
|
|
|
|