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. Review URL: http://codereview.chromium.org/3039025 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5127 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
e8c0a459a9
commit
79e332010a
@ -8968,16 +8968,21 @@ Result CodeGenerator::EmitNamedStore(Handle<String> name, bool is_contextual) {
|
|||||||
|
|
||||||
// Allocate scratch register for write barrier.
|
// Allocate scratch register for write barrier.
|
||||||
Result scratch = allocator()->Allocate();
|
Result scratch = allocator()->Allocate();
|
||||||
ASSERT(scratch.is_valid() &&
|
ASSERT(scratch.is_valid());
|
||||||
result.is_valid() &&
|
|
||||||
receiver.is_valid() &&
|
|
||||||
value.is_valid());
|
|
||||||
|
|
||||||
// The write barrier clobbers all input registers, so spill the
|
// The write barrier clobbers all input registers, so spill the
|
||||||
// receiver and the value.
|
// receiver and the value.
|
||||||
frame_->Spill(receiver.reg());
|
frame_->Spill(receiver.reg());
|
||||||
frame_->Spill(value.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
|
// Update the write barrier. To save instructions in the inlined
|
||||||
// version we do not filter smis.
|
// version we do not filter smis.
|
||||||
Label skip_write_barrier;
|
Label skip_write_barrier;
|
||||||
|
@ -8103,16 +8103,21 @@ Result CodeGenerator::EmitNamedStore(Handle<String> name, bool is_contextual) {
|
|||||||
|
|
||||||
// Allocate scratch register for write barrier.
|
// Allocate scratch register for write barrier.
|
||||||
Result scratch = allocator()->Allocate();
|
Result scratch = allocator()->Allocate();
|
||||||
ASSERT(scratch.is_valid() &&
|
ASSERT(scratch.is_valid());
|
||||||
result.is_valid() &&
|
|
||||||
receiver.is_valid() &&
|
|
||||||
value.is_valid());
|
|
||||||
|
|
||||||
// The write barrier clobbers all input registers, so spill the
|
// The write barrier clobbers all input registers, so spill the
|
||||||
// receiver and the value.
|
// receiver and the value.
|
||||||
frame_->Spill(receiver.reg());
|
frame_->Spill(receiver.reg());
|
||||||
frame_->Spill(value.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
|
// Update the write barrier. To save instructions in the inlined
|
||||||
// version we do not filter smis.
|
// version we do not filter smis.
|
||||||
Label skip_write_barrier;
|
Label skip_write_barrier;
|
||||||
|
Loading…
Reference in New Issue
Block a user