mirror of
https://github.com/corda/corda.git
synced 2025-01-03 19:54:13 +00:00
save locals to memory before executing any instruction which might trigger an exception if that instruction lies within an exception handler
This commit is contained in:
parent
3d9e508e3e
commit
eea2225176
@ -530,7 +530,7 @@ class Context {
|
||||
|
||||
Context(MyThread* t, object method):
|
||||
thread(t),
|
||||
zone(t->m->system, t->m->heap, 16 * 1024),
|
||||
zone(t->m->system, t->m->heap, 64 * 1024),
|
||||
assembler(makeAssembler(t->m->system, t->m->heap, &zone, t->arch)),
|
||||
client(t),
|
||||
compiler(makeCompiler(t->m->system, assembler, &zone, &client)),
|
||||
@ -1860,6 +1860,24 @@ exceptionIndex(MyThread* t, object code, unsigned jsrIp, unsigned dstIp)
|
||||
abort(t);
|
||||
}
|
||||
|
||||
bool
|
||||
inTryBlock(MyThread* t, object code, unsigned ip)
|
||||
{
|
||||
object table = codeExceptionHandlerTable(t, code);
|
||||
if (table) {
|
||||
unsigned length = exceptionHandlerTableLength(t, table);
|
||||
for (unsigned i = 0; i < length; ++i) {
|
||||
ExceptionHandler* eh = exceptionHandlerTableBody(t, table, i);
|
||||
if (ip >= exceptionHandlerStart(eh)
|
||||
and ip < exceptionHandlerEnd(eh))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
int exceptionHandlerStart = -1);
|
||||
@ -1926,6 +1944,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
Compiler::Operand* index = frame->popInt();
|
||||
Compiler::Operand* array = frame->popObject();
|
||||
|
||||
if (inTryBlock(t, code, ip - 1)) {
|
||||
c->saveLocals();
|
||||
}
|
||||
|
||||
if (CheckArrayBounds) {
|
||||
c->checkBounds(array, ArrayLength, index, reinterpret_cast<intptr_t>
|
||||
(&singletonValue(t, aioobThunk(t), 0)));
|
||||
@ -1982,6 +2004,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
Compiler::Operand* index = frame->popInt();
|
||||
Compiler::Operand* array = frame->popObject();
|
||||
|
||||
if (inTryBlock(t, code, ip - 1)) {
|
||||
c->saveLocals();
|
||||
}
|
||||
|
||||
if (CheckArrayBounds) {
|
||||
c->checkBounds(array, ArrayLength, index, reinterpret_cast<intptr_t>
|
||||
(&singletonValue(t, aioobThunk(t), 0)));
|
||||
@ -2405,6 +2431,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
table = frame->append(classStaticTable(t, fieldClass(t, field)));
|
||||
} else {
|
||||
table = frame->popObject();
|
||||
|
||||
if (inTryBlock(t, code, ip - 3)) {
|
||||
c->saveLocals();
|
||||
}
|
||||
}
|
||||
|
||||
switch (fieldCode(t, field)) {
|
||||
@ -3330,6 +3360,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
}
|
||||
|
||||
staticTable = classStaticTable(t, fieldClass(t, field));
|
||||
} else if (inTryBlock(t, code, ip - 3)) {
|
||||
c->saveLocals();
|
||||
}
|
||||
|
||||
Compiler::Operand* value;
|
||||
@ -3968,7 +4000,7 @@ finish(MyThread* t, Context* context)
|
||||
strcmp
|
||||
(reinterpret_cast<const char*>
|
||||
(&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)),
|
||||
"Longs") == 0 and
|
||||
"Arrays") == 0 and
|
||||
strcmp
|
||||
(reinterpret_cast<const char*>
|
||||
(&byteArrayBody(t, methodName(t, context->method), 0)),
|
||||
|
@ -2294,7 +2294,7 @@ clean(Context* c, Event* e, Stack* stack, Local* locals, Read* reads,
|
||||
|
||||
for (Read* r = reads; r; r = r->eventNext) {
|
||||
nextRead(c, e, r->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CodePromise*
|
||||
@ -2313,6 +2313,26 @@ codePromise(Context* c, Promise* offset)
|
||||
void
|
||||
append(Context* c, Event* e);
|
||||
|
||||
void
|
||||
saveLocals(Context* c, Event* e)
|
||||
{
|
||||
for (unsigned li = 0; li < c->localFootprint; ++li) {
|
||||
Local* local = e->localsBefore + li;
|
||||
if (local->value) {
|
||||
if (DebugReads) {
|
||||
fprintf(stderr, "local save read %p of footprint %d at %d of %d\n",
|
||||
local->value, local->footprint,
|
||||
::frameIndex(c, li, local->footprint),
|
||||
c->alignedFrameSize + c->parameterFootprint);
|
||||
}
|
||||
|
||||
addRead(c, e, local->value, read
|
||||
(c, footprintSizeInBytes(local->footprint), 1 << MemoryOperand,
|
||||
0, ::frameIndex(c, li, local->footprint)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class CallEvent: public Event {
|
||||
public:
|
||||
CallEvent(Context* c, Value* address, unsigned flags,
|
||||
@ -2422,21 +2442,7 @@ class CallEvent: public Event {
|
||||
frameIndex += s->footprint;
|
||||
}
|
||||
|
||||
for (unsigned li = 0; li < c->localFootprint; ++li) {
|
||||
Local* local = localsBefore + li;
|
||||
if (local->value) {
|
||||
if (DebugReads) {
|
||||
fprintf(stderr, "local save read %p of footprint %d at %d of %d\n",
|
||||
local->value, local->footprint,
|
||||
::frameIndex(c, li, local->footprint),
|
||||
c->alignedFrameSize + c->parameterFootprint);
|
||||
}
|
||||
|
||||
addRead(c, this, local->value, read
|
||||
(c, footprintSizeInBytes(local->footprint), 1 << MemoryOperand,
|
||||
0, ::frameIndex(c, li, local->footprint)));
|
||||
}
|
||||
}
|
||||
saveLocals(c, this);
|
||||
}
|
||||
|
||||
virtual const char* name() {
|
||||
@ -3412,6 +3418,32 @@ appendBuddy(Context* c, Value* original, Value* buddy, unsigned size)
|
||||
BuddyEvent(c, original, buddy, size));
|
||||
}
|
||||
|
||||
class SaveLocalsEvent: public Event {
|
||||
public:
|
||||
SaveLocalsEvent(Context* c):
|
||||
Event(c)
|
||||
{
|
||||
saveLocals(c, this);
|
||||
}
|
||||
|
||||
virtual const char* name() {
|
||||
return "SaveLocalsEvent";
|
||||
}
|
||||
|
||||
virtual void compile(Context* c) {
|
||||
for (Read* r = reads; r; r = r->eventNext) {
|
||||
nextRead(c, this, r->value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
appendSaveLocals(Context* c)
|
||||
{
|
||||
append(c, new (c->zone->allocate(sizeof(SaveLocalsEvent)))
|
||||
SaveLocalsEvent(c));
|
||||
}
|
||||
|
||||
class DummyEvent: public Event {
|
||||
public:
|
||||
DummyEvent(Context* c):
|
||||
@ -4482,6 +4514,10 @@ class MyCompiler: public Compiler {
|
||||
return c.locals[index].value;
|
||||
}
|
||||
|
||||
virtual void saveLocals() {
|
||||
appendSaveLocals(&c);
|
||||
}
|
||||
|
||||
virtual void checkBounds(Operand* object, unsigned lengthOffset,
|
||||
Operand* index, intptr_t handler)
|
||||
{
|
||||
|
@ -92,6 +92,7 @@ class Compiler {
|
||||
virtual void storeLocal(unsigned footprint, Operand* src,
|
||||
unsigned index) = 0;
|
||||
virtual Operand* loadLocal(unsigned footprint, unsigned index) = 0;
|
||||
virtual void saveLocals() = 0;
|
||||
|
||||
virtual void checkBounds(Operand* object, unsigned lengthOffset,
|
||||
Operand* index, intptr_t handler) = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user