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 classpath = classpath
test = test test = test
input = $(test-build)/Threads.class input = $(test-build)/Misc.class
build-cxx = g++ build-cxx = g++
build-cc = gcc 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 { class PoolElement {
public: public:
PoolElement(object value, Promise* address): PoolElement(object value, Promise* address):
@ -968,6 +975,17 @@ unwind(MyThread* t)
vmJump(compiled + exceptionHandlerIp(handler), base, stack, t); vmJump(compiled + exceptionHandlerIp(handler), base, stack, t);
} else { } 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; stack = static_cast<void**>(base) + 1;
base = *static_cast<void**>(base); base = *static_cast<void**>(base);
} }
@ -1366,6 +1384,41 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target)
pushReturnValue(t, frame, methodReturnCode(t, 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 void
compile(MyThread* t, Frame* initialFrame, unsigned ip) compile(MyThread* t, Frame* initialFrame, unsigned ip)
{ {
@ -1577,6 +1630,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
} break; } break;
case areturn: { case areturn: {
handleExit(t, frame);
Operand* result = frame->popObject(); Operand* result = frame->popObject();
returnW(c, result); returnW(c, result);
c->release(result); c->release(result);
@ -2426,6 +2480,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case ireturn: case ireturn:
case freturn: { case freturn: {
handleExit(t, frame);
Operand* a = frame->popInt(); Operand* a = frame->popInt();
c->return4(a); c->return4(a);
c->release(a); c->release(a);
@ -2711,6 +2766,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
case lreturn: case lreturn:
case dreturn: { case dreturn: {
handleExit(t, frame);
Operand* a = frame->popLong(); Operand* a = frame->popLong();
c->return8(a); c->return8(a);
c->release(a); c->release(a);
@ -3009,6 +3065,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip)
return; return;
case return_: case return_:
handleExit(t, frame);
c->epilogue(); c->epilogue();
c->ret(); c->ret();
return; return;
@ -3251,10 +3308,10 @@ finish(MyThread* t, Compiler* c, object method, Vector* objectPool,
if (false and if (false and
strcmp(reinterpret_cast<const char*> strcmp(reinterpret_cast<const char*>
(&byteArrayBody(t, className(t, methodClass(t, method)), 0)), (&byteArrayBody(t, className(t, methodClass(t, method)), 0)),
"org/eclipse/swt/internal/gtk/OS") == 0 and "Misc") == 0 and
strcmp(reinterpret_cast<const char*> strcmp(reinterpret_cast<const char*>
(&byteArrayBody(t, methodName(t, method), 0)), (&byteArrayBody(t, methodName(t, method), 0)),
"ascii") == 0) "syncStatic") == 0)
{ {
asm("int3"); asm("int3");
} }
@ -3292,6 +3349,8 @@ compile(MyThread* t, Compiler* c, object method)
uintptr_t map[Frame::mapSizeInWords(t, method)]; uintptr_t map[Frame::mapSizeInWords(t, method)];
Frame frame(t, c, method, map, &objectPool, &traceLog); Frame frame(t, c, method, map, &objectPool, &traceLog);
handleEntrance(t, &frame);
compile(t, &frame, 0); compile(t, &frame, 0);
if (UNLIKELY(t->exception)) return 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 void
visitParameters(MyThread* t, Heap::Visitor* v, void* base, object method) visitParameters(MyThread* t, Heap::Visitor* v, void* base, object method)
{ {

View File

@ -19,6 +19,20 @@ public class Misc {
if (! v) throw new RuntimeException(); 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) { public static void main(String[] args) {
boolean v = Boolean.valueOf("true"); boolean v = Boolean.valueOf("true");
@ -34,6 +48,14 @@ public class Misc {
m.bar(s); m.bar(s);
baz(s); baz(s);
m.sync();
syncStatic(false);
try {
syncStatic(true);
} catch (RuntimeException e) {
e.printStackTrace();
}
int d = alpha; int d = alpha;
beta = 42; beta = 42;
alpha = 43; alpha = 43;