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

Reply via email to