Index: src/x64/lithium-codegen-x64.cc |
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc |
index c6d5a147a76ac8e484273753421cb459158d7500..5a5fbc62739c15af33b71e043a2a68e04507fae6 100644 |
--- a/src/x64/lithium-codegen-x64.cc |
+++ b/src/x64/lithium-codegen-x64.cc |
@@ -3930,13 +3930,14 @@ void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { |
void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
+ HStoreNamedField* hinstr = instr->hydrogen(); |
Representation representation = instr->representation(); |
- HObjectAccess access = instr->hydrogen()->access(); |
+ HObjectAccess access = hinstr->access(); |
int offset = access.offset(); |
if (access.IsExternalMemory()) { |
- ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); |
+ ASSERT(!hinstr->NeedsWriteBarrier()); |
Register value = ToRegister(instr->value()); |
if (instr->object()->IsConstantOperand()) { |
ASSERT(value.is(rax)); |
@@ -3956,7 +3957,8 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
if (FLAG_track_fields && representation.IsSmi()) { |
if (instr->value()->IsConstantOperand()) { |
LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
- if (!IsSmiConstant(operand_value)) { |
+ if (!IsInteger32Constant(operand_value) && |
+ !IsSmiConstant(operand_value)) { |
DeoptimizeIf(no_condition, instr->environment()); |
} |
} |
@@ -3967,7 +3969,7 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
DeoptimizeIf(no_condition, instr->environment()); |
} |
} else { |
- if (!instr->hydrogen()->value()->type().IsHeapObject()) { |
+ if (!hinstr->value()->type().IsHeapObject()) { |
Register value = ToRegister(instr->value()); |
Condition cc = masm()->CheckSmi(value); |
DeoptimizeIf(cc, instr->environment()); |
@@ -3976,14 +3978,14 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
} else if (FLAG_track_double_fields && representation.IsDouble()) { |
ASSERT(transition.is_null()); |
ASSERT(access.IsInobject()); |
- ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); |
+ ASSERT(!hinstr->NeedsWriteBarrier()); |
XMMRegister value = ToDoubleRegister(instr->value()); |
__ movsd(FieldOperand(object, offset), value); |
return; |
} |
if (!transition.is_null()) { |
- if (!instr->hydrogen()->NeedsWriteBarrierForMap()) { |
+ if (!hinstr->NeedsWriteBarrierForMap()) { |
__ Move(FieldOperand(object, HeapObject::kMapOffset), transition); |
} else { |
Register temp = ToRegister(instr->temp()); |
@@ -4001,9 +4003,8 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
} |
// Do the store. |
- SmiCheck check_needed = |
- instr->hydrogen()->value()->IsHeapObject() |
- ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
+ SmiCheck check_needed = hinstr->value()->IsHeapObject() |
+ ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
Register write_register = object; |
if (!access.IsInobject()) { |
@@ -4011,26 +4012,41 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
__ movq(write_register, FieldOperand(object, JSObject::kPropertiesOffset)); |
} |
- if (instr->value()->IsConstantOperand()) { |
+ if (representation.IsSmi() && |
+ hinstr->value()->representation().IsInteger32()) { |
+ ASSERT(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY); |
+ // Store int value directly to upper half of the smi. |
+ STATIC_ASSERT(kSmiTag == 0); |
+ STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32); |
+ offset += kPointerSize / 2; |
+ representation = Representation::Integer32(); |
+ } |
+ |
+ Operand operand = FieldOperand(write_register, offset); |
+ |
+ if (instr->value()->IsRegister()) { |
+ Register value = ToRegister(instr->value()); |
+ __ Store(operand, value, representation); |
+ } else { |
LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
- if (operand_value->IsRegister()) { |
- Register value = ToRegister(operand_value); |
- __ Store(FieldOperand(write_register, offset), value, representation); |
- } else if (representation.IsInteger32()) { |
+ if (IsInteger32Constant(operand_value)) { |
+ ASSERT(!hinstr->NeedsWriteBarrier()); |
int32_t value = ToInteger32(operand_value); |
- ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); |
- __ movl(FieldOperand(write_register, offset), Immediate(value)); |
+ if (representation.IsSmi()) { |
+ __ Move(operand, Smi::FromInt(value)); |
+ |
+ } else { |
+ __ movl(operand, Immediate(value)); |
+ } |
+ |
} else { |
Handle<Object> handle_value = ToHandle(operand_value); |
- ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); |
- __ Move(FieldOperand(write_register, offset), handle_value); |
+ ASSERT(!hinstr->NeedsWriteBarrier()); |
+ __ Move(operand, handle_value); |
} |
- } else { |
- Register value = ToRegister(instr->value()); |
- __ Store(FieldOperand(write_register, offset), value, representation); |
} |
- if (instr->hydrogen()->NeedsWriteBarrier()) { |
+ if (hinstr->NeedsWriteBarrier()) { |
Register value = ToRegister(instr->value()); |
Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object; |
// Update the write barrier for the object for in-object properties. |