mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +00:00
Merge pull request #135 from joshuawarner32/no-busy-block
make sure a busy-waiting loop can't block the GC and hence the whole VM
This commit is contained in:
commit
10d15d23fb
@ -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);
|
||||
|
@ -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<int8_t>(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<int32_t>(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<int32_t>(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<int32_t>(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<int32_t>(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);
|
||||
|
@ -70,3 +70,4 @@ THUNK(set)
|
||||
THUNK(getJClass64)
|
||||
THUNK(getJClassFromReference)
|
||||
THUNK(gcIfNecessary)
|
||||
THUNK(idleIfNecessary)
|
||||
|
25
test/Busy.java
Normal file
25
test/Busy.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user