diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index ce51ec7b32..18beee6e03 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -4253,15 +4253,15 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { if (instr->value()->IsConstantOperand()) { LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); if (IsInteger32(operand_value)) { - int const_value = ToInteger32(operand_value); - __ mov(FieldOperand(write_register, offset), Immediate(const_value)); + // In lithium register preparation, we made sure that the constant integer + // operand fits into smi range. + Smi* smi_value = Smi::FromInt(ToInteger32(operand_value)); + __ mov(FieldOperand(write_register, offset), Immediate(smi_value)); + } else if (operand_value->IsRegister()) { + __ mov(FieldOperand(write_register, offset), ToRegister(operand_value)); } else { - if (operand_value->IsRegister()) { - __ mov(FieldOperand(write_register, offset), ToRegister(operand_value)); - } else { - Handle handle_value = ToHandle(operand_value); - __ mov(FieldOperand(write_register, offset), handle_value); - } + Handle handle_value = ToHandle(operand_value); + __ mov(FieldOperand(write_register, offset), handle_value); } } else { __ mov(FieldOperand(write_register, offset), ToRegister(instr->value())); diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index 08ab6981c6..494daa617b 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -2287,6 +2287,19 @@ LOperand* LChunkBuilder::GetStoreKeyedValueOperand(HStoreKeyed* instr) { } +// DoStoreKeyed and DoStoreNamedField have special considerations for allowing +// use of a constant instead of a register. +static bool StoreConstantValueAllowed(HValue* value) { + if (value->IsConstant()) { + HConstant* constant_value = HConstant::cast(value); + return constant_value->HasSmiValue() + || constant_value->HasDoubleValue() + || constant_value->ImmortalImmovable(); + } + return false; +} + + LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { if (!instr->is_external()) { ASSERT(instr->elements()->representation().IsTagged()); @@ -2314,8 +2327,17 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { val = UseTempRegister(instr->value()); key = UseTempRegister(instr->key()); } else { - val = UseRegisterOrConstantAtStart(instr->value()); - key = UseRegisterOrConstantAtStart(instr->key()); + if (StoreConstantValueAllowed(instr->value())) { + val = UseRegisterOrConstantAtStart(instr->value()); + } else { + val = UseRegisterAtStart(instr->value()); + } + + if (StoreConstantValueAllowed(instr->key())) { + key = UseRegisterOrConstantAtStart(instr->key()); + } else { + key = UseRegisterAtStart(instr->key()); + } } return new(zone()) LStoreKeyed(obj, key, val); } @@ -2416,18 +2438,10 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { : UseRegisterAtStart(instr->object()); } - bool register_or_constant = false; - if (instr->value()->IsConstant()) { - HConstant* constant_value = HConstant::cast(instr->value()); - register_or_constant = constant_value->HasInteger32Value() - || constant_value->HasDoubleValue() - || constant_value->ImmortalImmovable(); - } - LOperand* val; if (needs_write_barrier) { val = UseTempRegister(instr->value()); - } else if (register_or_constant) { + } else if (StoreConstantValueAllowed(instr->value())) { val = UseRegisterOrConstant(instr->value()); } else { val = UseRegister(instr->value()); diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 054dd606a2..ae80b841ea 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -3954,16 +3954,16 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { if (instr->value()->IsConstantOperand()) { LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); if (IsInteger32Constant(operand_value)) { - int const_value = ToInteger32(operand_value); - __ movq(FieldOperand(write_register, offset), Immediate(const_value)); + // In lithium register preparation, we made sure that the constant integer + // operand fits into smi range. + Smi* smi_value = Smi::FromInt(ToInteger32(operand_value)); + __ Move(FieldOperand(write_register, offset), smi_value); + } else if (operand_value->IsRegister()) { + __ movq(FieldOperand(write_register, offset), + ToRegister(operand_value)); } else { - if (operand_value->IsRegister()) { - __ movq(FieldOperand(write_register, offset), - ToRegister(operand_value)); - } else { - Handle handle_value = ToHandle(operand_value); - __ Move(FieldOperand(write_register, offset), handle_value); - } + Handle handle_value = ToHandle(operand_value); + __ Move(FieldOperand(write_register, offset), handle_value); } } else { __ movq(FieldOperand(write_register, offset), ToRegister(instr->value())); diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index f564e1cbab..bb25450483 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -2124,6 +2124,19 @@ LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { } +// DoStoreKeyed and DoStoreNamedField have special considerations for allowing +// use of a constant instead of a register. +static bool StoreConstantValueAllowed(HValue* value) { + if (value->IsConstant()) { + HConstant* constant_value = HConstant::cast(value); + return constant_value->HasSmiValue() + || constant_value->HasDoubleValue() + || constant_value->ImmortalImmovable(); + } + return false; +} + + LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { ElementsKind elements_kind = instr->elements_kind(); bool clobbers_key = instr->key()->representation().IsTagged(); @@ -2143,11 +2156,24 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { } else { ASSERT(instr->value()->representation().IsTagged()); object = UseTempRegister(instr->elements()); - val = needs_write_barrier ? UseTempRegister(instr->value()) - : UseRegisterOrConstantAtStart(instr->value()); - key = (clobbers_key || needs_write_barrier) - ? UseTempRegister(instr->key()) - : UseRegisterOrConstantAtStart(instr->key()); + if (needs_write_barrier) { + val = UseTempRegister(instr->value()); + key = UseTempRegister(instr->key()); + } else { + if (StoreConstantValueAllowed(instr->value())) { + val = UseRegisterOrConstantAtStart(instr->value()); + } else { + val = UseRegisterAtStart(instr->value()); + } + + if (clobbers_key) { + key = UseTempRegister(instr->key()); + } else if (StoreConstantValueAllowed(instr->key())) { + key = UseRegisterOrConstantAtStart(instr->key()); + } else { + key = UseRegisterAtStart(instr->key()); + } + } } return new(zone()) LStoreKeyed(object, key, val); @@ -2241,18 +2267,10 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { : UseRegisterAtStart(instr->object()); } - bool register_or_constant = false; - if (instr->value()->IsConstant()) { - HConstant* constant_value = HConstant::cast(instr->value()); - register_or_constant = constant_value->HasInteger32Value() - || constant_value->HasDoubleValue() - || constant_value->ImmortalImmovable(); - } - LOperand* val; if (needs_write_barrier) { val = UseTempRegister(instr->value()); - } else if (register_or_constant) { + } else if (StoreConstantValueAllowed(instr->value())) { val = UseRegisterOrConstant(instr->value()); } else { val = UseRegister(instr->value());