Revision: 3508
Author: [email protected]
Date: Mon Dec 21 07:04:00 2009
Log: Optimize implementation of Math.floor a little by special casing
the comparison it uses in the code generator. Use Math.floor for
date operations.
Review URL: http://codereview.chromium.org/509007
http://code.google.com/p/v8/source/detail?r=3508
Modified:
/branches/bleeding_edge/src/ia32/codegen-ia32.cc
/branches/bleeding_edge/src/jump-target.h
/branches/bleeding_edge/src/macros.py
/branches/bleeding_edge/src/math.js
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Mon Dec 21 05:30:10
2009
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Mon Dec 21 07:04:00
2009
@@ -5928,6 +5928,8 @@
void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
Comment cmnt(masm_, "[ CompareOperation");
+ bool left_already_loaded = false;
+
// Get the expressions from the node.
Expression* left = node->left();
Expression* right = node->right();
@@ -6008,7 +6010,6 @@
__ CmpInstanceType(answer.reg(), JS_REGEXP_TYPE);
answer.Unuse();
destination()->Split(equal);
-
} else if (check->Equals(Heap::object_symbol())) {
__ test(answer.reg(), Immediate(kSmiTagMask));
destination()->false_target()->Branch(zero);
@@ -6040,6 +6041,38 @@
destination()->Goto(false);
}
return;
+ } else if (op == Token::LT &&
+ right->AsLiteral() != NULL &&
+ right->AsLiteral()->handle()->IsHeapNumber()) {
+ Handle<HeapNumber>
check(HeapNumber::cast(*right->AsLiteral()->handle()));
+ if (check->value() == 2147483648.0) { // 0x80000000.
+ Load(left);
+ left_already_loaded = true;
+ Result lhs = frame_->Pop();
+ lhs.ToRegister();
+ __ test(lhs.reg(), Immediate(kSmiTagMask));
+ destination()->true_target()->Branch(zero); // All Smis are less.
+ Result scratch = allocator()->Allocate();
+ ASSERT(scratch.is_valid());
+ __ mov(scratch.reg(), FieldOperand(lhs.reg(),
HeapObject::kMapOffset));
+ __ cmp(scratch.reg(), Factory::heap_number_map());
+ JumpTarget not_a_number;
+ not_a_number.Branch(not_equal, &lhs);
+ __ mov(scratch.reg(),
+ FieldOperand(lhs.reg(), HeapNumber::kExponentOffset));
+ __ cmp(Operand(scratch.reg()), Immediate(0xfff00000));
+ not_a_number.Branch(above_equal, &lhs); // It's a negative NaN or
-Inf.
+ const uint32_t borderline_exponent =
+ (HeapNumber::kExponentBias + 31) << HeapNumber::kExponentShift;
+ __ cmp(Operand(scratch.reg()), Immediate(borderline_exponent));
+ scratch.Unuse();
+ lhs.Unuse();
+ destination()->true_target()->Branch(less);
+ destination()->false_target()->Jump();
+
+ not_a_number.Bind(&lhs);
+ frame_->Push(&lhs);
+ }
}
Condition cc = no_condition;
@@ -6064,14 +6097,14 @@
cc = greater_equal;
break;
case Token::IN: {
- Load(left);
+ if (!left_already_loaded) Load(left);
Load(right);
Result answer = frame_->InvokeBuiltin(Builtins::IN, CALL_FUNCTION,
2);
frame_->Push(&answer); // push the result
return;
}
case Token::INSTANCEOF: {
- Load(left);
+ if (!left_already_loaded) Load(left);
Load(right);
InstanceofStub stub;
Result answer = frame_->CallStub(&stub, 2);
@@ -6084,7 +6117,7 @@
default:
UNREACHABLE();
}
- Load(left);
+ if (!left_already_loaded) Load(left);
Load(right);
Comparison(node, cc, strict, destination());
}
=======================================
--- /branches/bleeding_edge/src/jump-target.h Thu Oct 15 08:01:36 2009
+++ /branches/bleeding_edge/src/jump-target.h Mon Dec 21 07:04:00 2009
@@ -112,7 +112,8 @@
// Emit a conditional branch to the target. There must be a current
// frame at the branch. The current frame will fall through to the
- // code after the branch.
+ // code after the branch. The arg is a result that is live both at
+ // the target and the fall-through.
virtual void Branch(Condition cc, Hint hint = no_hint);
virtual void Branch(Condition cc, Result* arg, Hint hint = no_hint);
=======================================
--- /branches/bleeding_edge/src/macros.py Wed Nov 18 23:41:32 2009
+++ /branches/bleeding_edge/src/macros.py Mon Dec 21 07:04:00 2009
@@ -92,7 +92,7 @@
macro IS_SCRIPT(arg) = (%_ClassOf(arg) === 'Script');
macro IS_ARGUMENTS(arg) = (%_ClassOf(arg) === 'Arguments');
macro IS_GLOBAL(arg) = (%_ClassOf(arg) === 'global');
-macro FLOOR(arg) = %Math_floor(arg);
+macro FLOOR(arg) = $floor(arg);
# Inline macros. Use %IS_VAR to make sure arg is evaluated only once.
macro NUMBER_IS_NAN(arg) = (!%_IsSmi(%IS_VAR(arg)) && !(arg == arg));
=======================================
--- /branches/bleeding_edge/src/math.js Mon Dec 21 05:30:10 2009
+++ /branches/bleeding_edge/src/math.js Mon Dec 21 07:04:00 2009
@@ -98,7 +98,7 @@
if (!IS_NUMBER(x)) x = ToNumber(x);
// It's more common to call this with a positive number that's out
// of range than negative numbers; check the upper bound first.
- if (x <= 0x7FFFFFFF && x > 0) {
+ if (x < 0x80000000 && x > 0) {
// Numbers in the range [0, 2^31) can be floored by converting
// them to an unsigned 32-bit value using the shift operator.
// We avoid doing so for -0, because the result of Math.floor(-0)
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev