handle synchronized methods properly in JIT mode

This commit is contained in:
Joel Dice 2007-12-27 17:02:05 -07:00
parent 96f3749c01
commit 5d65e7c220
3 changed files with 84 additions and 10 deletions

View File

@ -28,7 +28,7 @@ src = src
classpath = classpath
test = test
input = $(test-build)/Threads.class
input = $(test-build)/Misc.class
build-cxx = g++
build-cc = gcc

View File

@ -248,6 +248,13 @@ localOffset(MyThread* t, int v, object method)
}
}
inline object*
localObject(MyThread* t, void* base, object method, unsigned index)
{
return reinterpret_cast<object*>
(static_cast<uint8_t*>(base) + localOffset(t, index, method));
}
class PoolElement {
public:
PoolElement(object value, Promise* address):
@ -968,6 +975,17 @@ unwind(MyThread* t)
vmJump(compiled + exceptionHandlerIp(handler), base, stack, t);
} else {
if (methodFlags(t, method) & ACC_SYNCHRONIZED) {
object lock;
if (methodFlags(t, method) & ACC_STATIC) {
lock = methodClass(t, method);
} else {
lock = *localObject(t, base, method, 0);
}
release(t, lock);
}
stack = static_cast<void**>(base) + 1;
base = *static_cast<void**>(base);
}
@ -1366,6 +1384,41 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target)
pushReturnValue(t, frame, methodReturnCode(t, target));
}
void
handleMonitorEvent(MyThread* t, Frame* frame, intptr_t function)
{
Compiler* c = frame->c;
object method = frame->method;
if (methodFlags(t, method) & ACC_SYNCHRONIZED) {
Operand* lock;
if (methodFlags(t, method) & ACC_STATIC) {
lock = frame->append(methodClass(t, method));
} else {
lock = c->memory(c->base(), localOffset(t, 0, method));
}
Promise* returnAddress = c->indirectCall
(c->constant(function), 2, c->thread(), lock);
frame->trace(returnAddress, 0, false);
}
}
void
handleEntrance(MyThread* t, Frame* frame)
{
handleMonitorEvent
(t, frame, reinterpret_cast<intptr_t>(acquireMonitorForObject));
}
void
handleExit(MyThread* t, Frame* frame)
{
handleMonitorEvent
(t, frame, reinterpret_cast<intptr_t>(releaseMonitorForObject));
}
void
compile(MyThread* t, Frame* initialFrame, unsigned ip)
{
@ -1577,6 +1630,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
} break;
case areturn: {
handleExit(t, frame);
Operand* result = frame->popObject();
returnW(c, result);
c->release(result);
@ -2426,6 +2480,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case ireturn:
case freturn: {
handleExit(t, frame);
Operand* a = frame->popInt();
c->return4(a);
c->release(a);
@ -2711,6 +2766,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case lreturn:
case dreturn: {
handleExit(t, frame);
Operand* a = frame->popLong();
c->return8(a);
c->release(a);
@ -3009,6 +3065,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
return;
case return_:
handleExit(t, frame);
c->epilogue();
c->ret();
return;
@ -3251,10 +3308,10 @@ finish(MyThread* t, Compiler* c, object method, Vector* objectPool,
if (false and
strcmp(reinterpret_cast<const char*>
(&byteArrayBody(t, className(t, methodClass(t, method)), 0)),
"org/eclipse/swt/internal/gtk/OS") == 0 and
"Misc") == 0 and
strcmp(reinterpret_cast<const char*>
(&byteArrayBody(t, methodName(t, method), 0)),
"ascii") == 0)
"syncStatic") == 0)
{
asm("int3");
}
@ -3292,6 +3349,8 @@ compile(MyThread* t, Compiler* c, object method)
uintptr_t map[Frame::mapSizeInWords(t, method)];
Frame frame(t, c, method, map, &objectPool, &traceLog);
handleEntrance(t, &frame);
compile(t, &frame, 0);
if (UNLIKELY(t->exception)) return 0;
@ -3525,13 +3584,6 @@ invokeNative(MyThread* t)
}
}
inline object*
localObject(MyThread* t, void* base, object method, unsigned index)
{
return reinterpret_cast<object*>
(static_cast<uint8_t*>(base) + localOffset(t, index, method));
}
void
visitParameters(MyThread* t, Heap::Visitor* v, void* base, object method)
{

View File

@ -19,6 +19,20 @@ public class Misc {
if (! v) throw new RuntimeException();
}
private synchronized byte sync() {
byte[] array = new byte[123];
return array[42];
}
private static synchronized byte syncStatic(boolean throw_) {
byte[] array = new byte[123];
if (throw_) {
throw new RuntimeException();
} else {
return array[42];
}
}
public static void main(String[] args) {
boolean v = Boolean.valueOf("true");
@ -34,6 +48,14 @@ public class Misc {
m.bar(s);
baz(s);
m.sync();
syncStatic(false);
try {
syncStatic(true);
} catch (RuntimeException e) {
e.printStackTrace();
}
int d = alpha;
beta = 42;
alpha = 43;