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:
parent
555c78c513
commit
54a11734ac
@ -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()));
|
||||||
|
@ -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());
|
||||||
|
@ -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()));
|
||||||
|
@ -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());
|
||||||
|
Loading…
Reference in New Issue
Block a user