Reviewers: danno,

Description:
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.

[email protected]


Please review this at https://chromiumcodereview.appspot.com/10868032/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/x64/lithium-codegen-x64.cc
  M test/mjsunit/compiler/uint32.js


Index: src/x64/lithium-codegen-x64.cc
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index d549054bccea26b7b82041c7989a88c762ad45db..9d2b6aafc177510105ea278f6a64c9d0930e7460 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -4075,7 +4075,10 @@ void LCodeGen::DoDeferredNumberTagU(LNumberTagU* instr) {
   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 @@ void LCodeGen::DoDeferredNumberTagU(LNumberTagU* instr) {
   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);
 }

Index: test/mjsunit/compiler/uint32.js
diff --git a/test/mjsunit/compiler/uint32.js b/test/mjsunit/compiler/uint32.js index 4237207c3645e45c2e5f5bb43b5999fe1d13b08f..2735dec01fe95d49d8936cecf9d9a76478af4d48 100644
--- a/test/mjsunit/compiler/uint32.js
+++ b/test/mjsunit/compiler/uint32.js
@@ -44,7 +44,10 @@ assertEquals(K1, ChangeI2T(uint32_array, 0));
 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


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

Reply via email to