| Index: src/x64/ic-x64.cc
|
| diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
|
| index 1fdffa2651d2c0003c70702e67434091f76711f1..9d92c8eff5390f81f0c186aa4f2854db5d4a2bb5 100644
|
| --- a/src/x64/ic-x64.cc
|
| +++ b/src/x64/ic-x64.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:
|
| @@ -635,6 +635,8 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
|
| Label slow, slow_with_tagged_index, fast, array, extra, check_extra_double;
|
| 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;
|
|
|
| // Check that the object isn't a smi.
|
| __ JumpIfSmi(rdx, &slow_with_tagged_index);
|
| @@ -737,7 +739,8 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
|
| __ bind(&non_smi_value);
|
| // Writing a non-smi, check whether array allows non-smi elements.
|
| // r9: receiver's map
|
| - __ CheckFastObjectElements(r9, &slow, Label::kNear);
|
| + __ CheckFastObjectElements(r9, &transition_smi_elements);
|
| + __ bind(&finish_object_store);
|
| __ movq(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize),
|
| rax);
|
| __ movq(rdx, rax); // Preserve the value which is returned.
|
| @@ -754,8 +757,52 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
|
| __ bind(&fast_double_without_map_check);
|
| // If the value is a number, store it as a double in the FastDoubleElements
|
| // array.
|
| - __ StoreNumberToDoubleElements(rax, rbx, rcx, xmm0, &slow);
|
| + __ StoreNumberToDoubleElements(rax, rbx, rcx, xmm0,
|
| + &transition_double_elements);
|
| __ ret(0);
|
| +
|
| + __ bind(&transition_smi_elements);
|
| + __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
|
| +
|
| + // Transition the array appropriately depending on the value type.
|
| + __ CompareRoot(r9, Heap::kHeapNumberMapRootIndex);
|
| + __ j(not_equal, &non_double_value);
|
| +
|
| + // Value is a double. Transition FAST_SMI_ONLY_ELEMENTS ->
|
| + // FAST_DOUBLE_ELEMENTS and complete the store.
|
| + __ LoadTransitionedArrayMapConditional(FAST_SMI_ONLY_ELEMENTS,
|
| + FAST_DOUBLE_ELEMENTS,
|
| + rbx,
|
| + rdi,
|
| + &slow);
|
| + ElementsTransitionGenerator::GenerateSmiOnlyToDouble(masm, &slow);
|
| + __ movq(rbx, FieldOperand(rdx, 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,
|
| + rbx,
|
| + rdi,
|
| + &slow);
|
| + ElementsTransitionGenerator::GenerateSmiOnlyToObject(masm);
|
| + __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
|
| + __ jmp(&finish_object_store);
|
| +
|
| + __ bind(&transition_double_elements);
|
| + // Elements are FAST_DOUBLE_WITHOUT_MAP_CHECK, 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
|
| + __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
|
| + __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS,
|
| + FAST_ELEMENTS,
|
| + rbx,
|
| + rdi,
|
| + &slow);
|
| + ElementsTransitionGenerator::GenerateDoubleToObject(masm, &slow);
|
| + __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
|
| + __ jmp(&finish_object_store);
|
| }
|
|
|
|
|
|
|