Revision: 4155
Author: [email protected]
Date: Wed Mar 17 02:49:03 2010
Log: Fix bug in propagation of type information into registers.
The number type information of results has to be also copied when
calling ToRegister with a fixed register as destination.
Also fix an unbound label and a missing CpuFeatures scope.
Review URL: http://codereview.chromium.org/987003
http://code.google.com/p/v8/source/detail?r=4155
Modified:
/branches/bleeding_edge/src/ia32/codegen-ia32.cc
/branches/bleeding_edge/src/ia32/register-allocator-ia32.cc
/branches/bleeding_edge/src/x64/register-allocator-x64.cc
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Wed Mar 17 01:53:21
2010
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Wed Mar 17 02:49:03
2010
@@ -1578,6 +1578,7 @@
// if right is a smi we make a fast case if left is either a smi
// or a heapnumber.
if (CpuFeatures::IsSupported(SSE2) && right->number_info().IsSmi()) {
+ CpuFeatures::Scope use_sse2(SSE2);
__ mov(answer.reg(), left->reg());
// Fast case - both are actually smis.
if (!left->number_info().IsSmi()) {
@@ -1608,6 +1609,7 @@
__ SmiUntag(answer.reg());
}
+ __ bind(&do_op);
__ SmiUntag(ecx);
// Perform the operation.
switch (op) {
@@ -6652,7 +6654,6 @@
break;
}
frame_->Push(&value);
-
} else {
Load(node->expression());
bool overwrite =
@@ -6663,38 +6664,58 @@
GenericUnaryOpStub stub(Token::SUB, overwrite);
Result operand = frame_->Pop();
Result answer = frame_->CallStub(&stub, &operand);
+ answer.set_number_info(NumberInfo::Number());
frame_->Push(&answer);
break;
}
-
case Token::BIT_NOT: {
// Smi check.
JumpTarget smi_label;
JumpTarget continue_label;
Result operand = frame_->Pop();
+ NumberInfo operand_info = operand.number_info();
operand.ToRegister();
- __ test(operand.reg(), Immediate(kSmiTagMask));
- smi_label.Branch(zero, &operand, taken);
-
- GenericUnaryOpStub stub(Token::BIT_NOT, overwrite);
- Result answer = frame_->CallStub(&stub, &operand);
- continue_label.Jump(&answer);
-
- smi_label.Bind(&answer);
- answer.ToRegister();
- frame_->Spill(answer.reg());
- __ not_(answer.reg());
- __ and_(answer.reg(), ~kSmiTagMask); // Remove inverted smi-tag.
-
- continue_label.Bind(&answer);
- frame_->Push(&answer);
+ if (operand_info.IsSmi()) {
+ if (FLAG_debug_code) {
+ __ AbortIfNotSmi(operand.reg(), "Operand not a smi.");
+ }
+ frame_->Spill(operand.reg());
+ // Set smi tag bit. It will be reset by the not operation.
+ __ lea(operand.reg(), Operand(operand.reg(), kSmiTagMask));
+ __ not_(operand.reg());
+ Result answer = operand;
+ answer.set_number_info(NumberInfo::Smi());
+ frame_->Push(&answer);
+ } else {
+ __ test(operand.reg(), Immediate(kSmiTagMask));
+ smi_label.Branch(zero, &operand, taken);
+
+ GenericUnaryOpStub stub(Token::BIT_NOT, overwrite);
+ Result answer = frame_->CallStub(&stub, &operand);
+ continue_label.Jump(&answer);
+
+ smi_label.Bind(&answer);
+ answer.ToRegister();
+ frame_->Spill(answer.reg());
+ // Set smi tag bit. It will be reset by the not operation.
+ __ lea(answer.reg(), Operand(answer.reg(), kSmiTagMask));
+ __ not_(answer.reg());
+
+ continue_label.Bind(&answer);
+ if (operand_info.IsInteger32()) {
+ answer.set_number_info(NumberInfo::Integer32());
+ } else {
+ answer.set_number_info(NumberInfo::Number());
+ }
+ frame_->Push(&answer);
+ }
break;
}
-
case Token::ADD: {
// Smi check.
JumpTarget continue_label;
Result operand = frame_->Pop();
+ NumberInfo operand_info = operand.number_info();
operand.ToRegister();
__ test(operand.reg(), Immediate(kSmiTagMask));
continue_label.Branch(zero, &operand, taken);
@@ -6704,10 +6725,16 @@
CALL_FUNCTION, 1);
continue_label.Bind(&answer);
+ if (operand_info.IsSmi()) {
+ answer.set_number_info(NumberInfo::Smi());
+ } else if (operand_info.IsInteger32()) {
+ answer.set_number_info(NumberInfo::Integer32());
+ } else {
+ answer.set_number_info(NumberInfo::Number());
+ }
frame_->Push(&answer);
break;
}
-
default:
// NOT, DELETE, TYPEOF, and VOID are handled outside the
// switch.
=======================================
--- /branches/bleeding_edge/src/ia32/register-allocator-ia32.cc Tue Mar 16
09:07:19 2010
+++ /branches/bleeding_edge/src/ia32/register-allocator-ia32.cc Wed Mar 17
02:49:03 2010
@@ -122,6 +122,7 @@
}
}
}
+ fresh.set_number_info(number_info());
fresh.set_untagged_int32(is_untagged_int32());
*this = fresh;
} else if (is_register() && reg().is(target)) {
=======================================
--- /branches/bleeding_edge/src/x64/register-allocator-x64.cc Fri Feb 26
01:32:48 2010
+++ /branches/bleeding_edge/src/x64/register-allocator-x64.cc Wed Mar 17
02:49:03 2010
@@ -44,6 +44,7 @@
ASSERT(fresh.is_valid());
CodeGeneratorScope::Current()->masm()->Move(fresh.reg(), handle());
// This result becomes a copy of the fresh one.
+ fresh.set_number_info(number_info());
*this = fresh;
}
ASSERT(is_register());
@@ -61,6 +62,7 @@
ASSERT(is_constant());
CodeGeneratorScope::Current()->masm()->Move(fresh.reg(), handle());
}
+ fresh.set_number_info(number_info());
*this = fresh;
} else if (is_register() && reg().is(target)) {
ASSERT(CodeGeneratorScope::Current()->has_valid_frame());
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev