Reviewers: Mads Ager,
Message:
Simple cl for you.
Description:
Port inlined quick equality check for non-NaN to x64.
Please review this at http://codereview.chromium.org/1756002/show
SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge/
Affected files:
M src/ia32/codegen-ia32.cc
M src/x64/codegen-x64.cc
Index: src/ia32/codegen-ia32.cc
===================================================================
--- src/ia32/codegen-ia32.cc (revision 4462)
+++ src/ia32/codegen-ia32.cc (working copy)
@@ -2773,11 +2773,7 @@
// number comparison in the stub if it was inlined.
CompareStub stub(cc, strict, nan_info, !inline_number_compare);
Result answer = frame_->CallStub(&stub, &left_side, &right_side);
- if (cc == equal) {
- __ test(answer.reg(), Operand(answer.reg()));
- } else {
- __ cmp(answer.reg(), 0);
- }
+ __ test(answer.reg(), Operand(answer.reg()));
answer.Unuse();
dest->Split(cc);
} else {
Index: src/x64/codegen-x64.cc
===================================================================
--- src/x64/codegen-x64.cc (revision 4462)
+++ src/x64/codegen-x64.cc (working copy)
@@ -5297,6 +5297,15 @@
}
+static bool CouldBeNaN(const Result& result) {
+ if (result.type_info().IsSmi()) return false;
+ if (result.type_info().IsInteger32()) return false;
+ if (!result.is_constant()) return true;
+ if (!result.handle()->IsHeapNumber()) return false;
+ return isnan(HeapNumber::cast(*result.handle())->value());
+}
+
+
void CodeGenerator::Comparison(AstNode* node,
Condition cc,
bool strict,
@@ -5614,15 +5623,29 @@
right_side.Unuse();
dest->Split(cc);
}
- } else { // Neither side is a constant Smi or null.
+ } else {
+ // Neither side is a constant Smi, constant 1-char string, or constant
null.
// If either side is a non-smi constant, skip the smi check.
bool known_non_smi =
(left_side.is_constant() && !left_side.handle()->IsSmi()) ||
(right_side.is_constant() && !right_side.handle()->IsSmi());
+
+ NaNInformation nan_info =
+ (CouldBeNaN(left_side) && CouldBeNaN(right_side)) ?
+ kBothCouldBeNaN :
+ kCantBothBeNaN;
+
left_side.ToRegister();
right_side.ToRegister();
if (known_non_smi) {
+ // If at least one of the objects is not NaN, then if the objects
+ // are identical, they are equal.
+ if (nan_info == kCantBothBeNaN && cc == equal) {
+ __ cmpq(left_side.reg(), right_side.reg());
+ dest->true_target()->Branch(equal);
+ }
+
// When non-smi, call out to the compare stub.
CompareStub stub(cc, strict);
Result answer = frame_->CallStub(&stub, &left_side, &right_side);
@@ -5642,7 +5665,14 @@
Condition both_smi = masm_->CheckBothSmi(left_reg, right_reg);
is_smi.Branch(both_smi);
- // When non-smi, call out to the compare stub.
+ // When non-smi, call out to the compare stub, after inlined checks.
+ // If at least one of the objects is not NaN, then if the objects
+ // are identical, they are equal.
+ if (nan_info == kCantBothBeNaN && cc == equal) {
+ __ cmpq(left_side.reg(), right_side.reg());
+ dest->true_target()->Branch(equal);
+ }
+
CompareStub stub(cc, strict);
Result answer = frame_->CallStub(&stub, &left_side, &right_side);
__ SmiTest(answer.reg()); // Sets both zero and sign flags.
--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev