diff --git a/src/compile.cpp b/src/compile.cpp index 286d64cdec..6cce909980 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -970,7 +970,7 @@ enum Thunk { #undef THUNK }; -const unsigned ThunkCount = gcIfNecessaryThunk + 1; +const unsigned ThunkCount = idleIfNecessaryThunk + 1; intptr_t getThunk(MyThread* t, Thunk thunk); @@ -3298,6 +3298,11 @@ gcIfNecessary(MyThread* t) } } +void idleIfNecessary(MyThread* t) +{ + ENTER(t, Thread::IdleState); +} + unsigned resultSize(MyThread* t, unsigned code) { @@ -3413,6 +3418,16 @@ useLongJump(MyThread* t, uintptr_t target) or (target < start && (end - target) > reach); } +void compileSafePoint(MyThread* t, Compiler* c, Frame* frame) { + c->call + (c->constant(getThunk(t, idleIfNecessaryThunk), Compiler::AddressType), + 0, + frame->trace(0, 0), + 0, + Compiler::VoidType, + 1, c->register_(t->arch->thread())); +} + Compiler::Operand* compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall, bool useThunk, unsigned rSize, avian::codegen::Promise* addressPromise) @@ -4951,6 +4966,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp, uint32_t newIp = (ip - 3) + offset; assert(t, newIp < codeLength(t, code)); + if(newIp <= ip) { + compileSafePoint(t, c, frame); + } + c->jmp(frame->machineIp(newIp)); ip = newIp; } break; @@ -4960,6 +4979,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp, uint32_t newIp = (ip - 5) + offset; assert(t, newIp < codeLength(t, code)); + if(newIp <= ip) { + compileSafePoint(t, c, frame); + } + c->jmp(frame->machineIp(newIp)); ip = newIp; } break; @@ -5048,6 +5071,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp, uint32_t offset = codeReadInt16(t, code, ip); newIp = (ip - 3) + offset; assert(t, newIp < codeLength(t, code)); + + if(newIp <= ip) { + compileSafePoint(t, c, frame); + } Compiler::Operand* a = frame->popObject(); Compiler::Operand* b = frame->popObject(); @@ -5069,6 +5096,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp, uint32_t offset = codeReadInt16(t, code, ip); newIp = (ip - 3) + offset; assert(t, newIp < codeLength(t, code)); + + if(newIp <= ip) { + compileSafePoint(t, c, frame); + } Compiler::Operand* a = frame->popInt(); Compiler::Operand* b = frame->popInt(); @@ -5110,6 +5141,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp, Compiler::Operand* target = frame->machineIp(newIp); + if(newIp <= ip) { + compileSafePoint(t, c, frame); + } + Compiler::Operand* a = c->constant(0, Compiler::IntegerType); Compiler::Operand* b = frame->popInt(); @@ -5143,6 +5178,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned initialIp, newIp = (ip - 3) + offset; assert(t, newIp < codeLength(t, code)); + if(newIp <= ip) { + compileSafePoint(t, c, frame); + } + Compiler::Operand* a = c->constant(0, Compiler::ObjectType); Compiler::Operand* b = frame->popObject(); Compiler::Operand* target = frame->machineIp(newIp); diff --git a/src/interpret.cpp b/src/interpret.cpp index a1d855079a..feac47591f 100644 --- a/src/interpret.cpp +++ b/src/interpret.cpp @@ -765,6 +765,10 @@ pushField(Thread* t, object target, object field) } } +void safePoint(Thread* t) { + ENTER(t, Thread::IdleState); +} + object interpret3(Thread* t, const int base) { @@ -1489,12 +1493,12 @@ interpret3(Thread* t, const int base) case goto_: { int16_t offset = codeReadInt16(t, code, ip); ip = (ip - 3) + offset; - } goto loop; + } goto back_branch; case goto_w: { int32_t offset = codeReadInt32(t, code, ip); ip = (ip - 5) + offset; - } goto loop; + } goto back_branch; case i2b: { pushInt(t, static_cast(popInt(t))); @@ -1626,7 +1630,7 @@ interpret3(Thread* t, const int base) if (a == b) { ip = (ip - 3) + offset; } - } goto loop; + } goto back_branch; case if_acmpne: { int16_t offset = codeReadInt16(t, code, ip); @@ -1637,7 +1641,7 @@ interpret3(Thread* t, const int base) if (a != b) { ip = (ip - 3) + offset; } - } goto loop; + } goto back_branch; case if_icmpeq: { int16_t offset = codeReadInt16(t, code, ip); @@ -1648,7 +1652,7 @@ interpret3(Thread* t, const int base) if (a == b) { ip = (ip - 3) + offset; } - } goto loop; + } goto back_branch; case if_icmpne: { int16_t offset = codeReadInt16(t, code, ip); @@ -1659,7 +1663,7 @@ interpret3(Thread* t, const int base) if (a != b) { ip = (ip - 3) + offset; } - } goto loop; + } goto back_branch; case if_icmpgt: { int16_t offset = codeReadInt16(t, code, ip); @@ -1670,7 +1674,7 @@ interpret3(Thread* t, const int base) if (a > b) { ip = (ip - 3) + offset; } - } goto loop; + } goto back_branch; case if_icmpge: { int16_t offset = codeReadInt16(t, code, ip); @@ -1681,7 +1685,7 @@ interpret3(Thread* t, const int base) if (a >= b) { ip = (ip - 3) + offset; } - } goto loop; + } goto back_branch; case if_icmplt: { int16_t offset = codeReadInt16(t, code, ip); @@ -1692,7 +1696,7 @@ interpret3(Thread* t, const int base) if (a < b) { ip = (ip - 3) + offset; } - } goto loop; + } goto back_branch; case if_icmple: { int16_t offset = codeReadInt16(t, code, ip); @@ -1703,7 +1707,7 @@ interpret3(Thread* t, const int base) if (a <= b) { ip = (ip - 3) + offset; } - } goto loop; + } goto back_branch; case ifeq: { int16_t offset = codeReadInt16(t, code, ip); @@ -1711,7 +1715,7 @@ interpret3(Thread* t, const int base) if (popInt(t) == 0) { ip = (ip - 3) + offset; } - } goto loop; + } goto back_branch; case ifne: { int16_t offset = codeReadInt16(t, code, ip); @@ -1719,7 +1723,7 @@ interpret3(Thread* t, const int base) if (popInt(t)) { ip = (ip - 3) + offset; } - } goto loop; + } goto back_branch; case ifgt: { int16_t offset = codeReadInt16(t, code, ip); @@ -1727,7 +1731,7 @@ interpret3(Thread* t, const int base) if (static_cast(popInt(t)) > 0) { ip = (ip - 3) + offset; } - } goto loop; + } goto back_branch; case ifge: { int16_t offset = codeReadInt16(t, code, ip); @@ -1735,7 +1739,7 @@ interpret3(Thread* t, const int base) if (static_cast(popInt(t)) >= 0) { ip = (ip - 3) + offset; } - } goto loop; + } goto back_branch; case iflt: { int16_t offset = codeReadInt16(t, code, ip); @@ -1743,7 +1747,7 @@ interpret3(Thread* t, const int base) if (static_cast(popInt(t)) < 0) { ip = (ip - 3) + offset; } - } goto loop; + } goto back_branch; case ifle: { int16_t offset = codeReadInt16(t, code, ip); @@ -1751,7 +1755,7 @@ interpret3(Thread* t, const int base) if (static_cast(popInt(t)) <= 0) { ip = (ip - 3) + offset; } - } goto loop; + } goto back_branch; case ifnonnull: { int16_t offset = codeReadInt16(t, code, ip); @@ -1759,7 +1763,7 @@ interpret3(Thread* t, const int base) if (popObject(t)) { ip = (ip - 3) + offset; } - } goto loop; + } goto back_branch; case ifnull: { int16_t offset = codeReadInt16(t, code, ip); @@ -1767,7 +1771,7 @@ interpret3(Thread* t, const int base) if (popObject(t) == 0) { ip = (ip - 3) + offset; } - } goto loop; + } goto back_branch; case iinc: { uint8_t index = codeBody(t, code, ip++); @@ -2711,6 +2715,10 @@ interpret3(Thread* t, const int base) default: abort(t); } + back_branch: + safePoint(t); + goto loop; + invoke: { if (methodFlags(t, code) & ACC_NATIVE) { invokeNative(t, code); diff --git a/src/thunks.cpp b/src/thunks.cpp index 328e62c8f3..9c0278876b 100644 --- a/src/thunks.cpp +++ b/src/thunks.cpp @@ -70,3 +70,4 @@ THUNK(set) THUNK(getJClass64) THUNK(getJClassFromReference) THUNK(gcIfNecessary) +THUNK(idleIfNecessary) diff --git a/test/Busy.java b/test/Busy.java new file mode 100644 index 0000000000..e301896416 --- /dev/null +++ b/test/Busy.java @@ -0,0 +1,25 @@ +public class Busy { + private static volatile int foo = 0; + private static volatile boolean go; + + public static void main(String[] args) { + final Object lock = new Object(); + + synchronized (lock) { + new Thread() { + public void run() { + while (foo < 100) { + go = true; + } + } + }.start(); + + while (foo < 100) { + while (! go) { } + go = false; + byte[] array = new byte[256 * 1024]; + ++ foo; + } + } + } +} \ No newline at end of file