| Index: src/mips/ic-mips.cc
|
| diff --git a/src/mips/ic-mips.cc b/src/mips/ic-mips.cc
|
| index 3489936657a57321589cdd72dff1fa617c7ef9e4..c3cdb4cd388310a767a7f7f9d96ad4390972c4d7 100644
|
| --- a/src/mips/ic-mips.cc
|
| +++ b/src/mips/ic-mips.cc
|
| @@ -1,4 +1,4 @@
|
| -// Copyright 2011 the V8 project authors. All rights reserved.
|
| +// Copyright 2012 the V8 project authors. All rights reserved.
|
| // Redistribution and use in source and binary forms, with or without
|
| // modification, are permitted provided that the following conditions are
|
| // met:
|
| @@ -1198,14 +1198,16 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
|
| 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;
|
| + Label transition_smi_elements, finish_object_store, non_double_value;
|
| + Label transition_double_elements;
|
|
|
| // Register usage.
|
| Register value = a0;
|
| Register key = a1;
|
| Register receiver = a2;
|
| - Register elements = a3; // Elements array of the receiver.
|
| + Register receiver_map = a3;
|
| Register elements_map = t2;
|
| - Register receiver_map = t3;
|
| + Register elements = t3; // Elements array of the receiver.
|
| // t0 and t1 are used as general scratch registers.
|
|
|
| // Check that the key is a smi.
|
| @@ -1298,9 +1300,11 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
|
| __ mov(v0, value);
|
|
|
| __ bind(&non_smi_value);
|
| - // Escape to slow case when writing non-smi into smi-only array.
|
| - __ CheckFastObjectElements(receiver_map, scratch_value, &slow);
|
| + // Escape to elements kind transition case.
|
| + __ CheckFastObjectElements(receiver_map, scratch_value,
|
| + &transition_smi_elements);
|
| // Fast elements array, store the value to the elements backing store.
|
| + __ bind(&finish_object_store);
|
| __ Addu(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
|
| __ sll(scratch_value, key, kPointerSizeLog2 - kSmiTagSize);
|
| __ Addu(address, address, scratch_value);
|
| @@ -1326,13 +1330,57 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
|
| key,
|
| receiver,
|
| elements,
|
| + a3,
|
| t0,
|
| t1,
|
| t2,
|
| - t3,
|
| - &slow);
|
| + &transition_double_elements);
|
| __ Ret(USE_DELAY_SLOT);
|
| __ mov(v0, value);
|
| +
|
| + __ bind(&transition_smi_elements);
|
| + // Transition the array appropriately depending on the value type.
|
| + __ lw(t0, FieldMemOperand(value, HeapObject::kMapOffset));
|
| + __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
|
| + __ Branch(&non_double_value, ne, t0, Operand(at));
|
| +
|
| + // Value is a double. Transition FAST_SMI_ONLY_ELEMENTS ->
|
| + // FAST_DOUBLE_ELEMENTS and complete the store.
|
| + __ LoadTransitionedArrayMapConditional(FAST_SMI_ONLY_ELEMENTS,
|
| + FAST_DOUBLE_ELEMENTS,
|
| + receiver_map,
|
| + t0,
|
| + &slow);
|
| + ASSERT(receiver_map.is(a3)); // Transition code expects map in a3
|
| + ElementsTransitionGenerator::GenerateSmiOnlyToDouble(masm, &slow);
|
| + __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
|
| + __ jmp(&fast_double_without_map_check);
|
| +
|
| + __ bind(&non_double_value);
|
| + // Value is not a double, FAST_SMI_ONLY_ELEMENTS -> FAST_ELEMENTS
|
| + __ LoadTransitionedArrayMapConditional(FAST_SMI_ONLY_ELEMENTS,
|
| + FAST_ELEMENTS,
|
| + receiver_map,
|
| + t0,
|
| + &slow);
|
| + ASSERT(receiver_map.is(a3)); // Transition code expects map in a3
|
| + ElementsTransitionGenerator::GenerateSmiOnlyToObject(masm);
|
| + __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
|
| + __ jmp(&finish_object_store);
|
| +
|
| + __ bind(&transition_double_elements);
|
| + // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
|
| + // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
|
| + // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
|
| + __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
|
| + FAST_ELEMENTS,
|
| + receiver_map,
|
| + t0,
|
| + &slow);
|
| + ASSERT(receiver_map.is(a3)); // Transition code expects map in a3
|
| + ElementsTransitionGenerator::GenerateDoubleToObject(masm, &slow);
|
| + __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
|
| + __ jmp(&finish_object_store);
|
| }
|
|
|
|
|
|
|