Author: [email protected]
Date: Thu Jul  9 01:00:12 2009
New Revision: 2409

Modified:
    branches/bleeding_edge/src/x64/assembler-x64.cc
    branches/bleeding_edge/src/x64/assembler-x64.h
    branches/bleeding_edge/src/x64/codegen-x64.cc
    branches/bleeding_edge/test/mjsunit/apply.js
    branches/bleeding_edge/test/mjsunit/array-reduce.js
    branches/bleeding_edge/test/mjsunit/big-array-literal.js
    branches/bleeding_edge/test/mjsunit/regress/regress-244.js

Log:
X64: Fix bug in left-shift.
Also changed a few other places that looked suspicious in the same way.
Added more info to failing test case and rewrote incorrect uses of  
mjsunit "fail" function.

Review URL: http://codereview.chromium.org/155279


Modified: branches/bleeding_edge/src/x64/assembler-x64.cc
==============================================================================
--- branches/bleeding_edge/src/x64/assembler-x64.cc     (original)
+++ branches/bleeding_edge/src/x64/assembler-x64.cc     Thu Jul  9 01:00:12 2009
@@ -579,6 +579,23 @@
  }


+void Assembler::shift_32(Register dst, Immediate shift_amount, int  
subcode) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  ASSERT(is_uint6(shift_amount.value_));  // illegal shift count
+  if (shift_amount.value_ == 1) {
+    emit_optional_rex_32(dst);
+    emit(0xD1);
+    emit_modrm(subcode, dst);
+  } else {
+    emit_optional_rex_32(dst);
+    emit(0xC1);
+    emit_modrm(subcode, dst);
+    emit(shift_amount.value_);
+  }
+}
+
+
  void Assembler::bt(const Operand& dst, Register src) {
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;

Modified: branches/bleeding_edge/src/x64/assembler-x64.h
==============================================================================
--- branches/bleeding_edge/src/x64/assembler-x64.h      (original)
+++ branches/bleeding_edge/src/x64/assembler-x64.h      Thu Jul  9 01:00:12 2009
@@ -690,11 +690,22 @@
      shift(dst, shift_amount, 0x7);
    }

+  // Shifts dst right, duplicating sign bit, by shift_amount bits.
+  // Shifting by 1 is handled efficiently.
+  void sarl(Register dst, Immediate shift_amount) {
+    shift_32(dst, shift_amount, 0x7);
+  }
+
    // Shifts dst right, duplicating sign bit, by cl % 64 bits.
    void sar(Register dst) {
      shift(dst, 0x7);
    }

+  // Shifts dst right, duplicating sign bit, by cl % 64 bits.
+  void sarl(Register dst) {
+    shift_32(dst, 0x7);
+  }
+
    void shl(Register dst, Immediate shift_amount) {
      shift(dst, shift_amount, 0x4);
    }
@@ -1123,6 +1134,7 @@
                                   Immediate src);
    // Emit machine code for a shift operation.
    void shift(Register dst, Immediate shift_amount, int subcode);
+  void shift_32(Register dst, Immediate shift_amount, int subcode);
    // Shift dst by cl % 64 bits.
    void shift(Register dst, int subcode);
    void shift_32(Register dst, int subcode);

Modified: branches/bleeding_edge/src/x64/codegen-x64.cc
==============================================================================
--- branches/bleeding_edge/src/x64/codegen-x64.cc       (original)
+++ branches/bleeding_edge/src/x64/codegen-x64.cc       Thu Jul  9 01:00:12 2009
@@ -1292,7 +1292,7 @@
    node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);

    __ movq(rax, frame_->ElementAt(0));  // load the current count
-  __ cmpq(rax, frame_->ElementAt(1));  // compare to the array length
+  __ cmpl(rax, frame_->ElementAt(1));  // compare to the array length
    node->break_target()->Branch(above_equal);

    // Get the i'th entry of the array.
@@ -5109,7 +5109,7 @@
          Label result_ok;
          __ shl(answer.reg());
          // Check that the *signed* result fits in a smi.
-        __ cmpq(answer.reg(), Immediate(0xc0000000));
+        __ cmpl(answer.reg(), Immediate(0xc0000000));
          __ j(positive, &result_ok);
          ASSERT(kSmiTag == 0);
          __ shl(rcx, Immediate(kSmiTagSize));
@@ -6675,12 +6675,12 @@
        // Move the second operand into register ecx.
        __ movq(rcx, rbx);
        // Remove tags from operands (but keep sign).
-      __ sar(rax, Immediate(kSmiTagSize));
-      __ sar(rcx, Immediate(kSmiTagSize));
+      __ sarl(rax, Immediate(kSmiTagSize));
+      __ sarl(rcx, Immediate(kSmiTagSize));
        // Perform the operation.
        switch (op_) {
          case Token::SAR:
-          __ sar(rax);
+          __ sarl(rax);
            // No checks of result necessary
            break;
          case Token::SHR:
@@ -6691,19 +6691,17 @@
            // - 0x40000000: this number would convert to negative when
            // Smi tagging these two cases can only happen with shifts
            // by 0 or 1 when handed a valid smi.
-          __ testq(rax, Immediate(0xc0000000));
+          __ testl(rax, Immediate(0xc0000000));
            __ j(not_zero, slow);
            break;
          case Token::SHL:
            __ shll(rax);
-          // TODO(Smi): Significant change if Smi changes.
            // Check that the *signed* result fits in a smi.
            // It does, if the 30th and 31st bits are equal, since then
            // shifting the SmiTag in at the bottom doesn't change the sign.
            ASSERT(kSmiTagSize == 1);
            __ cmpl(rax, Immediate(0xc0000000));
            __ j(sign, slow);
-          __ movsxlq(rax, rax);  // Extend new sign of eax into rax.
            break;
          default:
            UNREACHABLE();

Modified: branches/bleeding_edge/test/mjsunit/apply.js
==============================================================================
--- branches/bleeding_edge/test/mjsunit/apply.js        (original)
+++ branches/bleeding_edge/test/mjsunit/apply.js        Thu Jul  9 01:00:12 2009
@@ -38,12 +38,12 @@
  assertTrue(this === f0.apply(this), "2a");
  assertTrue(this === f0.apply(this, new Array(1)), "2b");
  assertTrue(this === f0.apply(this, new Array(2)), "2c");
-assertTrue(this === f0.apply(this, new Array(4242)), "2c");
+assertTrue(this === f0.apply(this, new Array(4242)), "2d");

  assertTrue(this === f0.apply(null), "3a");
  assertTrue(this === f0.apply(null, new Array(1)), "3b");
  assertTrue(this === f0.apply(null, new Array(2)), "3c");
-assertTrue(this === f0.apply(this, new Array(4242)), "2c");
+assertTrue(this === f0.apply(this, new Array(4242)), "3d");

  assertTrue(this === f0.apply(void 0), "4a");
  assertTrue(this === f0.apply(void 0, new Array(1)), "4b");
@@ -51,26 +51,26 @@

  assertTrue(void 0 === f1.apply(), "1-1");

-assertTrue(void 0 === f1.apply(this), "2a");
-assertTrue(void 0 === f1.apply(this, new Array(1)), "2b");
-assertTrue(void 0 === f1.apply(this, new Array(2)), "2c");
-assertTrue(void 0 === f1.apply(this, new Array(4242)), "2c");
-assertTrue(42 === f1.apply(this, new Array(42, 43)), "2c");
-assertEquals("foo", f1.apply(this, new  
Array("foo", "bar", "baz", "boo")), "2c");
-
-assertTrue(void 0 === f1.apply(null), "3a");
-assertTrue(void 0 === f1.apply(null, new Array(1)), "3b");
-assertTrue(void 0 === f1.apply(null, new Array(2)), "3c");
-assertTrue(void 0 === f1.apply(null, new Array(4242)), "2c");
-assertTrue(42 === f1.apply(null, new Array(42, 43)), "2c");
-assertEquals("foo", f1.apply(null, new  
Array("foo", "bar", "baz", "boo")), "2c");
-
-assertTrue(void 0 === f1.apply(void 0), "4a");
-assertTrue(void 0 === f1.apply(void 0, new Array(1)), "4b");
-assertTrue(void 0 === f1.apply(void 0, new Array(2)), "4c");
-assertTrue(void 0 === f1.apply(void 0, new Array(4242)), "4c");
-assertTrue(42 === f1.apply(void 0, new Array(42, 43)), "2c");
-assertEquals("foo", f1.apply(void 0, new  
Array("foo", "bar", "baz", "boo")), "2c");
+assertTrue(void 0 === f1.apply(this), "5a");
+assertTrue(void 0 === f1.apply(this, new Array(1)), "5b");
+assertTrue(void 0 === f1.apply(this, new Array(2)), "5c");
+assertTrue(void 0 === f1.apply(this, new Array(4242)), "5d");
+assertTrue(42 === f1.apply(this, new Array(42, 43)), "5e");
+assertEquals("foo", f1.apply(this, new  
Array("foo", "bar", "baz", "bo")), "5f");
+
+assertTrue(void 0 === f1.apply(null), "6a");
+assertTrue(void 0 === f1.apply(null, new Array(1)), "6b");
+assertTrue(void 0 === f1.apply(null, new Array(2)), "6c");
+assertTrue(void 0 === f1.apply(null, new Array(4242)), "6d");
+assertTrue(42 === f1.apply(null, new Array(42, 43)), "6e");
+assertEquals("foo", f1.apply(null, new  
Array("foo", "bar", "baz", "bo")), "6f");
+
+assertTrue(void 0 === f1.apply(void 0), "7a");
+assertTrue(void 0 === f1.apply(void 0, new Array(1)), "7b");
+assertTrue(void 0 === f1.apply(void 0, new Array(2)), "7c");
+assertTrue(void 0 === f1.apply(void 0, new Array(4242)), "7d");
+assertTrue(42 === f1.apply(void 0, new Array(42, 43)), "7e");
+assertEquals("foo", f1.apply(void 0, new  
Array("foo", "bar", "ba", "b")), "7f");

  var arr = new Array(42, "foo", "fish", "horse");
  function j(a, b, c, d, e, f, g, h, i, j, k, l) {
@@ -81,7 +81,7 @@
  var expect = "42foofishhorse";
  for (var i = 0; i < 8; i++)
    expect += "undefined";
-assertEquals(expect, j.apply(undefined, arr));
+assertEquals(expect, j.apply(undefined, arr), "apply to undefined");

  assertThrows("f0.apply(this, 1);");
  assertThrows("f0.apply(this, 1, 2);");
@@ -95,7 +95,7 @@
    return doo;
  }

-assertEquals("42foofishhorse", f.apply(this, arr));
+assertEquals("42foofishhorse", f.apply(this, arr), "apply to this");

  function s() {
    var doo = this;
@@ -105,7 +105,7 @@
    return doo;
  }

-assertEquals("bar42foofishhorse", s.apply("bar", arr));
+assertEquals("bar42foofishhorse", s.apply("bar", arr), "apply to string");

  function al() {
    assertEquals(345, this);
@@ -118,19 +118,24 @@
      a[j - 1] = 42;
      assertEquals(42 + j, al.apply(345, a));
    } catch (e) {
-    assertTrue(e.toString().indexOf("Function.prototype.apply") != -1);
+    assertTrue(e.toString().indexOf("Function.prototype.apply") != -1,
+              "exception does not contain Function.prototype.apply: " +
+                  e.toString());
      for (; j < 0x40000000; j <<= 1) {
        var caught = false;
        try {
          a = new Array(j);
          a[j - 1] = 42;
          al.apply(345, a);
-        assertEquals("Shouldn't get", "here");
+        assertUnreachable("Apply of arrray with length " + a.length +
+                          " should have thrown");
        } catch (e) {
-        assertTrue(e.toString().indexOf("Function.prototype.apply") != -1);
+        assertTrue(e.toString().indexOf("Function.prototype.apply") != -1,
+                   "exception does not contain Function.prototype.apply ["  
+
+                   "length = " + j + "]: " + e.toString());
          caught = true;
        }
-      assertTrue(caught);
+      assertTrue(caught, "exception not caught");
      }
      break;
    }
@@ -160,8 +165,8 @@
  var same_primes = Array.prototype.constructor.apply(Array, primes);

  for (var i = 0; i < primes.length; i++)
-  assertEquals(primes[i], same_primes[i]);
-assertEquals(primes.length, same_primes.length);
+  assertEquals(primes[i], same_primes[i], "prime" + primes[i]);
+assertEquals(primes.length, same_primes.length, "prime-length");


  Array.prototype["1"] = "sep";
@@ -170,15 +175,22 @@
  holey[0] = "mor";
  holey[2] = "er";

-assertEquals("morseper", String.prototype.concat.apply("", holey));
-assertEquals("morseper", String.prototype.concat.apply("", holey, 1));
-assertEquals("morseper", String.prototype.concat.apply("", holey, 1, 2));
-assertEquals("morseper", String.prototype.concat.apply("", holey, 1, 2,  
3));
-assertEquals("morseper", String.prototype.concat.apply("", holey, 1, 2, 3,  
4));
+assertEquals("morseper", String.prototype.concat.apply("", holey),
+             "moreseper0");
+assertEquals("morseper", String.prototype.concat.apply("", holey, 1),
+             "moreseper1");
+assertEquals("morseper", String.prototype.concat.apply("", holey, 1, 2),
+             "moreseper2");
+assertEquals("morseper", String.prototype.concat.apply("", holey, 1, 2, 3),
+             "morseper3");
+assertEquals("morseper", String.prototype.concat.apply("", holey, 1, 2, 3,  
4),
+             "morseper4");

  primes[0] = "";
  primes[1] = holey;
  assertThrows("String.prototype.concat.apply.apply('foo', primes)");
-assertEquals("morseper",  
String.prototype.concat.apply.apply(String.prototype.concat, primes));
+assertEquals("morseper",
+    String.prototype.concat.apply.apply(String.prototype.concat, primes),
+    "moreseper-prime");

  delete(Array.prototype["1"]);

Modified: branches/bleeding_edge/test/mjsunit/array-reduce.js
==============================================================================
--- branches/bleeding_edge/test/mjsunit/array-reduce.js (original)
+++ branches/bleeding_edge/test/mjsunit/array-reduce.js Thu Jul  9 01:00:12  
2009
@@ -413,7 +413,7 @@

  try {
    [1].reduce("not a function");
-  fail("Reduce callback not a function not throwing");
+  assertUnreachable("Reduce callback not a function not throwing");
  } catch (e) {
    assertTrue(e instanceof TypeError,
               "reduce callback not a function not throwing TypeError");
@@ -423,7 +423,7 @@

  try {
    [1].reduceRight("not a function");
-  fail("ReduceRight callback not a function not throwing");
+  assertUnreachable("ReduceRight callback not a function not throwing");
  } catch (e) {
    assertTrue(e instanceof TypeError,
               "reduceRight callback not a function not throwing TypeError");
@@ -434,7 +434,7 @@

  try {
    [].reduce(sum);
-  fail("Reduce no initial value not throwing");
+  assertUnreachable("Reduce no initial value not throwing");
  } catch (e) {
    assertTrue(e instanceof TypeError,
               "reduce no initial value not throwing TypeError");
@@ -444,7 +444,7 @@

  try {
    [].reduceRight(sum);
-  fail("ReduceRight no initial value not throwing");
+  assertUnreachable("ReduceRight no initial value not throwing");
  } catch (e) {
    assertTrue(e instanceof TypeError,
               "reduceRight no initial value not throwing TypeError");
@@ -455,7 +455,7 @@

  try {
    [,,,].reduce(sum);
-  fail("Reduce sparse no initial value not throwing");
+  assertUnreachable("Reduce sparse no initial value not throwing");
  } catch (e) {
    assertTrue(e instanceof TypeError,
               "reduce sparse no initial value not throwing TypeError");
@@ -465,7 +465,7 @@

  try {
    [,,,].reduceRight(sum);
-  fail("ReduceRight sparse no initial value not throwing");
+  assertUnreachable("ReduceRight sparse no initial value not throwing");
  } catch (e) {
    assertTrue(e instanceof TypeError,
               "reduceRight sparse no initial value not throwing TypeError");

Modified: branches/bleeding_edge/test/mjsunit/big-array-literal.js
==============================================================================
--- branches/bleeding_edge/test/mjsunit/big-array-literal.js    (original)
+++ branches/bleeding_edge/test/mjsunit/big-array-literal.js    Thu Jul  9  
01:00:12 2009
@@ -81,7 +81,7 @@
  }

  // The sizes to test.
-var sizes = [1, 2, 100, 200, 400];
+var sizes = [1, 2, 100, 200, 300];

  // Run the test.
  for (var i = 0; i < sizes.length; i++) {

Modified: branches/bleeding_edge/test/mjsunit/regress/regress-244.js
==============================================================================
--- branches/bleeding_edge/test/mjsunit/regress/regress-244.js  (original)
+++ branches/bleeding_edge/test/mjsunit/regress/regress-244.js  Thu Jul  9  
01:00:12 2009
@@ -57,7 +57,7 @@
      var threw = false;
      try {
        decodeURI(value);
-      fail(value);
+      assertUnreachable(value);
      } catch (e) {
        assertInstanceof(e, URIError);
      }

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

Reply via email to