Author: [email protected]
Date: Tue Jan  6 05:41:47 2009
New Revision: 1029

Modified:
    branches/experimental/toiger/src/codegen-ia32.cc
    branches/experimental/toiger/src/codegen.cc
    branches/experimental/toiger/src/virtual-frame-ia32.cc
    branches/experimental/toiger/src/virtual-frame-ia32.h
    branches/experimental/toiger/test/mjsunit/switch.js

Log:
Experimental: begin using the register allocator for switch statements
but not fast-case ones.
Review URL: http://codereview.chromium.org/16513

Modified: branches/experimental/toiger/src/codegen-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/codegen-ia32.cc    (original)
+++ branches/experimental/toiger/src/codegen-ia32.cc    Tue Jan  6 05:41:47  
2009
@@ -1675,12 +1675,12 @@
      // Verify that the result of the runtime call and the esi register are
      // the same in debug mode.
      __ cmp(context.reg(), Operand(esi));
-    verified_true.Branch(equal, &context);
+    context.Unuse();
+    verified_true.Branch(equal);
      frame_->SpillAll();
      __ int3();
-    verified_true.Bind(&context);
+    verified_true.Bind();
    }
-  context.Unuse();

    // Update context local.
    frame_->SaveContextRegister();
@@ -1724,6 +1724,7 @@
    // placeholders, and fill in the addresses after the labels have been
    // bound.

+  VirtualFrame::SpilledScope spilled_scope(this);
    frame_->EmitPop(eax);  // supposed Smi
    // check range of value, if outside [0..length-1] jump to default/end  
label.
    ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
@@ -1738,8 +1739,8 @@
    __ cmp(ebx, HEAP_NUMBER_TYPE);
    fail_label->Branch(not_equal);
    // eax points to a heap number.
-  __ push(eax);
-  __ CallRuntime(Runtime::kNumberToSmi, 1);
+  frame_->EmitPush(eax);
+  frame_->CallRuntime(Runtime::kNumberToSmi, 1);
    is_smi.Bind();

    if (min_index != 0) {
@@ -1777,13 +1778,12 @@

  void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
    ASSERT(!in_spilled_code());
-  VirtualFrame::SpilledScope spilled_scope(this);
    Comment cmnt(masm_, "[ SwitchStatement");
    CodeForStatement(node);
    node->set_break_stack_height(break_stack_height_);
    node->break_target()->set_code_generator(this);

-  LoadAndSpill(node->tag());
+  Load(node->tag());

    if (TryGenerateFastCaseSwitchStatement(node)) {
      return;
@@ -1805,34 +1805,42 @@
        continue;
      }

+    // Compile each non-default clause.
      Comment cmnt(masm_, "[ Case clause");
-    // Compile the test.
-    next_test.Bind();
-    next_test.Unuse();
-    // Duplicate TOS.
-    __ mov(eax, frame_->Top());
-    frame_->EmitPush(eax);
-    LoadAndSpill(clause->label());
+    // Label and compile the test.
+    if (next_test.is_linked()) {
+      // Recycle the same label for each test.
+      next_test.Bind();
+      next_test.Unuse();
+    }
+    // Duplicate the switch value.
+    frame_->Dup();
+    Load(clause->label());
      Comparison(equal, true);
      Branch(false, &next_test);

-    // Before entering the body from the test, remove the switch value from
-    // the stack.
+    // Before entering the body from the test remove the switch value from
+    // the frame.
      frame_->Drop();

      // Label the body so that fall through is enabled.
      if (i > 0 && cases->at(i - 1)->is_default()) {
+      // The previous case was the default.  This will be the target of a
+      // possible backward edge.
        default_exit.Bind();
-    } else {
+    } else if (fall_through.is_linked()) {
+      // Recycle the same label for each fall through except for the  
default
+      // case.
        fall_through.Bind();
        fall_through.Unuse();
      }
-    VisitStatementsAndSpill(clause->statements());
+    VisitStatements(clause->statements());

-    // If control flow can fall through from the body, jump to the next  
body
+    // If control flow can fall through from the body jump to the next body
      // or the end of the statement.
      if (has_valid_frame()) {
        if (i < length - 1 && cases->at(i + 1)->is_default()) {
+        // The next case is the default.
          default_entry.Jump();
        } else {
          fall_through.Jump();
@@ -1840,15 +1848,15 @@
      }
    }

-  // The final "test" removes the switch value.
+  // The block at the final "test" label removes the switch value.
    next_test.Bind();
    frame_->Drop();

-  // If there is a default clause, compile it.
+  // If there is a default clause, compile it now.
    if (default_clause != NULL) {
      Comment cmnt(masm_, "[ Default clause");
      default_entry.Bind();
-    VisitStatementsAndSpill(default_clause->statements());
+    VisitStatements(default_clause->statements());
      // If control flow can fall out of the default and there is a case  
after
      // it, jump to that case's body.
      if (has_valid_frame() && default_exit.is_bound()) {

Modified: branches/experimental/toiger/src/codegen.cc
==============================================================================
--- branches/experimental/toiger/src/codegen.cc (original)
+++ branches/experimental/toiger/src/codegen.cc Tue Jan  6 05:41:47 2009
@@ -442,9 +442,10 @@
      CaseClause* clause = cases->at(i);
      if (clause->is_default()) {
        if (default_index >= 0) {
-        return false;  // More than one default label:
-                       // Defer to normal case for error.
-    }
+        // There is more than one default label. Defer to the normal case
+        // for error.
+        return false;
+      }
        default_index = i;
      } else {
        Expression* label = clause->label();
@@ -456,9 +457,9 @@
        if (!value->IsSmi()) {
          return false;
        }
-      int smi = Smi::cast(value)->value();
-      if (smi < min_index) { min_index = smi; }
-      if (smi > max_index) { max_index = smi; }
+      int int_value = Smi::cast(value)->value();
+      min_index = Min(int_value, min_index);
+      max_index = Max(int_value, max_index);
      }
    }


Modified: branches/experimental/toiger/src/virtual-frame-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/virtual-frame-ia32.cc      (original)
+++ branches/experimental/toiger/src/virtual-frame-ia32.cc      Tue Jan  6  
05:41:47 2009
@@ -727,15 +727,14 @@
      ASSERT(temp.is_valid());
      FrameElement new_element
          = FrameElement::RegisterElement(temp.reg(),
-                                        FrameElement::NOT_SYNCED);
+                                        FrameElement::SYNCED);
      Use(temp.reg());
      elements_[index] = new_element;
+    __ mov(temp.reg(), Operand(ebp, fp_relative(index)));
+
      Use(temp.reg());
+    new_element.clear_sync();
      elements_.Add(new_element);
-
-    // Finally, move the element at the index into its new location.
-    elements_[index].set_sync();
-    __ mov(temp.reg(), Operand(ebp, fp_relative(index)));
    } else {
      // For constants and registers, add an (unsynced) copy of the element  
to
      // the top of the frame.
@@ -896,9 +895,6 @@
      }
    }
  }
-
-
-void VirtualFrame::Drop() { Drop(1); }


  Result VirtualFrame::Pop() {

Modified: branches/experimental/toiger/src/virtual-frame-ia32.h
==============================================================================
--- branches/experimental/toiger/src/virtual-frame-ia32.h       (original)
+++ branches/experimental/toiger/src/virtual-frame-ia32.h       Tue Jan  6  
05:41:47 2009
@@ -351,7 +351,10 @@
    void Drop(int count);

    // Drop one element.
-  void Drop();
+  void Drop() { Drop(1); }
+
+  // Duplicate the top element of the frame.
+  void Dup() { LoadFrameSlotAt(elements_.length() - 1); }

    // Pop an element from the top of the expression stack.
    // Returns a Result, which may be a constant or a register.

Modified: branches/experimental/toiger/test/mjsunit/switch.js
==============================================================================
--- branches/experimental/toiger/test/mjsunit/switch.js (original)
+++ branches/experimental/toiger/test/mjsunit/switch.js Tue Jan  6 05:41:47  
2009
@@ -222,8 +222,8 @@
  assertEquals(190, f6(20), "largeSwitch.20");
  assertEquals(2016, f6(64), "largeSwitch.64");
  assertEquals(4032, f6(128), "largeSwitch.128");
-assertEquals(4222, f6(148), "largeSwitch.148");
-
+assertEquals(4222, f6(148), "largeSwitch.148");
+

  function f7(value) {
    switch (value) {
@@ -252,7 +252,7 @@
    case 11:
    case 12:
    case 13:
-  case 14:
+  case 14:
    case 15:  // Dummy fillers
    }
    return "default";
@@ -270,7 +270,7 @@

  function makeVeryLong(length) {
    var res = "function() {\n" +
-            "  var res = 0;\n" +
+            "  var res = 0;\n" +
              "  for (var i = 0; i <= " + length + "; i++) {\n" +
              "    switch(i) {\n";
    for (var i = 0; i < length; i++) {
@@ -286,4 +286,4 @@
  var verylong_size = 1000;
  var verylong = makeVeryLong(verylong_size);

-assertEquals(verylong_size * 2 + 1, verylong());
\ No newline at end of file
+assertEquals(verylong_size * 2 + 1, verylong());

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

Reply via email to