| Index: src/arm/lithium-codegen-arm.cc
|
| diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
|
| index 46002646fe92fef76fdead72b9d13293dae8434b..6eaa1c90d6e0ff2b2f05200cd989b6a316e7482e 100644
|
| --- a/src/arm/lithium-codegen-arm.cc
|
| +++ b/src/arm/lithium-codegen-arm.cc
|
| @@ -4231,15 +4231,31 @@ void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
|
|
|
|
|
| void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
|
| - Handle<FixedArray> constant_elements = instr->hydrogen()->constant_elements();
|
| - ASSERT_EQ(2, constant_elements->length());
|
| - ElementsKind constant_elements_kind =
|
| - static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value());
|
| + Heap* heap = isolate()->heap();
|
| + ElementsKind boilerplate_elements_kind =
|
| + instr->hydrogen()->boilerplate_elements_kind();
|
| +
|
| + // 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 FAST_ELEMENTS.
|
| + if (boilerplate_elements_kind != FAST_ELEMENTS) {
|
| + LoadHeapObject(r1, instr->hydrogen()->boilerplate_object());
|
| + // 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());
|
| + }
|
|
|
| __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
|
| __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset));
|
| __ mov(r2, Operand(Smi::FromInt(instr->hydrogen()->literal_index())));
|
| - __ mov(r1, Operand(constant_elements));
|
| + // Boilerplate already exists, constant elements are never accessed.
|
| + // Pass an empty fixed array.
|
| + __ mov(r1, Operand(Handle<FixedArray>(heap->empty_fixed_array())));
|
| __ Push(r3, r2, r1);
|
|
|
| // Pick the right runtime function or stub to call.
|
| @@ -4256,9 +4272,9 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
|
| CallRuntime(Runtime::kCreateArrayLiteralShallow, 3, instr);
|
| } else {
|
| FastCloneShallowArrayStub::Mode mode =
|
| - constant_elements_kind == FAST_DOUBLE_ELEMENTS
|
| - ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS
|
| - : FastCloneShallowArrayStub::CLONE_ELEMENTS;
|
| + boilerplate_elements_kind == FAST_DOUBLE_ELEMENTS
|
| + ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS
|
| + : FastCloneShallowArrayStub::CLONE_ELEMENTS;
|
| FastCloneShallowArrayStub stub(mode, length);
|
| CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
|
| }
|
|
|