Fix unary sub IC heap number code on x64: an untagged double was pushed on the stack...
authorwhesse@chromium.org <whesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 2 May 2011 12:55:44 +0000 (12:55 +0000)
committerwhesse@chromium.org <whesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 2 May 2011 12:55:44 +0000 (12:55 +0000)
BUG=1352
TEST=mjsunit/math-abs

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7742 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/ia32/code-stubs-ia32.cc
src/x64/code-stubs-x64.cc

index b8cad4b..777924b 100644 (file)
@@ -710,9 +710,8 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberCodeSub(MacroAssembler* masm,
   __ j(not_equal, slow);
 
   if (mode_ == UNARY_OVERWRITE) {
-    __ mov(edx, FieldOperand(eax, HeapNumber::kExponentOffset));
-    __ xor_(edx, HeapNumber::kSignMask);  // Flip sign.
-    __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), edx);
+    __ xor_(FieldOperand(eax, HeapNumber::kExponentOffset),
+            Immediate(HeapNumber::kSignMask));  // Flip sign.
   } else {
     __ mov(edx, Operand(eax));
     // edx: operand
index 2ebfa11..ec1c185 100644 (file)
@@ -535,29 +535,33 @@ void TypeRecordingUnaryOpStub::GenerateHeapNumberCodeSub(MacroAssembler* masm,
                  Heap::kHeapNumberMapRootIndex);
   __ j(not_equal, slow);
 
-  // Operand is a float, negate its value by flipping sign bit.
-  __ movq(rdx, FieldOperand(rax, HeapNumber::kValueOffset));
-  __ Set(kScratchRegister, 0x01);
-  __ shl(kScratchRegister, Immediate(63));
-  __ xor_(rdx, kScratchRegister);  // Flip sign.
-  // rdx is value to store.
+  // Operand is a float, negate its value by flipping the sign bit.
   if (mode_ == UNARY_OVERWRITE) {
-    __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rdx);
+    __ Set(kScratchRegister, 0x01);
+    __ shl(kScratchRegister, Immediate(63));
+    __ xor_(FieldOperand(rax, HeapNumber::kValueOffset), kScratchRegister);
   } else {
+    // Allocate a heap number before calculating the answer,
+    // so we don't have an untagged double around during GC.
     Label slow_allocate_heapnumber, heapnumber_allocated;
     __ AllocateHeapNumber(rcx, rbx, &slow_allocate_heapnumber);
     __ jmp(&heapnumber_allocated);
 
     __ bind(&slow_allocate_heapnumber);
     __ EnterInternalFrame();
-    __ push(rdx);
+    __ push(rax);
     __ CallRuntime(Runtime::kNumberAlloc, 0);
     __ movq(rcx, rax);
-    __ pop(rdx);
+    __ pop(rax);
     __ LeaveInternalFrame();
-
     __ bind(&heapnumber_allocated);
     // rcx: allocated 'empty' number
+
+    // Copy the double value to the new heap number, flipping the sign.
+    __ movq(rdx, FieldOperand(rax, HeapNumber::kValueOffset));
+    __ Set(kScratchRegister, 0x01);
+    __ shl(kScratchRegister, Immediate(63));
+    __ xor_(rdx, kScratchRegister);  // Flip sign.
     __ movq(FieldOperand(rcx, HeapNumber::kValueOffset), rdx);
     __ movq(rax, rcx);
   }