Commit 14975f3d authored by erik.corry@gmail.com's avatar erik.corry@gmail.com

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3508 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent fc263074
...@@ -5928,6 +5928,8 @@ void CodeGenerator::VisitThisFunction(ThisFunction* node) { ...@@ -5928,6 +5928,8 @@ void CodeGenerator::VisitThisFunction(ThisFunction* node) {
void CodeGenerator::VisitCompareOperation(CompareOperation* node) { void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
Comment cmnt(masm_, "[ CompareOperation"); Comment cmnt(masm_, "[ CompareOperation");
bool left_already_loaded = false;
// Get the expressions from the node. // Get the expressions from the node.
Expression* left = node->left(); Expression* left = node->left();
Expression* right = node->right(); Expression* right = node->right();
...@@ -6008,7 +6010,6 @@ void CodeGenerator::VisitCompareOperation(CompareOperation* node) { ...@@ -6008,7 +6010,6 @@ void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
__ CmpInstanceType(answer.reg(), JS_REGEXP_TYPE); __ CmpInstanceType(answer.reg(), JS_REGEXP_TYPE);
answer.Unuse(); answer.Unuse();
destination()->Split(equal); destination()->Split(equal);
} else if (check->Equals(Heap::object_symbol())) { } else if (check->Equals(Heap::object_symbol())) {
__ test(answer.reg(), Immediate(kSmiTagMask)); __ test(answer.reg(), Immediate(kSmiTagMask));
destination()->false_target()->Branch(zero); destination()->false_target()->Branch(zero);
...@@ -6040,6 +6041,38 @@ void CodeGenerator::VisitCompareOperation(CompareOperation* node) { ...@@ -6040,6 +6041,38 @@ void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
destination()->Goto(false); destination()->Goto(false);
} }
return; 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; Condition cc = no_condition;
...@@ -6064,14 +6097,14 @@ void CodeGenerator::VisitCompareOperation(CompareOperation* node) { ...@@ -6064,14 +6097,14 @@ void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
cc = greater_equal; cc = greater_equal;
break; break;
case Token::IN: { case Token::IN: {
Load(left); if (!left_already_loaded) Load(left);
Load(right); Load(right);
Result answer = frame_->InvokeBuiltin(Builtins::IN, CALL_FUNCTION, 2); Result answer = frame_->InvokeBuiltin(Builtins::IN, CALL_FUNCTION, 2);
frame_->Push(&answer); // push the result frame_->Push(&answer); // push the result
return; return;
} }
case Token::INSTANCEOF: { case Token::INSTANCEOF: {
Load(left); if (!left_already_loaded) Load(left);
Load(right); Load(right);
InstanceofStub stub; InstanceofStub stub;
Result answer = frame_->CallStub(&stub, 2); Result answer = frame_->CallStub(&stub, 2);
...@@ -6084,7 +6117,7 @@ void CodeGenerator::VisitCompareOperation(CompareOperation* node) { ...@@ -6084,7 +6117,7 @@ void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
default: default:
UNREACHABLE(); UNREACHABLE();
} }
Load(left); if (!left_already_loaded) Load(left);
Load(right); Load(right);
Comparison(node, cc, strict, destination()); Comparison(node, cc, strict, destination());
} }
......
...@@ -112,7 +112,8 @@ class JumpTarget : public ZoneObject { // Shadows are dynamically allocated. ...@@ -112,7 +112,8 @@ class JumpTarget : public ZoneObject { // Shadows are dynamically allocated.
// Emit a conditional branch to the target. There must be a current // Emit a conditional branch to the target. There must be a current
// frame at the branch. The current frame will fall through to the // 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, Hint hint = no_hint);
virtual void Branch(Condition cc, Result* arg, Hint hint = no_hint); virtual void Branch(Condition cc, Result* arg, Hint hint = no_hint);
......
...@@ -92,7 +92,7 @@ macro IS_ERROR(arg) = (%_ClassOf(arg) === 'Error'); ...@@ -92,7 +92,7 @@ macro IS_ERROR(arg) = (%_ClassOf(arg) === 'Error');
macro IS_SCRIPT(arg) = (%_ClassOf(arg) === 'Script'); macro IS_SCRIPT(arg) = (%_ClassOf(arg) === 'Script');
macro IS_ARGUMENTS(arg) = (%_ClassOf(arg) === 'Arguments'); macro IS_ARGUMENTS(arg) = (%_ClassOf(arg) === 'Arguments');
macro IS_GLOBAL(arg) = (%_ClassOf(arg) === 'global'); 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. # Inline macros. Use %IS_VAR to make sure arg is evaluated only once.
macro NUMBER_IS_NAN(arg) = (!%_IsSmi(%IS_VAR(arg)) && !(arg == arg)); macro NUMBER_IS_NAN(arg) = (!%_IsSmi(%IS_VAR(arg)) && !(arg == arg));
......
...@@ -98,7 +98,7 @@ function MathFloor(x) { ...@@ -98,7 +98,7 @@ function MathFloor(x) {
if (!IS_NUMBER(x)) x = ToNumber(x); if (!IS_NUMBER(x)) x = ToNumber(x);
// It's more common to call this with a positive number that's out // It's more common to call this with a positive number that's out
// of range than negative numbers; check the upper bound first. // 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 // Numbers in the range [0, 2^31) can be floored by converting
// them to an unsigned 32-bit value using the shift operator. // them to an unsigned 32-bit value using the shift operator.
// We avoid doing so for -0, because the result of Math.floor(-0) // We avoid doing so for -0, because the result of Math.floor(-0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment