| Index: src/x64/lithium-codegen-x64.cc
|
| diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
|
| index c69b27c445568e21b07d7ee2d638d8cce38702a0..1ffea9851ee31dc4c3367531dcd6a40e31da9b97 100644
|
| --- a/src/x64/lithium-codegen-x64.cc
|
| +++ b/src/x64/lithium-codegen-x64.cc
|
| @@ -4921,26 +4921,43 @@ void LCodeGen::EmitDeepCopy(Handle<JSObject> object,
|
|
|
|
|
| void LCodeGen::DoFastLiteral(LFastLiteral* instr) {
|
| - int size = instr->hydrogen()->total_size();
|
| - ElementsKind boilerplate_elements_kind =
|
| - instr->hydrogen()->boilerplate()->GetElementsKind();
|
| -
|
| - // Deopt if the array literal boilerplate ElementsKind is of a type different
|
| - // than the expected one. The check isn't necessary if the boilerplate has
|
| - // already been converted to TERMINAL_FAST_ELEMENTS_KIND.
|
| - if (CanTransitionToMoreGeneralFastElementsKind(
|
| - boilerplate_elements_kind, true)) {
|
| - __ LoadHeapObject(rbx, instr->hydrogen()->boilerplate());
|
| - __ movq(rcx, FieldOperand(rbx, HeapObject::kMapOffset));
|
| - // Load the map's "bit field 2".
|
| - __ movb(rcx, FieldOperand(rcx, Map::kBitField2Offset));
|
| - // Retrieve elements_kind from bit field 2.
|
| - __ and_(rcx, Immediate(Map::kElementsKindMask));
|
| - __ cmpb(rcx, Immediate(boilerplate_elements_kind <<
|
| - Map::kElementsKindShift));
|
| - DeoptimizeIf(not_equal, instr->environment());
|
| + Handle<JSObject> result = instr->hydrogen()->boilerplate();
|
| +
|
| + if (instr->hydrogen()->TransitionRequested()) {
|
| + ElementsKind to_kind = instr->hydrogen()->TransitionTo();
|
| + result = Runtime::DeepCopyBoilerplate(isolate(),
|
| + instr->hydrogen()->boilerplate());
|
| + CHECK(!result.is_null());
|
| + // Now transition the copy
|
| + CHECK(!JSObject::TransitionElementsKind(result, to_kind).is_null());
|
| + } else {
|
| + ElementsKind boilerplate_elements_kind = result->GetElementsKind();
|
| +
|
| + // Deopt if the array literal boilerplate ElementsKind is of a type
|
| + // different than the expected one. The check isn't necessary if the
|
| + // boilerplate has already been converted to TERMINAL_FAST_ELEMENTS_KIND.
|
| + if (CanTransitionToMoreGeneralFastElementsKind(
|
| + boilerplate_elements_kind, true)) {
|
| + __ LoadHeapObject(rbx, result);
|
| + __ movq(rcx, FieldOperand(rbx, HeapObject::kMapOffset));
|
| + // Load the map's "bit field 2".
|
| + __ movb(rcx, FieldOperand(rcx, Map::kBitField2Offset));
|
| + // Retrieve elements_kind from bit field 2.
|
| + __ and_(rcx, Immediate(Map::kElementsKindMask));
|
| + __ cmpb(rcx, Immediate(boilerplate_elements_kind <<
|
| + Map::kElementsKindShift));
|
| + DeoptimizeIf(not_equal, instr->environment());
|
| + }
|
| }
|
|
|
| + // We need to compute the size now.
|
| + int size = 0;
|
| + int max_properties = HFastLiteral::kMaxLiteralProperties;
|
| + HFastLiteral::IsFastLiteral(result,
|
| + HFastLiteral::kMaxLiteralDepth,
|
| + &max_properties,
|
| + &size);
|
| +
|
| // Allocate all objects that are part of the literal in one big
|
| // allocation. This avoids multiple limit checks.
|
| Label allocated, runtime_allocate;
|
| @@ -4953,8 +4970,8 @@ void LCodeGen::DoFastLiteral(LFastLiteral* instr) {
|
|
|
| __ bind(&allocated);
|
| int offset = 0;
|
| - __ LoadHeapObject(rbx, instr->hydrogen()->boilerplate());
|
| - EmitDeepCopy(instr->hydrogen()->boilerplate(), rax, rbx, &offset);
|
| + __ LoadHeapObject(rbx, result);
|
| + EmitDeepCopy(result, rax, rbx, &offset);
|
| ASSERT_EQ(size, offset);
|
| }
|
|
|
|
|