From: whesse@chromium.org Date: Mon, 2 May 2011 12:55:44 +0000 (+0000) Subject: Fix unary sub IC heap number code on x64: an untagged double was pushed on the stack... X-Git-Tag: upstream/4.7.83~19527 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=014e42a81fcc9c96b9008c6b05a4df33944d6ba4;p=platform%2Fupstream%2Fv8.git Fix unary sub IC heap number code on x64: an untagged double was pushed on the stack and GCd. 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 --- diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index b8cad4b..777924b 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -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 diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index 2ebfa11..ec1c185 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -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); }