Index: src/x64/lithium-codegen-x64.cc |
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc |
index 45aaad7549fc31dcc3283d79f287b1fbf5732631..5e87e78bd5b3b6db91b84b671262c255535a87a1 100644 |
--- a/src/x64/lithium-codegen-x64.cc |
+++ b/src/x64/lithium-codegen-x64.cc |
@@ -3223,6 +3223,47 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { |
} |
+void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { |
+ Register object_reg = ToRegister(instr->object()); |
+ Register new_map_reg = ToRegister(instr->new_map_reg()); |
+ |
+ Handle<Map> from_map = instr->original_map(); |
+ Handle<Map> to_map = instr->transitioned_map(); |
+ ElementsKind from_kind = from_map->elements_kind(); |
+ ElementsKind to_kind = to_map->elements_kind(); |
+ |
+ Label not_applicable; |
+ __ Cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map); |
+ __ j(not_equal, ¬_applicable); |
+ __ movq(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT); |
+ if (from_kind == FAST_SMI_ONLY_ELEMENTS && to_kind == FAST_ELEMENTS) { |
+ __ movq(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg); |
+ // Write barrier. |
+ ASSERT_NE(instr->temp_reg(), NULL); |
+ __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, |
+ ToRegister(instr->temp_reg()), kDontSaveFPRegs); |
+ } else if (from_kind == FAST_SMI_ONLY_ELEMENTS && |
+ to_kind == FAST_DOUBLE_ELEMENTS) { |
+ Register fixed_object_reg = ToRegister(instr->temp_reg()); |
+ ASSERT(fixed_object_reg.is(rdx)); |
+ ASSERT(new_map_reg.is(rbx)); |
+ __ movq(fixed_object_reg, object_reg); |
+ CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(), |
+ RelocInfo::CODE_TARGET, instr); |
+ } else if (from_kind == FAST_DOUBLE_ELEMENTS && to_kind == FAST_ELEMENTS) { |
+ Register fixed_object_reg = ToRegister(instr->temp_reg()); |
+ ASSERT(fixed_object_reg.is(rdx)); |
+ ASSERT(new_map_reg.is(rbx)); |
+ __ movq(fixed_object_reg, object_reg); |
+ CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(), |
+ RelocInfo::CODE_TARGET, instr); |
+ } else { |
+ UNREACHABLE(); |
+ } |
+ __ bind(¬_applicable); |
+} |
+ |
+ |
void LCodeGen::DoStringAdd(LStringAdd* instr) { |
EmitPushTaggedOperand(instr->left()); |
EmitPushTaggedOperand(instr->right()); |