From: erik.corry@gmail.com Date: Wed, 25 May 2011 10:35:00 +0000 (+0000) Subject: Fix GC-unsafe corner case in bit-not on ARM X-Git-Tag: upstream/4.7.83~19311 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fbf76fc86a378d5e340fc416c76516f023537253;p=platform%2Fupstream%2Fv8.git Fix GC-unsafe corner case in bit-not on ARM Review URL: http://codereview.chromium.org/6987009 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8055 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index 3aa31dc..334f55f 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -1903,6 +1903,8 @@ void UnaryOpStub::GenerateHeapNumberCodeSub(MacroAssembler* masm, void UnaryOpStub::GenerateHeapNumberCodeBitNot( MacroAssembler* masm, Label* slow) { + Label impossible; + EmitCheckForHeapNumber(masm, r0, r1, r6, slow); // Convert the heap number is r0 to an untagged integer in r1. __ ConvertToInt32(r0, r1, r2, r3, d0, slow); @@ -1921,17 +1923,27 @@ void UnaryOpStub::GenerateHeapNumberCodeBitNot( __ bind(&try_float); if (mode_ == UNARY_NO_OVERWRITE) { Label slow_allocate_heapnumber, heapnumber_allocated; - __ AllocateHeapNumber(r0, r2, r3, r6, &slow_allocate_heapnumber); + // Allocate a new heap number without zapping r0, which we need if it fails. + __ AllocateHeapNumber(r2, r3, r4, r6, &slow_allocate_heapnumber); __ jmp(&heapnumber_allocated); __ bind(&slow_allocate_heapnumber); __ EnterInternalFrame(); - __ push(r1); - __ CallRuntime(Runtime::kNumberAlloc, 0); - __ pop(r1); + __ push(r0); // Push the heap number, not the untagged int32. + __ CallRuntime(Runtime::kNumberAlloc, 0); + __ mov(r2, r0); // Move the new heap number into r2. + // Get the heap number into r0, now that the new heap number is in r2. + __ pop(r0); __ LeaveInternalFrame(); + // Convert the heap number in r0 to an untagged integer in r1. + // This can't go slow-case because it's the same number we already + // converted once again. + __ ConvertToInt32(r0, r1, r3, r4, d0, &impossible); + __ mvn(r1, Operand(r1)); + __ bind(&heapnumber_allocated); + __ mov(r0, r2); // Move newly allocated heap number to r0. } if (CpuFeatures::IsSupported(VFP3)) { @@ -1948,6 +1960,11 @@ void UnaryOpStub::GenerateHeapNumberCodeBitNot( WriteInt32ToHeapNumberStub stub(r1, r0, r2); __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET); } + + __ bind(&impossible); + if (FLAG_debug_code) { + __ stop("Incorrect assumption in bit-not stub"); + } } diff --git a/test/mjsunit/binary-op-newspace.js b/test/mjsunit/binary-op-newspace.js index 032284c..e3341c4 100644 --- a/test/mjsunit/binary-op-newspace.js +++ b/test/mjsunit/binary-op-newspace.js @@ -25,8 +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: --max-new-space-size=256 - +// Flags: --max-new-space-size=256 --noopt // Check that a mod where the stub code hits a failure in heap number // allocation still works. diff --git a/test/mjsunit/bit-not.js b/test/mjsunit/bit-not.js index 85eccc4..d0316a7 100644 --- a/test/mjsunit/bit-not.js +++ b/test/mjsunit/bit-not.js @@ -68,6 +68,8 @@ testBitNot("-9.4", "string-9.4"); // the fast path and just use the slow path instead. function TryToGC() { var x = 0x40000000; + // Put in an eval to foil Crankshaft. + eval(""); for (var i = 0; i < 1000000; i++) { assertEquals(~0x40000000, ~x); }