| Index: src/x64/lithium-codegen-x64.cc
|
| diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
|
| index 02c36a3b135d1ef02234bbf5df44c90f365eb6e4..374c8b624ef11b1e7462661c77f638faaf39f187 100644
|
| --- a/src/x64/lithium-codegen-x64.cc
|
| +++ b/src/x64/lithium-codegen-x64.cc
|
| @@ -3836,16 +3836,32 @@ 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(rax, instr->hydrogen()->boilerplate_object());
|
| + __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
|
| + // Load the map's "bit field 2".
|
| + __ movb(rbx, FieldOperand(rbx, Map::kBitField2Offset));
|
| + // Retrieve elements_kind from bit field 2.
|
| + __ and_(rbx, Immediate(Map::kElementsKindMask));
|
| + __ cmpb(rbx, Immediate(boilerplate_elements_kind <<
|
| + Map::kElementsKindShift));
|
| + DeoptimizeIf(not_equal, instr->environment());
|
| + }
|
|
|
| // Setup the parameters to the stub/runtime call.
|
| __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
|
| __ push(FieldOperand(rax, JSFunction::kLiteralsOffset));
|
| __ Push(Smi::FromInt(instr->hydrogen()->literal_index()));
|
| - __ Push(instr->hydrogen()->constant_elements());
|
| + // Boilerplate already exists, constant elements are never accessed.
|
| + // Pass an empty fixed array.
|
| + __ Push(Handle<FixedArray>(heap->empty_fixed_array()));
|
|
|
| // Pick the right runtime function or stub to call.
|
| int length = instr->hydrogen()->length();
|
| @@ -3861,9 +3877,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);
|
| }
|
|
|