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:
Joel Dice 2013-12-13 16:35:20 -08:00
commit 10d15d23fb
4 changed files with 92 additions and 19 deletions

View File

@ -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);

View File

@ -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);

View File

@ -70,3 +70,4 @@ THUNK(set)
THUNK(getJClass64)
THUNK(getJClassFromReference)
THUNK(gcIfNecessary)
THUNK(idleIfNecessary)

25
test/Busy.java Normal file
View 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;
}
}
}
}