Revision: 12373
Author:   [email protected]
Date:     Thu Aug 23 09:14:01 2012
Log: Fix DoDeferredNumberTagU to keep the value in xmm1 instead of xmm0 on x64.

xmm0 is not saved across runtime call on x64 because MacroAssembler::EnterExitFrameEpilogue preserves only allocatable XMM registers unlike on ia32 where it preserves all registers.

Cleanup handling of shifts: SHR can deoptimize only when its a shift by 0, all other shift never deoptimize.

Fix type inference for i-to-t change instruction. On X64 this ensures that write-barrier is generated correctly.

[email protected]

Review URL: https://chromiumcodereview.appspot.com/10868032
http://code.google.com/p/v8/source/detail?r=12373

Modified:
 /branches/bleeding_edge/src/arm/lithium-arm.cc
 /branches/bleeding_edge/src/hydrogen-instructions.cc
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/ia32/lithium-ia32.cc
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
 /branches/bleeding_edge/src/x64/lithium-x64.cc
 /branches/bleeding_edge/test/mjsunit/compiler/uint32.js

=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc      Wed Aug 22 08:44:17 2012
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc      Thu Aug 23 09:14:01 2012
@@ -713,15 +713,13 @@
     right = UseRegisterAtStart(right_value);
   }

+  // Shift operations can only deoptimize if we do a logical shift
+  // by 0 and the result cannot be truncated to int32.
   bool does_deopt = false;
-
-  if (FLAG_opt_safe_uint32_operations) {
-    does_deopt = !instr->CheckFlag(HInstruction::kUint32);
-  } else {
-    // Shift operations can only deoptimize if we do a logical shift
-    // by 0 and the result cannot be truncated to int32.
-    bool may_deopt = (op == Token::SHR && constant_value == 0);
-    if (may_deopt) {
+  if (op == Token::SHR && constant_value == 0) {
+    if (FLAG_opt_safe_uint32_operations) {
+      does_deopt = !instr->CheckFlag(HInstruction::kUint32);
+    } else {
       for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
         if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) {
           does_deopt = true;
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Wed Aug 22 08:44:17 2012 +++ /branches/bleeding_edge/src/hydrogen-instructions.cc Thu Aug 23 09:14:01 2012
@@ -1124,6 +1124,7 @@
   Range* input_range = value()->range();
   if (from().IsInteger32() &&
       to().IsTagged() &&
+      !value()->CheckFlag(HInstruction::kUint32) &&
       input_range != NULL && input_range->IsInSmiRange()) {
     set_type(HType::Smi());
   }
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Wed Aug 22 12:00:02 2012
+++ /branches/bleeding_edge/src/hydrogen.cc     Thu Aug 23 09:14:01 2012
@@ -8270,7 +8270,16 @@
     case Token::SHR:
       instr = HShr::NewHShr(zone(), context, left, right);
       if (FLAG_opt_safe_uint32_operations && instr->IsShr()) {
-        graph()->RecordUint32Instruction(instr);
+        bool can_be_shift_by_zero = true;
+        if (right->IsConstant()) {
+          HConstant* right_const = HConstant::cast(right);
+          if (right_const->HasInteger32Value() &&
+              (right_const->Integer32Value() & 0x1f) != 0) {
+            can_be_shift_by_zero = false;
+          }
+        }
+
+        if (can_be_shift_by_zero) graph()->RecordUint32Instruction(instr);
       }
       break;
     case Token::SHL:
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Wed Aug 22 08:44:17 2012 +++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Thu Aug 23 09:14:01 2012
@@ -738,15 +738,13 @@
     right = UseFixed(right_value, ecx);
   }

+  // Shift operations can only deoptimize if we do a logical shift by 0 and
+  // the result cannot be truncated to int32.
   bool does_deopt = false;
-  if (FLAG_opt_safe_uint32_operations) {
-    does_deopt = !instr->CheckFlag(HInstruction::kUint32);
-  } else {
- // Shift operations can only deoptimize if we do a logical shift by 0 and
-    // the result cannot be truncated to int32.
-    bool may_deopt = (op == Token::SHR && constant_value == 0 &&
-      !instr->CheckFlag(HInstruction::kUint32));
-    if (may_deopt) {
+  if (op == Token::SHR && constant_value == 0) {
+    if (FLAG_opt_safe_uint32_operations) {
+      does_deopt = !instr->CheckFlag(HInstruction::kUint32);
+    } else {
       for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
         if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) {
           does_deopt = true;
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Wed Aug 22 08:44:17 2012 +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Thu Aug 23 09:14:01 2012
@@ -4075,7 +4075,10 @@
   PushSafepointRegistersScope scope(this);

   Label done;
-  __ LoadUint32(xmm0, reg, xmm1);
+  // Load value into xmm1 which will be preserved across potential call to
+ // runtime (MacroAssembler::EnterExitFrameEpilogue preserves only allocatable
+  // XMM registers on x64).
+  __ LoadUint32(xmm1, reg, xmm0);

   if (FLAG_inline_new) {
     __ AllocateHeapNumber(reg, tmp, &slow);
@@ -4093,10 +4096,10 @@
   CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
   if (!reg.is(rax)) __ movq(reg, rax);

-  // Done. Put the value in xmm0 into the value of the allocated heap
+  // Done. Put the value in xmm1 into the value of the allocated heap
   // number.
   __ bind(&done);
-  __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), xmm0);
+  __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), xmm1);
   __ StoreToSafepointRegisterSlot(reg, reg);
 }

=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc      Wed Aug 22 08:44:17 2012
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc      Thu Aug 23 09:14:01 2012
@@ -721,11 +721,10 @@
   // Shift operations can only deoptimize if we do a logical shift by 0 and
   // the result cannot be truncated to int32.
   bool does_deopt = false;
-  if (FLAG_opt_safe_uint32_operations) {
-    does_deopt = !instr->CheckFlag(HInstruction::kUint32);
-  } else {
-    bool may_deopt = (op == Token::SHR && constant_value == 0);
-    if (may_deopt) {
+  if (op == Token::SHR && constant_value == 0) {
+    if (FLAG_opt_safe_uint32_operations) {
+      does_deopt = !instr->CheckFlag(HInstruction::kUint32);
+    } else {
       for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
         if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) {
           does_deopt = true;
=======================================
--- /branches/bleeding_edge/test/mjsunit/compiler/uint32.js Wed Aug 22 08:44:17 2012 +++ /branches/bleeding_edge/test/mjsunit/compiler/uint32.js Thu Aug 23 09:14:01 2012
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-// Flags: --allow-natives-syntax
+// Flags: --allow-natives-syntax --expose-gc

 // Test uint32 handing in optimized frames.

@@ -44,7 +44,10 @@
 assertEquals(K2, ChangeI2T(uint32_array, 1));
 %OptimizeFunctionOnNextCall(ChangeI2T);
 assertEquals(K1, ChangeI2T(uint32_array, 0));
-assertEquals(K2, ChangeI2T(uint32_array, 1));
+// Loop to force inline allocation failure and a call into runtime.
+for (var i = 0; i < 80000; i++) {
+  assertEquals(K2, ChangeI2T(uint32_array, 1));
+}

 function SideEffect() {
   with ({}) { }  // not inlinable
@@ -148,3 +151,23 @@
 assertEquals(2, PhiOfPhiUnsafe(1));
 %OptimizeFunctionOnNextCall(PhiOfPhiUnsafe);
 assertEquals(2 * K3, PhiOfPhiUnsafe(K3));
+
+var old_array = new Array(1000);
+
+for (var i = 0; i < old_array.length; i++) old_array[i] = null;
+
+// Force promotion.
+gc();
+gc();
+
+function FillOldArrayWithHeapNumbers(N) {
+  for (var i = 0; i < N; i++) {
+    old_array[i] = uint32_array[1];
+  }
+}
+
+FillOldArrayWithHeapNumbers(1);
+FillOldArrayWithHeapNumbers(1);
+%OptimizeFunctionOnNextCall(FillOldArrayWithHeapNumbers);
+FillOldArrayWithHeapNumbers(old_array.length);
+gc();

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

Reply via email to