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