| Index: src/arm/lithium-codegen-arm.cc
|
| diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
|
| index 06b021669bd1792e150796f844f135935179dbdc..909d772706d4752a51230e52fc84f65b4c55584f 100644
|
| --- a/src/arm/lithium-codegen-arm.cc
|
| +++ b/src/arm/lithium-codegen-arm.cc
|
| @@ -5296,26 +5296,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(r1, instr->hydrogen()->boilerplate());
|
| - // Load map into r2.
|
| - __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
|
| - // Load the map's "bit field 2".
|
| - __ ldrb(r2, FieldMemOperand(r2, Map::kBitField2Offset));
|
| - // Retrieve elements_kind from bit field 2.
|
| - __ ubfx(r2, r2, Map::kElementsKindShift, Map::kElementsKindBitCount);
|
| - __ cmp(r2, Operand(boilerplate_elements_kind));
|
| - DeoptimizeIf(ne, 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(r1, result);
|
| + // Load map into r2.
|
| + __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset));
|
| + // Load the map's "bit field 2".
|
| + __ ldrb(r2, FieldMemOperand(r2, Map::kBitField2Offset));
|
| + // Retrieve elements_kind from bit field 2.
|
| + __ ubfx(r2, r2, Map::kElementsKindShift, Map::kElementsKindBitCount);
|
| + __ cmp(r2, Operand(boilerplate_elements_kind));
|
| + DeoptimizeIf(ne, 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;
|
| @@ -5329,8 +5346,8 @@ void LCodeGen::DoFastLiteral(LFastLiteral* instr) {
|
|
|
| __ bind(&allocated);
|
| int offset = 0;
|
| - __ LoadHeapObject(r1, instr->hydrogen()->boilerplate());
|
| - EmitDeepCopy(instr->hydrogen()->boilerplate(), r0, r1, &offset);
|
| + __ LoadHeapObject(r1, result);
|
| + EmitDeepCopy(result, r0, r1, &offset);
|
| ASSERT_EQ(size, offset);
|
| }
|
|
|
|
|