Fix problem with GenericBinaryOperationStub::GenerateCall for a Smi

left operand.  For non-commutative operations the right operand could
be overwritten with the Smi left operand.

We need better testing of all of these cases.  We will add more test
cases as a separate commit.
Review URL: http://codereview.chromium.org/598059

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3834 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
ager@chromium.org 2010-02-11 12:26:08 +00:00
parent 9b47ae91d1
commit 51a7ecc1f7
2 changed files with 22 additions and 6 deletions

View File

@ -7036,6 +7036,8 @@ void GenericBinaryOpStub::GenerateCall(
} }
} else if (left.is(left_arg)) { } else if (left.is(left_arg)) {
__ mov(right_arg, right); __ mov(right_arg, right);
} else if (right.is(right_arg)) {
__ mov(left_arg, left);
} else if (left.is(right_arg)) { } else if (left.is(right_arg)) {
if (IsOperationCommutative()) { if (IsOperationCommutative()) {
__ mov(left_arg, right); __ mov(left_arg, right);
@ -7054,8 +7056,6 @@ void GenericBinaryOpStub::GenerateCall(
__ mov(right_arg, right); __ mov(right_arg, right);
__ mov(left_arg, left); __ mov(left_arg, left);
} }
} else if (right.is(right_arg)) {
__ mov(left_arg, left);
} else { } else {
// Order of moves is not important. // Order of moves is not important.
__ mov(left_arg, left); __ mov(left_arg, left);
@ -7091,6 +7091,10 @@ void GenericBinaryOpStub::GenerateCall(
__ mov(left_arg, Immediate(right)); __ mov(left_arg, Immediate(right));
SetArgsReversed(); SetArgsReversed();
} else { } else {
// For non-commutative operations, left and right_arg might be
// the same register. Therefore, the order of the moves is
// important here in order to not overwrite left before moving
// it to left_arg.
__ mov(left_arg, left); __ mov(left_arg, left);
__ mov(right_arg, Immediate(right)); __ mov(right_arg, Immediate(right));
} }
@ -7123,8 +7127,12 @@ void GenericBinaryOpStub::GenerateCall(
__ mov(right_arg, Immediate(left)); __ mov(right_arg, Immediate(left));
SetArgsReversed(); SetArgsReversed();
} else { } else {
__ mov(left_arg, Immediate(left)); // For non-commutative operations, right and left_arg might be
// the same register. Therefore, the order of the moves is
// important here in order to not overwrite right before moving
// it to right_arg.
__ mov(right_arg, right); __ mov(right_arg, right);
__ mov(left_arg, Immediate(left));
} }
// Update flags to indicate that arguments are in registers. // Update flags to indicate that arguments are in registers.
SetArgsInRegisters(); SetArgsInRegisters();

View File

@ -8051,6 +8051,8 @@ void GenericBinaryOpStub::GenerateCall(
} }
} else if (left.is(left_arg)) { } else if (left.is(left_arg)) {
__ movq(right_arg, right); __ movq(right_arg, right);
} else if (right.is(right_arg)) {
__ movq(left_arg, left);
} else if (left.is(right_arg)) { } else if (left.is(right_arg)) {
if (IsOperationCommutative()) { if (IsOperationCommutative()) {
__ movq(left_arg, right); __ movq(left_arg, right);
@ -8069,8 +8071,6 @@ void GenericBinaryOpStub::GenerateCall(
__ movq(right_arg, right); __ movq(right_arg, right);
__ movq(left_arg, left); __ movq(left_arg, left);
} }
} else if (right.is(right_arg)) {
__ movq(left_arg, left);
} else { } else {
// Order of moves is not important. // Order of moves is not important.
__ movq(left_arg, left); __ movq(left_arg, left);
@ -8106,6 +8106,10 @@ void GenericBinaryOpStub::GenerateCall(
__ Move(left_arg, right); __ Move(left_arg, right);
SetArgsReversed(); SetArgsReversed();
} else { } else {
// For non-commutative operations, left and right_arg might be
// the same register. Therefore, the order of the moves is
// important here in order to not overwrite left before moving
// it to left_arg.
__ movq(left_arg, left); __ movq(left_arg, left);
__ Move(right_arg, right); __ Move(right_arg, right);
} }
@ -8138,8 +8142,12 @@ void GenericBinaryOpStub::GenerateCall(
__ Move(right_arg, left); __ Move(right_arg, left);
SetArgsReversed(); SetArgsReversed();
} else { } else {
__ Move(left_arg, left); // For non-commutative operations, right and left_arg might be
// the same register. Therefore, the order of the moves is
// important here in order to not overwrite right before moving
// it to right_arg.
__ movq(right_arg, right); __ movq(right_arg, right);
__ Move(left_arg, left);
} }
// Update flags to indicate that arguments are in registers. // Update flags to indicate that arguments are in registers.
SetArgsInRegisters(); SetArgsInRegisters();