mirror of
https://github.com/corda/corda.git
synced 2025-03-17 17:45:17 +00:00
ensure reads and writes of volatile 64-bit fields are atomic
This commit is contained in:
parent
2ca8132d97
commit
8410e1d683
@ -2631,6 +2631,20 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
}
|
||||
}
|
||||
|
||||
Compiler::Operand* fieldOperand = 0;
|
||||
|
||||
if ((fieldFlags(t, field) & ACC_VOLATILE)
|
||||
and BytesPerWord == 4
|
||||
and (fieldCode(t, field) == DoubleField
|
||||
or fieldCode(t, field) == LongField))
|
||||
{
|
||||
fieldOperand = frame->append(field);
|
||||
|
||||
c->call
|
||||
(c->constant(getThunk(t, acquireMonitorForObjectThunk)),
|
||||
0, frame->trace(0, false), 0, 2, c->thread(), fieldOperand);
|
||||
}
|
||||
|
||||
switch (fieldCode(t, field)) {
|
||||
case ByteField:
|
||||
case BooleanField:
|
||||
@ -2676,7 +2690,16 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
}
|
||||
|
||||
if (fieldFlags(t, field) & ACC_VOLATILE) {
|
||||
c->loadBarrier();
|
||||
if (BytesPerWord == 4
|
||||
and (fieldCode(t, field) == DoubleField
|
||||
or fieldCode(t, field) == LongField))
|
||||
{
|
||||
c->call
|
||||
(c->constant(getThunk(t, releaseMonitorForObjectThunk)),
|
||||
0, frame->trace(0, false), 0, 2, c->thread(), fieldOperand);
|
||||
} else {
|
||||
c->loadBarrier();
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -3416,15 +3439,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
case monitorenter: {
|
||||
c->call
|
||||
(c->constant(getThunk(t, acquireMonitorForObjectThunk)),
|
||||
0,
|
||||
frame->trace(0, false), 0, 2, c->thread(), frame->popObject());
|
||||
0, frame->trace(0, false), 0, 2, c->thread(), frame->popObject());
|
||||
} break;
|
||||
|
||||
case monitorexit: {
|
||||
c->call
|
||||
(c->constant(getThunk(t, releaseMonitorForObjectThunk)),
|
||||
0,
|
||||
frame->trace(0, false), 0, 2, c->thread(), frame->popObject());
|
||||
0, frame->trace(0, false), 0, 2, c->thread(), frame->popObject());
|
||||
} break;
|
||||
|
||||
case multianewarray: {
|
||||
@ -3565,8 +3586,21 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
table = frame->popObject();
|
||||
}
|
||||
|
||||
Compiler::Operand* fieldOperand = 0;
|
||||
|
||||
if (fieldFlags(t, field) & ACC_VOLATILE) {
|
||||
c->storeStoreBarrier();
|
||||
if (BytesPerWord == 4
|
||||
and (fieldCode(t, field) == DoubleField
|
||||
or fieldCode(t, field) == LongField))
|
||||
{
|
||||
fieldOperand = frame->append(field);
|
||||
|
||||
c->call
|
||||
(c->constant(getThunk(t, acquireMonitorForObjectThunk)),
|
||||
0, frame->trace(0, false), 0, 2, c->thread(), fieldOperand);
|
||||
} else {
|
||||
c->storeStoreBarrier();
|
||||
}
|
||||
}
|
||||
|
||||
switch (fieldCode(t, field)) {
|
||||
@ -3613,7 +3647,16 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
}
|
||||
|
||||
if (fieldFlags(t, field) & ACC_VOLATILE) {
|
||||
c->storeLoadBarrier();
|
||||
if (BytesPerWord == 4
|
||||
and (fieldCode(t, field) == DoubleField
|
||||
or fieldCode(t, field) == LongField))
|
||||
{
|
||||
c->call
|
||||
(c->constant(getThunk(t, releaseMonitorForObjectThunk)),
|
||||
0, frame->trace(0, false), 0, 2, c->thread(), fieldOperand);
|
||||
} else {
|
||||
c->storeLoadBarrier();
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
|
@ -1456,10 +1456,25 @@ interpret(Thread* t)
|
||||
|
||||
assert(t, (fieldFlags(t, field) & ACC_STATIC) == 0);
|
||||
|
||||
if (UNLIKELY((fieldFlags(t, field) & ACC_VOLATILE)
|
||||
and BytesPerWord == 4
|
||||
and (fieldCode(t, field) == DoubleField
|
||||
or fieldCode(t, field) == LongField)))
|
||||
{
|
||||
acquire(t, field);
|
||||
}
|
||||
|
||||
pushField(t, popObject(t), field);
|
||||
|
||||
if (fieldFlags(t, field) & ACC_VOLATILE) {
|
||||
loadMemoryBarrier();
|
||||
if (UNLIKELY(fieldFlags(t, field) & ACC_VOLATILE)) {
|
||||
if (BytesPerWord == 4
|
||||
and (fieldCode(t, field) == DoubleField
|
||||
or fieldCode(t, field) == LongField))
|
||||
{
|
||||
release(t, field);
|
||||
} else {
|
||||
loadMemoryBarrier();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
exception = makeNullPointerException(t);
|
||||
@ -1479,10 +1494,25 @@ interpret(Thread* t)
|
||||
|
||||
if (UNLIKELY(classInit(t, fieldClass(t, field), 3))) goto invoke;
|
||||
|
||||
if (UNLIKELY((fieldFlags(t, field) & ACC_VOLATILE)
|
||||
and BytesPerWord == 4
|
||||
and (fieldCode(t, field) == DoubleField
|
||||
or fieldCode(t, field) == LongField)))
|
||||
{
|
||||
acquire(t, field);
|
||||
}
|
||||
|
||||
pushField(t, classStaticTable(t, fieldClass(t, field)), field);
|
||||
|
||||
if (fieldFlags(t, field) & ACC_VOLATILE) {
|
||||
loadMemoryBarrier();
|
||||
if (UNLIKELY(fieldFlags(t, field) & ACC_VOLATILE)) {
|
||||
if (BytesPerWord == 4
|
||||
and (fieldCode(t, field) == DoubleField
|
||||
or fieldCode(t, field) == LongField))
|
||||
{
|
||||
release(t, field);
|
||||
} else {
|
||||
loadMemoryBarrier();
|
||||
}
|
||||
}
|
||||
} goto loop;
|
||||
|
||||
@ -2411,8 +2441,15 @@ interpret(Thread* t)
|
||||
object field = resolveField(t, codePool(t, code), index - 1);
|
||||
if (UNLIKELY(exception)) goto throw_;
|
||||
|
||||
if (fieldFlags(t, field) & ACC_VOLATILE) {
|
||||
storeStoreMemoryBarrier();
|
||||
if (UNLIKELY(fieldFlags(t, field) & ACC_VOLATILE)) {
|
||||
if (BytesPerWord == 4
|
||||
and (fieldCode(t, field) == DoubleField
|
||||
or fieldCode(t, field) == LongField))
|
||||
{
|
||||
acquire(t, field);
|
||||
} else {
|
||||
storeStoreMemoryBarrier();
|
||||
}
|
||||
}
|
||||
|
||||
assert(t, (fieldFlags(t, field) & ACC_STATIC) == 0);
|
||||
@ -2445,7 +2482,6 @@ interpret(Thread* t)
|
||||
}
|
||||
} else {
|
||||
exception = makeNullPointerException(t);
|
||||
goto throw_;
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -2457,7 +2493,6 @@ interpret(Thread* t)
|
||||
cast<int64_t>(o, fieldOffset(t, field)) = value;
|
||||
} else {
|
||||
exception = makeNullPointerException(t);
|
||||
goto throw_;
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -2468,15 +2503,25 @@ interpret(Thread* t)
|
||||
set(t, o, fieldOffset(t, field), value);
|
||||
} else {
|
||||
exception = makeNullPointerException(t);
|
||||
goto throw_;
|
||||
}
|
||||
} break;
|
||||
|
||||
default: abort(t);
|
||||
}
|
||||
|
||||
if (fieldFlags(t, field) & ACC_VOLATILE) {
|
||||
storeLoadMemoryBarrier();
|
||||
if (UNLIKELY(fieldFlags(t, field) & ACC_VOLATILE)) {
|
||||
if (BytesPerWord == 4
|
||||
and (fieldCode(t, field) == DoubleField
|
||||
or fieldCode(t, field) == LongField))
|
||||
{
|
||||
release(t, field);
|
||||
} else {
|
||||
storeLoadMemoryBarrier();
|
||||
}
|
||||
}
|
||||
|
||||
if (UNLIKELY(exception)) {
|
||||
goto throw_;
|
||||
}
|
||||
} goto loop;
|
||||
|
||||
@ -2486,8 +2531,15 @@ interpret(Thread* t)
|
||||
object field = resolveField(t, codePool(t, code), index - 1);
|
||||
if (UNLIKELY(exception)) goto throw_;
|
||||
|
||||
if (fieldFlags(t, field) & ACC_VOLATILE) {
|
||||
storeStoreMemoryBarrier();
|
||||
if (UNLIKELY(fieldFlags(t, field) & ACC_VOLATILE)) {
|
||||
if (BytesPerWord == 4
|
||||
and (fieldCode(t, field) == DoubleField
|
||||
or fieldCode(t, field) == LongField))
|
||||
{
|
||||
acquire(t, field);
|
||||
} else {
|
||||
storeStoreMemoryBarrier();
|
||||
}
|
||||
}
|
||||
|
||||
assert(t, fieldFlags(t, field) & ACC_STATIC);
|
||||
@ -2536,8 +2588,15 @@ interpret(Thread* t)
|
||||
default: abort(t);
|
||||
}
|
||||
|
||||
if (fieldFlags(t, field) & ACC_VOLATILE) {
|
||||
storeLoadMemoryBarrier();
|
||||
if (UNLIKELY(fieldFlags(t, field) & ACC_VOLATILE)) {
|
||||
if (BytesPerWord == 4
|
||||
and (fieldCode(t, field) == DoubleField
|
||||
or fieldCode(t, field) == LongField))
|
||||
{
|
||||
release(t, field);
|
||||
} else {
|
||||
storeLoadMemoryBarrier();
|
||||
}
|
||||
}
|
||||
} goto loop;
|
||||
|
||||
|
@ -3,6 +3,8 @@ public class Misc {
|
||||
private static int beta;
|
||||
private static byte byte1, byte2, byte3;
|
||||
|
||||
private static volatile int volatileStatic;
|
||||
|
||||
private final int NonStaticConstant = 42;
|
||||
|
||||
private int gamma;
|
||||
@ -10,6 +12,7 @@ public class Misc {
|
||||
private boolean boolean1;
|
||||
private boolean boolean2;
|
||||
private long time;
|
||||
private volatile int volatileMember;
|
||||
|
||||
public Misc() {
|
||||
expect(! boolean1);
|
||||
@ -132,13 +135,18 @@ public class Misc {
|
||||
int d = alpha;
|
||||
beta = 42;
|
||||
alpha = 43;
|
||||
volatileStatic = 55;
|
||||
int e = beta;
|
||||
int f = alpha;
|
||||
m.volatileMember = 23;
|
||||
m.gamma = 44;
|
||||
m.volatileMember = 27;
|
||||
|
||||
expect(beta == 42);
|
||||
expect(alpha == 43);
|
||||
expect(m.gamma == 44);
|
||||
expect(volatileStatic == 55);
|
||||
expect(m.volatileMember == 27);
|
||||
}
|
||||
|
||||
expect(zip() == 47);
|
||||
|
Loading…
x
Reference in New Issue
Block a user