fix miscompilation of 64-bit volatile field reads and writes on x86_32

We were generating code which clobbered the data we were putting into
64-bit volatile fields (and potentially also clobbering the target or
source object in the case of non-static fields) due to misplaced
synchronization code.  Reordering this code ensures that both the data
and the target or source survive across calls to synchronization
helper functions.
This commit is contained in:
Joel Dice 2010-03-01 18:24:25 -07:00
parent fdf9c5087b
commit 3e5b2cbc7b

@ -3542,6 +3542,19 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
object field = resolveField(t, context->method, index - 1);
if (UNLIKELY(t->exception)) return;
if ((fieldFlags(t, field) & ACC_VOLATILE)
and BytesPerWord == 4
and (fieldCode(t, field) == DoubleField
or fieldCode(t, field) == LongField))
{
c->call
(c->constant
(getThunk(t, acquireMonitorForObjectThunk), Compiler::AddressType),
0, frame->trace(0, 0), 0, Compiler::VoidType, 2,
c->register_(t->arch->thread()),
frame->append(field));
}
Compiler::Operand* table;
if (instruction == getstatic) {
@ -3572,19 +3585,6 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
}
}
if ((fieldFlags(t, field) & ACC_VOLATILE)
and BytesPerWord == 4
and (fieldCode(t, field) == DoubleField
or fieldCode(t, field) == LongField))
{
c->call
(c->constant
(getThunk(t, acquireMonitorForObjectThunk), Compiler::AddressType),
0, frame->trace(0, 0), 0, Compiler::VoidType, 2,
c->register_(t->arch->thread()),
frame->append(field));
}
switch (fieldCode(t, field)) {
case ByteField:
case BooleanField:
@ -4553,6 +4553,22 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
}
}
if (fieldFlags(t, field) & ACC_VOLATILE) {
if (BytesPerWord == 4
and (fieldCode(t, field) == DoubleField
or fieldCode(t, field) == LongField))
{
c->call
(c->constant
(getThunk(t, acquireMonitorForObjectThunk),
Compiler::AddressType),
0, frame->trace(0, 0), 0, Compiler::VoidType, 2,
c->register_(t->arch->thread()), frame->append(field));
} else {
c->storeStoreBarrier();
}
}
Compiler::Operand* value;
switch (fieldCode(t, field)) {
case ByteField:
@ -4584,22 +4600,6 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
table = frame->popObject();
}
if (fieldFlags(t, field) & ACC_VOLATILE) {
if (BytesPerWord == 4
and (fieldCode(t, field) == DoubleField
or fieldCode(t, field) == LongField))
{
c->call
(c->constant
(getThunk(t, acquireMonitorForObjectThunk),
Compiler::AddressType),
0, frame->trace(0, 0), 0, Compiler::VoidType, 2,
c->register_(t->arch->thread()), frame->append(field));
} else {
c->storeStoreBarrier();
}
}
switch (fieldCode(t, field)) {
case ByteField:
case BooleanField: