Reviewers: William Hesse, Description: Fix aliasing problem in inlined stores on x64 and ia32. The receiver and the value can share a register. We need to remove this aliasing before modifying the registers.
I haven't managed to generate a stand-alon test case for this yet. I'll do that as a separate change. This was found while loading Wave. Please review this at http://codereview.chromium.org/3039025/show SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge/ Affected files: M src/ia32/codegen-ia32.cc M src/x64/codegen-x64.cc Index: src/ia32/codegen-ia32.cc =================================================================== --- src/ia32/codegen-ia32.cc (revision 5121) +++ src/ia32/codegen-ia32.cc (working copy) @@ -8917,16 +8917,21 @@ // Allocate scratch register for write barrier. Result scratch = allocator()->Allocate(); - ASSERT(scratch.is_valid() && - result.is_valid() && - receiver.is_valid() && - value.is_valid()); + ASSERT(scratch.is_valid()); // The write barrier clobbers all input registers, so spill the // receiver and the value. frame_->Spill(receiver.reg()); frame_->Spill(value.reg()); + // If the receiver and the value share a register allocate a new + // register for the receiver. + if (receiver.reg().is(value.reg())) { + receiver = allocator()->Allocate(); + ASSERT(receiver.is_valid()); + __ mov(receiver.reg(), Operand(value.reg())); + } + // Update the write barrier. To save instructions in the inlined // version we do not filter smis. Label skip_write_barrier; Index: src/x64/codegen-x64.cc =================================================================== --- src/x64/codegen-x64.cc (revision 5121) +++ src/x64/codegen-x64.cc (working copy) @@ -8051,16 +8051,21 @@ // Allocate scratch register for write barrier. Result scratch = allocator()->Allocate(); - ASSERT(scratch.is_valid() && - result.is_valid() && - receiver.is_valid() && - value.is_valid()); + ASSERT(scratch.is_valid()); // The write barrier clobbers all input registers, so spill the // receiver and the value. frame_->Spill(receiver.reg()); frame_->Spill(value.reg()); + // If the receiver and the value share a register allocate a new + // register for the receiver. + if (receiver.reg().is(value.reg())) { + receiver = allocator()->Allocate(); + ASSERT(receiver.is_valid()); + __ movq(receiver.reg(), value.reg()); + } + // Update the write barrier. To save instructions in the inlined // version we do not filter smis. Label skip_write_barrier; -- v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev
