mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +00:00
ensure that the saved exception in a finally block is visited during GC when the jsr instruction is used
This commit is contained in:
parent
3001c2067c
commit
dc2700d913
@ -1764,6 +1764,67 @@ handleExit(MyThread* t, Frame* frame)
|
|||||||
(t, frame, getThunk(t, releaseMonitorForObjectThunk));
|
(t, frame, getThunk(t, releaseMonitorForObjectThunk));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
exceptionIndex(MyThread* t, object code, unsigned jsrIp, unsigned dstIp)
|
||||||
|
{
|
||||||
|
object table = codeExceptionHandlerTable(t, code);
|
||||||
|
unsigned length = exceptionHandlerTableLength(t, table);
|
||||||
|
for (unsigned i = 0; i < length; ++i) {
|
||||||
|
ExceptionHandler* eh = exceptionHandlerTableBody(t, table, i);
|
||||||
|
if (exceptionHandlerCatchType(eh) == 0) {
|
||||||
|
unsigned ip = exceptionHandlerIp(eh);
|
||||||
|
unsigned index;
|
||||||
|
switch (codeBody(t, code, ip++)) {
|
||||||
|
case astore:
|
||||||
|
index = codeBody(t, code, ip++);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case astore_0:
|
||||||
|
index = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case astore_1:
|
||||||
|
index = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case astore_2:
|
||||||
|
index = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case astore_3:
|
||||||
|
index = 3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: abort(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ip == jsrIp) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (codeBody(t, code, ip++)) {
|
||||||
|
case jsr: {
|
||||||
|
uint32_t offset = codeReadInt16(t, code, ip);
|
||||||
|
if ((ip - 3) + offset == dstIp) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case jsr_w: {
|
||||||
|
uint32_t offset = codeReadInt32(t, code, ip);
|
||||||
|
if ((ip - 5) + offset == dstIp) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abort(t);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||||
bool exceptionHandler = false)
|
bool exceptionHandler = false)
|
||||||
@ -2783,18 +2844,33 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
|
|
||||||
case jsr:
|
case jsr:
|
||||||
case jsr_w: {
|
case jsr_w: {
|
||||||
|
uint32_t thisIp;
|
||||||
uint32_t newIp;
|
uint32_t newIp;
|
||||||
|
|
||||||
if (instruction == jsr) {
|
if (instruction == jsr) {
|
||||||
uint32_t offset = codeReadInt16(t, code, ip);
|
uint32_t offset = codeReadInt16(t, code, ip);
|
||||||
newIp = (ip - 3) + offset;
|
thisIp = ip - 3;
|
||||||
|
newIp = thisIp + offset;
|
||||||
} else {
|
} else {
|
||||||
uint32_t offset = codeReadInt32(t, code, ip);
|
uint32_t offset = codeReadInt32(t, code, ip);
|
||||||
newIp = (ip - 5) + offset;
|
thisIp = ip - 5;
|
||||||
|
newIp = thisIp + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(t, newIp < codeLength(t, code));
|
assert(t, newIp < codeLength(t, code));
|
||||||
|
|
||||||
|
int index = exceptionIndex(t, code, thisIp, newIp);
|
||||||
|
if (index >= 0) {
|
||||||
|
// store a null pointer at the same index the exception would
|
||||||
|
// be stored in the finally block so we can safely treat that
|
||||||
|
// location as a GC root. Of course, this assumes there
|
||||||
|
// wasn't already a live value there, which is something we
|
||||||
|
// should verify once we have complete data flow information
|
||||||
|
// (todo).
|
||||||
|
c->storeLocal(BytesPerWord, c->constant(0), index);
|
||||||
|
frame->storedObject(index);
|
||||||
|
}
|
||||||
|
|
||||||
c->saveStack();
|
c->saveStack();
|
||||||
|
|
||||||
frame->pushAddress(frame->machineIp(ip));
|
frame->pushAddress(frame->machineIp(ip));
|
||||||
|
Loading…
Reference in New Issue
Block a user