| Index: src/x64/lithium-codegen-x64.cc
|
| diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
|
| index 31b2f217c6941e3c14b59682319283d814d41321..d35219c2dcb8cac1ad1fee2eef3cb38a04031bb8 100644
|
| --- a/src/x64/lithium-codegen-x64.cc
|
| +++ b/src/x64/lithium-codegen-x64.cc
|
| @@ -4241,7 +4241,7 @@ void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
|
|
|
|
|
| void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
|
| - Register elements = ToRegister(instr->elements());
|
| + HStoreKeyed* hinstr = instr->hydrogen();
|
| LOperand* key = instr->key();
|
| if (!key->IsConstantOperand()) {
|
| Register key_reg = ToRegister(key);
|
| @@ -4250,38 +4250,56 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
|
| // input gets replaced during bound check elimination with the index
|
| // argument to the bounds check, which can be tagged, so that case
|
| // must be handled here, too.
|
| - if (instr->hydrogen()->IsDehoisted()) {
|
| + if (hinstr->IsDehoisted()) {
|
| // Sign extend key because it could be a 32 bit negative value
|
| // and the dehoisted address computation happens in 64 bits
|
| __ movsxlq(key_reg, key_reg);
|
| }
|
| }
|
|
|
| + int offset = FixedArray::kHeaderSize - kHeapObjectTag;
|
| + Representation representation = hinstr->value()->representation();
|
| +
|
| + if (representation.IsInteger32()) {
|
| + ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY);
|
| + ASSERT(hinstr->elements_kind() == FAST_SMI_ELEMENTS);
|
| + // Store int value directly to upper half of the smi.
|
| + STATIC_ASSERT(kSmiTag == 0);
|
| + STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
|
| + offset += kPointerSize / 2;
|
| + }
|
| +
|
| Operand operand =
|
| BuildFastArrayOperand(instr->elements(),
|
| key,
|
| FAST_ELEMENTS,
|
| - FixedArray::kHeaderSize - kHeapObjectTag,
|
| + offset,
|
| instr->additional_index());
|
| +
|
| if (instr->value()->IsRegister()) {
|
| - __ movq(operand, ToRegister(instr->value()));
|
| + __ Store(operand, ToRegister(instr->value()), representation);
|
| } else {
|
| LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
|
| if (IsInteger32Constant(operand_value)) {
|
| - Smi* smi_value = Smi::FromInt(ToInteger32(operand_value));
|
| - __ Move(operand, smi_value);
|
| + int32_t value = ToInteger32(operand_value);
|
| + if (representation.IsSmi()) {
|
| + __ Move(operand, Smi::FromInt(value));
|
| +
|
| + } else {
|
| + __ movl(operand, Immediate(value));
|
| + }
|
| } else {
|
| Handle<Object> handle_value = ToHandle(operand_value);
|
| __ Move(operand, handle_value);
|
| }
|
| }
|
|
|
| - if (instr->hydrogen()->NeedsWriteBarrier()) {
|
| + if (hinstr->NeedsWriteBarrier()) {
|
| + Register elements = ToRegister(instr->elements());
|
| ASSERT(instr->value()->IsRegister());
|
| Register value = ToRegister(instr->value());
|
| - ASSERT(!instr->key()->IsConstantOperand());
|
| - SmiCheck check_needed =
|
| - instr->hydrogen()->value()->IsHeapObject()
|
| + ASSERT(!key->IsConstantOperand());
|
| + SmiCheck check_needed = hinstr->value()->IsHeapObject()
|
| ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
|
| // Compute address of modified element and store it into key register.
|
| Register key_reg(ToRegister(key));
|
|
|