Author: whessev8
Date: Mon Jan 12 07:41:08 2009
New Revision: 1054

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

Log:
Computes Boolean AND and OR without spilling frames.
Review URL: http://codereview.chromium.org/17607

Modified: branches/experimental/toiger/src/codegen-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/codegen-ia32.cc    (original)
+++ branches/experimental/toiger/src/codegen-ia32.cc    Mon Jan 12 07:41:08  
2009
@@ -407,22 +407,29 @@
                                    bool force_cc) {
    ASSERT(!in_spilled_code());
    ASSERT(!has_cc());
-
+#ifdef DEBUG
+  int original_height = frame_->height();
+#endif
    { CodeGenState new_state(this, typeof_state, true_target, false_target);
      Visit(x);
    }

    if (force_cc && has_valid_frame() && !has_cc()) {
      // Convert the TOS value to a boolean in the condition code register.
-    VirtualFrame::SpilledScope spilled_scope(this);
      ToBoolean(true_target, false_target);
    }

    ASSERT(!force_cc || frame_ == NULL || has_cc());
+  ASSERT(!has_valid_frame() ||
+         (has_cc() && frame_->height() == original_height) ||
+         (!has_cc() && frame_->height() == original_height + 1));
  }


  void CodeGenerator::Load(Expression* x, TypeofState typeof_state) {
+#ifdef DEBUG
+  int original_height = frame_->height();
+#endif
    ASSERT(!in_spilled_code());
    JumpTarget true_target(this);
    JumpTarget false_target(this);
@@ -473,6 +480,7 @@
    }
    ASSERT(has_valid_frame());
    ASSERT(!has_cc());
+  ASSERT(frame_->height() == original_height + 1);
  }


@@ -606,34 +614,36 @@
    Comment cmnt(masm_, "[ ToBoolean");

    // The value to convert should be popped from the stack.
-  frame_->EmitPop(eax);
-
+  Result value = frame_->Pop();
+  value.ToRegister();
    // Fast case checks.

    // 'false' => false.
-  __ cmp(eax, Factory::false_value());
+  __ cmp(value.reg(), Factory::false_value());
    false_target->Branch(equal);

    // 'true' => true.
-  __ cmp(eax, Factory::true_value());
+  __ cmp(value.reg(), Factory::true_value());
    true_target->Branch(equal);

    // 'undefined' => false.
-  __ cmp(eax, Factory::undefined_value());
+  __ cmp(value.reg(), Factory::undefined_value());
    false_target->Branch(equal);

    // Smi => false iff zero.
    ASSERT(kSmiTag == 0);
-  __ test(eax, Operand(eax));
+  __ test(value.reg(), Operand(value.reg()));
    false_target->Branch(zero);
-  __ test(eax, Immediate(kSmiTagMask));
+  __ test(value.reg(), Immediate(kSmiTagMask));
    true_target->Branch(zero);

    // Call the stub for all other cases.
-  frame_->EmitPush(eax);  // Undo the pop(eax) from above.
+  frame_->Push(&value);  // Undo the Pop() from above.
    ToBooleanStub stub;
    frame_->CallStub(&stub, 1);
    // Convert the result (eax) to condition code.
+  Result temp = allocator_->Allocate(eax);
+  ASSERT(temp.is_valid());
    __ test(eax, Operand(eax));

    ASSERT(not_equal == not_zero);
@@ -4020,7 +4030,6 @@


  void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) {
-  VirtualFrame::SpilledScope spilled_scope(this);
    // Note that due to an optimization in comparison operations (typeof
    // compared to a string literal), we can evaluate a binary expression  
such
    // as AND or OR and not leave a value on the frame or in the cc register.
@@ -4041,19 +4050,21 @@

    if (op == Token::AND) {
      JumpTarget is_true(this);
-    LoadConditionAndSpill(node->left(), NOT_INSIDE_TYPEOF,
-                          &is_true, false_target(), false);
+    LoadCondition(node->left(), NOT_INSIDE_TYPEOF,
+                  &is_true, false_target(), false);
      if (has_cc() || frame_ == NULL) {
        if (has_cc()) {
          ASSERT(has_valid_frame());
          Branch(false, false_target());
        }

-      if (has_valid_frame() || is_true.is_linked()) {
-        // Evaluate right side expression.
+      if (is_true.is_linked()) {
          is_true.Bind();
-        LoadConditionAndSpill(node->right(), NOT_INSIDE_TYPEOF,
-                              true_target(), false_target(), false);
+      }
+      if (has_valid_frame()) {
+        // Evaluate right side expression.
+        LoadCondition(node->right(), NOT_INSIDE_TYPEOF,
+                      true_target(), false_target(), false);
        }
      } else {
        // We have a materialized value on the frame.
@@ -4065,8 +4076,7 @@
        // 9.2, page 30.
        //
        // Duplicate the TOS value. The duplicate will be popped by  
ToBoolean.
-      __ mov(eax, frame_->Top());
-      frame_->EmitPush(eax);
+      frame_->Dup();
        ToBoolean(&pop_and_continue, &exit);
        Branch(false, &exit);

@@ -4076,7 +4086,7 @@

        // Evaluate right side expression.
        is_true.Bind();
-      LoadAndSpill(node->right());
+      Load(node->right());

        // Exit (always with a materialized value).
        exit.Bind();
@@ -4084,21 +4094,22 @@

    } else if (op == Token::OR) {
      JumpTarget is_false(this);
-    LoadConditionAndSpill(node->left(), NOT_INSIDE_TYPEOF,
-                          true_target(), &is_false, false);
+    LoadCondition(node->left(), NOT_INSIDE_TYPEOF,
+                  true_target(), &is_false, false);
      if (has_cc() || frame_ == NULL) {
        if (has_cc()) {
          ASSERT(has_valid_frame());
          Branch(true, true_target());
        }

-      if (has_valid_frame() || is_false.is_linked()) {
+      if (is_false.is_linked()) {
          // Evaluate right side expression.
          is_false.Bind();
-        LoadConditionAndSpill(node->right(), NOT_INSIDE_TYPEOF,
-                              true_target(), false_target(), false);
        }
-
+      if (has_valid_frame()) {
+        LoadCondition(node->right(), NOT_INSIDE_TYPEOF,
+                      true_target(), false_target(), false);
+      }
      } else {
        // We have a materialized value on the frame.
        JumpTarget pop_and_continue(this);
@@ -4108,8 +4119,7 @@
        // standard ToBoolean() conversion as described in ECMA-262,
        // section 9.2, page 30.
        // Duplicate the TOS value. The duplicate will be popped by  
ToBoolean.
-      __ mov(eax, frame_->Top());
-      frame_->EmitPush(eax);
+      frame_->Dup();
        ToBoolean(&exit, &pop_and_continue);
        Branch(true, &exit);

@@ -4119,13 +4129,14 @@

        // Evaluate right side expression.
        is_false.Bind();
-      LoadAndSpill(node->right());
+      Load(node->right());

        // Exit (always with a materialized value).
        exit.Bind();
      }

    } else {
+    VirtualFrame::SpilledScope spilled_scope(this);
      // NOTE: The code below assumes that the slow cases (calls to runtime)
      // never return a constant/immutable object.
      OverwriteMode overwrite_mode = NO_OVERWRITE;

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

Reply via email to