mirror of
https://github.com/corda/corda.git
synced 2025-06-19 15:43:52 +00:00
handle synchronized methods properly in JIT mode
This commit is contained in:
2
makefile
2
makefile
@ -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
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
Reference in New Issue
Block a user