From 45476eb591d927dbd4afde7a4d29e031139523ad Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 27 Jan 2010 17:46:04 -0700 Subject: [PATCH] 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. --- src/compile.cpp | 22 ++++++++++------------ test/Misc.java | 4 ++++ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/compile.cpp b/src/compile.cpp index 11bf8fcfcc..00fa33aa15 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -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(); } diff --git a/test/Misc.java b/test/Misc.java index 8795c9007b..5542ce5cfd 100644 --- a/test/Misc.java +++ b/test/Misc.java @@ -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); }