Chromium Code Reviews| Index: src/ia32/ic-ia32.cc |
| diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc |
| index 65ecaeced037e1e2e069d6e6be92a0365de0866f..61db9d3fc83d1da18cf8fdc398a4b40c7e8d6a01 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_extra_double, array, extra; |
|
Rico
2011/09/27 12:57:53
check_extra_double -> check_is_fast_double_array?
danno
2011/09/27 16:14:57
Done.
|
| // Check that the object isn't a smi. |
| __ JumpIfSmi(edx, &slow); |
| @@ -761,11 +763,10 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, |
| // eax: value |
| // edx: JSObject |
| // ecx: key (a smi) |
| - __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); |
| + __ 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 +779,24 @@ 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 |
| // 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. |
|
Rico
2011/09/27 12:57:53
Update comment
danno
2011/09/27 16:14:57
Done.
|
| + __ CheckMap(ebx, FACTORY->fixed_array_map(), |
| + &check_extra_double, DONT_DO_SMI_CHECK); |
| __ add(FieldOperand(edx, JSArray::kLengthOffset), |
| Immediate(Smi::FromInt(1))); |
| - __ jmp(&fast); |
| + __ jmp(&fast_object_without_map_check); |
| + |
| + __ bind(&check_extra_double); |
| + __ CheckMap(ebx, FACTORY->fixed_double_array_map(), &slow, DONT_DO_SMI_CHECK); |
| + __ 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 |
|
Rico
2011/09/27 12:57:53
This comment seems outdated now, please update to
danno
2011/09/27 16:14:57
Done.
|
| // array. Check that the array is in fast mode (and writable); if it |
| @@ -796,8 +805,7 @@ 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); |
| + __ 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. |
| @@ -805,30 +813,49 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, |
| __ j(above_equal, &extra); |
| // Fast case: Do the store. |
|
Rico
2011/09/27 12:57:53
This comment is also slightly misleading now, sinc
danno
2011/09/27 16:14:57
Done.
|
| - __ bind(&fast); |
| + __ bind(&fast_object_with_map_check); |
| // eax: value |
| // ecx: key (a smi) |
| // edx: receiver |
| - // edi: FixedArray receiver->elements |
| - |
| + // ebx: FixedArray receiver->elements |
| + __ 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); |
|
Rico
2011/09/27 12:57:53
Could we add something like the following to (all)
danno
2011/09/27 16:14:57
Done.
|
| } |
| + |
| // 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); |
| } |