mirror of
https://github.com/corda/corda.git
synced 2025-04-18 16:18:12 +00:00
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:
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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user