Author: [email protected]
Date: Thu Feb 19 05:24:33 2009
New Revision: 1317

Modified:
    branches/experimental/toiger/src/codegen-ia32.cc

Log:
Move inlined comparisons with null constant to use virtual frame constants.
Review URL: http://codereview.chromium.org/21509

Modified: branches/experimental/toiger/src/codegen-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/codegen-ia32.cc    (original)
+++ branches/experimental/toiger/src/codegen-ia32.cc    Thu Feb 19 05:24:33  
2009
@@ -1275,6 +1275,10 @@
        left_side.is_constant() && left_side.handle()->IsSmi();
    bool right_side_constant_smi =
        right_side.is_constant() && right_side.handle()->IsSmi();
+  bool left_side_constant_null =
+      left_side.is_constant() && left_side.handle()->IsNull();
+  bool right_side_constant_null =
+      right_side.is_constant() && right_side.handle()->IsNull();

    if (left_side_constant_smi || right_side_constant_smi) {
      if (left_side_constant_smi && right_side_constant_smi) {
@@ -1301,6 +1305,8 @@
          left_side = right_side;
          right_side = temp;
          cc = ReverseCondition(cc);
+        // This may reintroduce greater or less_equal as the value of cc.
+        // CompareStub and the inline code both support all values of cc.
        }
        // Implement comparison against a constant Smi, inlining the case
        // where both sides are Smis.
@@ -1336,7 +1342,43 @@
        right_side.Unuse();
        dest->Split(cc);
      }
-  } else {  // Neither side is a constant Smi, normal comparison operation.
+  } else if (cc == equal &&
+             (left_side_constant_null || right_side_constant_null)) {
+    // To make null checks efficient, we check if either the left side or
+    // the right side is the constant 'null'.
+    // If so, we optimize the code by inlining a null check instead of
+    // calling the (very) general runtime routine for checking equality.
+    Result operand = left_side_constant_null ? right_side : left_side;
+    right_side.Unuse();
+    left_side.Unuse();
+    operand.ToRegister();
+    __ cmp(operand.reg(), Factory::null_value());
+    if (strict) {
+      operand.Unuse();
+      dest->Split(equal);
+    } else {
+      // The 'null' value is only equal to 'undefined' if using non-strict
+      // comparisons.
+      dest->true_target()->Branch(equal);
+      __ cmp(operand.reg(), Factory::undefined_value());
+      dest->true_target()->Branch(equal);
+      __ test(operand.reg(), Immediate(kSmiTagMask));
+      dest->false_target()->Branch(equal);
+
+      // It can be an undetectable object.
+      // Use a scratch register in preference to spilling operand.reg().
+      Result temp = allocator()->Allocate();
+      ASSERT(temp.is_valid());
+      __ mov(temp.reg(),
+             FieldOperand(operand.reg(), HeapObject::kMapOffset));
+      __ movzx_b(temp.reg(),
+                 FieldOperand(temp.reg(), Map::kBitFieldOffset));
+      __ test(temp.reg(), Immediate(1 << Map::kIsUndetectable));
+      temp.Unuse();
+      operand.Unuse();
+      dest->Split(not_zero);
+    }
+  } else {  // Neither side is a constant Smi or 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() ||
@@ -4538,51 +4580,6 @@
    Expression* left = node->left();
    Expression* right = node->right();
    Token::Value op = node->op();
-
-  // To make null checks efficient, we check if either left or right is the
-  // literal 'null'. If so, we optimize the code by inlining a null check
-  // instead of calling the (very) general runtime routine for checking
-  // equality.
-  if (op == Token::EQ || op == Token::EQ_STRICT) {
-    bool left_is_null =
-        left->AsLiteral() != NULL && left->AsLiteral()->IsNull();
-    bool right_is_null =
-        right->AsLiteral() != NULL && right->AsLiteral()->IsNull();
-    // The 'null' value can only be equal to 'null' or 'undefined'.
-    if (left_is_null || right_is_null) {
-      Load(left_is_null ? right : left);
-      Result operand = frame_->Pop();
-      operand.ToRegister();
-      __ cmp(operand.reg(), Factory::null_value());
-      Condition cc = equal;
-
-      // The 'null' value is only equal to 'undefined' if using non-strict
-      // comparisons.
-      if (op != Token::EQ_STRICT) {
-        destination()->true_target()->Branch(cc);
-        __ cmp(operand.reg(), Factory::undefined_value());
-        destination()->true_target()->Branch(equal);
-        __ test(operand.reg(), Immediate(kSmiTagMask));
-        destination()->false_target()->Branch(equal);
-
-        // It can be an undetectable object.
-        // Use a scratch register in preference to spilling operand.reg().
-        Result temp = allocator()->Allocate();
-        ASSERT(temp.is_valid());
-        __ mov(temp.reg(),
-               FieldOperand(operand.reg(), HeapObject::kMapOffset));
-        __ movzx_b(temp.reg(),
-                   FieldOperand(temp.reg(), Map::kBitFieldOffset));
-        __ test(temp.reg(), Immediate(1 << Map::kIsUndetectable));
-        cc = not_zero;
-      }
-
-      operand.Unuse();
-      destination()->Split(cc);
-      return;
-    }
-  }
-
    // To make typeof testing for natives implemented in JavaScript really
    // efficient, we generate special code for expressions of the form:
    // 'typeof <expression> == <string>'.

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to