mirror of
https://github.com/corda/corda.git
synced 2025-06-01 07:00:54 +00:00
handle synchronized methods properly in JIT mode
This commit is contained in:
parent
96f3749c01
commit
5d65e7c220
2
makefile
2
makefile
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user