mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +00:00
fix handling of volatile longs and doubles on PowerPC
We were miscompiling methods which contained getfield, getstatic, putfield, or putstatic instructions for volatile 64-bit primitives on 32-bit PowerPC due to not noticing that values in registers are clobbered across function calls. The solution is to create a separate Compiler::Operand instance for each object monitor reference before and after the function call to avoid confusing the compiler. To avoid duplicate entries in the constant pool, we add code look for and, if found, reuse any existing entry for the same constant.
This commit is contained in:
parent
2868413b51
commit
45476eb591
@ -1101,6 +1101,12 @@ class Frame {
|
||||
|
||||
return c->promiseConstant(p, Compiler::ObjectType);
|
||||
} else {
|
||||
for (PoolElement* e = context->objectPool; e; e = e->next) {
|
||||
if (o == e->target) {
|
||||
return c->address(e);
|
||||
}
|
||||
}
|
||||
|
||||
context->objectPool = new
|
||||
(context->zone.allocate(sizeof(PoolElement)))
|
||||
PoolElement(t, o, context->objectPool);
|
||||
@ -3555,21 +3561,17 @@ 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), Compiler::AddressType),
|
||||
0, frame->trace(0, 0), 0, Compiler::VoidType, 2,
|
||||
c->register_(t->arch->thread()),
|
||||
fieldOperand);
|
||||
frame->append(field));
|
||||
}
|
||||
|
||||
switch (fieldCode(t, field)) {
|
||||
@ -3652,7 +3654,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
Compiler::AddressType),
|
||||
0, frame->trace(0, 0), 0, Compiler::VoidType, 2,
|
||||
c->register_(t->arch->thread()),
|
||||
fieldOperand);
|
||||
frame->append(field));
|
||||
} else {
|
||||
c->loadBarrier();
|
||||
}
|
||||
@ -4571,21 +4573,17 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
table = frame->popObject();
|
||||
}
|
||||
|
||||
Compiler::Operand* fieldOperand = 0;
|
||||
|
||||
if (fieldFlags(t, field) & ACC_VOLATILE) {
|
||||
if (BytesPerWord == 4
|
||||
and (fieldCode(t, field) == DoubleField
|
||||
or fieldCode(t, field) == LongField))
|
||||
{
|
||||
fieldOperand = frame->append(field);
|
||||
|
||||
c->call
|
||||
(c->constant
|
||||
(getThunk(t, acquireMonitorForObjectThunk),
|
||||
Compiler::AddressType),
|
||||
0, frame->trace(0, 0), 0, Compiler::VoidType, 2,
|
||||
c->register_(t->arch->thread()), fieldOperand);
|
||||
c->register_(t->arch->thread()), frame->append(field));
|
||||
} else {
|
||||
c->storeStoreBarrier();
|
||||
}
|
||||
@ -4663,7 +4661,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
(getThunk(t, releaseMonitorForObjectThunk),
|
||||
Compiler::AddressType),
|
||||
0, frame->trace(0, 0), 0, Compiler::VoidType, 2,
|
||||
c->register_(t->arch->thread()), fieldOperand);
|
||||
c->register_(t->arch->thread()), frame->append(field));
|
||||
} else {
|
||||
c->storeLoadBarrier();
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ public class Misc {
|
||||
|
||||
private static volatile int volatileStatic;
|
||||
|
||||
private static volatile long volatileStaticLong;
|
||||
|
||||
private final int NonStaticConstant = 42;
|
||||
|
||||
private int gamma;
|
||||
@ -131,6 +133,7 @@ public class Misc {
|
||||
beta = 42;
|
||||
alpha = 43;
|
||||
volatileStatic = 55;
|
||||
volatileStaticLong = 9L;
|
||||
int e = beta;
|
||||
int f = alpha;
|
||||
m.volatileMember = 23;
|
||||
@ -141,6 +144,7 @@ public class Misc {
|
||||
expect(alpha == 43);
|
||||
expect(m.gamma == 44);
|
||||
expect(volatileStatic == 55);
|
||||
expect(volatileStaticLong == 9L);
|
||||
expect(m.volatileMember == 27);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user