Chromium Code Reviews| Index: src/ia32/ic-ia32.cc |
| diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc |
| index f8e4ea53d0f78cb32f63e86b30343f85c857f42c..97445d01f27424839b8c8ef669cee5a15c891c7f 100644 |
| --- a/src/ia32/ic-ia32.cc |
| +++ b/src/ia32/ic-ia32.cc |
| @@ -711,6 +711,34 @@ void KeyedStoreIC::GenerateNonStrictArguments(MacroAssembler* masm) { |
| } |
| +static void HasElementCallbacksInPrototypeChain( |
|
danno
2013/10/23 12:22:11
This (and similar code in other implementations) b
mvstanton
2013/10/30 10:42:42
Done.
|
| + MacroAssembler* masm, |
| + Label* found) { |
| + Factory* factory = masm->isolate()->factory(); |
| + Label loop, not_found; |
| + |
| + // ebx contained elements pointer. |
| + __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); |
| + |
| + // Loop based on the map going up the prototype chain. |
| + __ bind(&loop); |
| + __ test(FieldOperand(ebx, Map::kBitField4Offset), |
| + Immediate(Smi::FromInt(Map::HasElementCallbacks::kMask))); |
| + __ j(not_zero, found); |
| + |
| + // Next map |
| + __ mov(ebx, FieldOperand(ebx, Map::kPrototypeOffset)); |
| + __ cmp(ebx, Immediate(factory->null_value())); |
| + __ j(equal, ¬_found); |
| + __ mov(ebx, FieldOperand(ebx, HeapObject::kMapOffset)); |
| + __ jmp(&loop); |
| + |
| + // Restore ebx |
| + __ bind(¬_found); |
| + __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); |
| +} |
| + |
| + |
| static void KeyedStoreGenerateGenericHelper( |
|
danno
2013/10/23 12:22:11
I wish *so* badly that we generaed this in Hydroge
mvstanton
2013/10/30 10:42:42
I've added this to the TODO list.
|
| MacroAssembler* masm, |
| Label* fast_object, |
| @@ -733,9 +761,22 @@ static void KeyedStoreGenerateGenericHelper( |
| __ cmp(edi, masm->isolate()->factory()->fixed_array_map()); |
| __ j(not_equal, fast_double); |
| } |
| + |
| + // HOLECHECK: guards "A[i] = V" |
| + // We have to go to the runtime if the current value is undefined because |
| + // there may be a callback on the element |
| + Label holecheck_passed1; |
| + __ cmp(CodeGenerator::FixedArrayElementOperand(ebx, ecx), |
| + masm->isolate()->factory()->the_hole_value()); |
| + __ j(not_equal, &holecheck_passed1); |
| + HasElementCallbacksInPrototypeChain(masm, slow); |
| + |
| + __ bind(&holecheck_passed1); |
| + |
| // Smi stores don't require further checks. |
| Label non_smi_value; |
| __ JumpIfNotSmi(eax, &non_smi_value); |
| + |
|
danno
2013/10/23 12:22:11
nit: please remove the extraneous whitespace chang
mvstanton
2013/10/30 10:42:42
Done.
|
| if (increment_length == kIncrementLength) { |
| // Add 1 to receiver->length. |
| __ add(FieldOperand(edx, JSArray::kLengthOffset), |
| @@ -773,6 +814,15 @@ static void KeyedStoreGenerateGenericHelper( |
| // If the value is a number, store it as a double in the FastDoubleElements |
| // array. |
| } |
| + |
| + // HOLECHECK: guards "A[i] double hole?" |
| + // We have to see if the double version of the hole is present. If so |
| + // go to the runtime. |
| + uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32); |
| + __ cmp(FieldOperand(ebx, ecx, times_4, offset), Immediate(kHoleNanUpper32)); |
| + __ j(not_equal, &fast_double_without_map_check); |
| + HasElementCallbacksInPrototypeChain(masm, slow); |
| + |
| __ bind(&fast_double_without_map_check); |
| __ StoreNumberToDoubleElements(eax, ebx, ecx, edi, xmm0, |
| &transition_double_elements, false); |
| @@ -794,6 +844,7 @@ static void KeyedStoreGenerateGenericHelper( |
| // Value is a double. Transition FAST_SMI_ELEMENTS -> FAST_DOUBLE_ELEMENTS |
| // and complete the store. |
| + |
|
danno
2013/10/23 12:22:11
nit: please remove the extraneous whitespace chang
mvstanton
2013/10/30 10:42:42
Done.
|
| __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, |
| FAST_DOUBLE_ELEMENTS, |
| ebx, |
| @@ -806,6 +857,7 @@ static void KeyedStoreGenerateGenericHelper( |
| __ jmp(&fast_double_without_map_check); |
| __ bind(&non_double_value); |
| + |
|
danno
2013/10/23 12:22:11
nit: please remove the extraneous whitespace chang
mvstanton
2013/10/30 10:42:42
Done.
|
| // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS |
| __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, |
| FAST_ELEMENTS, |