Fixed issue in StoreNamedField codegen where integer32 constants were not converted to a smi.

BUG=

Review URL: https://codereview.chromium.org/14075014

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14380 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
mvstanton@chromium.org 2013-04-22 15:35:23 +00:00
parent 555c78c513
commit 54a11734ac
4 changed files with 74 additions and 42 deletions

View File

@ -4253,15 +4253,15 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
if (instr->value()->IsConstantOperand()) { if (instr->value()->IsConstantOperand()) {
LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
if (IsInteger32(operand_value)) { if (IsInteger32(operand_value)) {
int const_value = ToInteger32(operand_value); // In lithium register preparation, we made sure that the constant integer
__ mov(FieldOperand(write_register, offset), Immediate(const_value)); // 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 { } else {
if (operand_value->IsRegister()) { Handle<Object> handle_value = ToHandle(operand_value);
__ mov(FieldOperand(write_register, offset), ToRegister(operand_value)); __ mov(FieldOperand(write_register, offset), handle_value);
} else {
Handle<Object> handle_value = ToHandle(operand_value);
__ mov(FieldOperand(write_register, offset), handle_value);
}
} }
} else { } else {
__ mov(FieldOperand(write_register, offset), ToRegister(instr->value())); __ mov(FieldOperand(write_register, offset), ToRegister(instr->value()));

View File

@ -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) { LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
if (!instr->is_external()) { if (!instr->is_external()) {
ASSERT(instr->elements()->representation().IsTagged()); ASSERT(instr->elements()->representation().IsTagged());
@ -2314,8 +2327,17 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
val = UseTempRegister(instr->value()); val = UseTempRegister(instr->value());
key = UseTempRegister(instr->key()); key = UseTempRegister(instr->key());
} else { } else {
val = UseRegisterOrConstantAtStart(instr->value()); if (StoreConstantValueAllowed(instr->value())) {
key = UseRegisterOrConstantAtStart(instr->key()); 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); return new(zone()) LStoreKeyed(obj, key, val);
} }
@ -2416,18 +2438,10 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
: UseRegisterAtStart(instr->object()); : 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; LOperand* val;
if (needs_write_barrier) { if (needs_write_barrier) {
val = UseTempRegister(instr->value()); val = UseTempRegister(instr->value());
} else if (register_or_constant) { } else if (StoreConstantValueAllowed(instr->value())) {
val = UseRegisterOrConstant(instr->value()); val = UseRegisterOrConstant(instr->value());
} else { } else {
val = UseRegister(instr->value()); val = UseRegister(instr->value());

View File

@ -3954,16 +3954,16 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
if (instr->value()->IsConstantOperand()) { if (instr->value()->IsConstantOperand()) {
LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
if (IsInteger32Constant(operand_value)) { if (IsInteger32Constant(operand_value)) {
int const_value = ToInteger32(operand_value); // In lithium register preparation, we made sure that the constant integer
__ movq(FieldOperand(write_register, offset), Immediate(const_value)); // 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 { } else {
if (operand_value->IsRegister()) { Handle<Object> handle_value = ToHandle(operand_value);
__ movq(FieldOperand(write_register, offset), __ Move(FieldOperand(write_register, offset), handle_value);
ToRegister(operand_value));
} else {
Handle<Object> handle_value = ToHandle(operand_value);
__ Move(FieldOperand(write_register, offset), handle_value);
}
} }
} else { } else {
__ movq(FieldOperand(write_register, offset), ToRegister(instr->value())); __ movq(FieldOperand(write_register, offset), ToRegister(instr->value()));

View File

@ -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) { LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
ElementsKind elements_kind = instr->elements_kind(); ElementsKind elements_kind = instr->elements_kind();
bool clobbers_key = instr->key()->representation().IsTagged(); bool clobbers_key = instr->key()->representation().IsTagged();
@ -2143,11 +2156,24 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
} else { } else {
ASSERT(instr->value()->representation().IsTagged()); ASSERT(instr->value()->representation().IsTagged());
object = UseTempRegister(instr->elements()); object = UseTempRegister(instr->elements());
val = needs_write_barrier ? UseTempRegister(instr->value()) if (needs_write_barrier) {
: UseRegisterOrConstantAtStart(instr->value()); val = UseTempRegister(instr->value());
key = (clobbers_key || needs_write_barrier) key = UseTempRegister(instr->key());
? UseTempRegister(instr->key()) } else {
: UseRegisterOrConstantAtStart(instr->key()); 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); return new(zone()) LStoreKeyed(object, key, val);
@ -2241,18 +2267,10 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
: UseRegisterAtStart(instr->object()); : 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; LOperand* val;
if (needs_write_barrier) { if (needs_write_barrier) {
val = UseTempRegister(instr->value()); val = UseTempRegister(instr->value());
} else if (register_or_constant) { } else if (StoreConstantValueAllowed(instr->value())) {
val = UseRegisterOrConstant(instr->value()); val = UseRegisterOrConstant(instr->value());
} else { } else {
val = UseRegister(instr->value()); val = UseRegister(instr->value());