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:
Joel Dice 2008-11-25 10:34:48 -07:00
parent 3d9e508e3e
commit eea2225176
3 changed files with 87 additions and 18 deletions

View File

@ -530,7 +530,7 @@ class Context {
Context(MyThread* t, object method): Context(MyThread* t, object method):
thread(t), 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)), assembler(makeAssembler(t->m->system, t->m->heap, &zone, t->arch)),
client(t), client(t),
compiler(makeCompiler(t->m->system, assembler, &zone, &client)), compiler(makeCompiler(t->m->system, assembler, &zone, &client)),
@ -1860,6 +1860,24 @@ exceptionIndex(MyThread* t, object code, unsigned jsrIp, unsigned dstIp)
abort(t); 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 void
compile(MyThread* t, Frame* initialFrame, unsigned ip, compile(MyThread* t, Frame* initialFrame, unsigned ip,
int exceptionHandlerStart = -1); int exceptionHandlerStart = -1);
@ -1926,6 +1944,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
Compiler::Operand* index = frame->popInt(); Compiler::Operand* index = frame->popInt();
Compiler::Operand* array = frame->popObject(); Compiler::Operand* array = frame->popObject();
if (inTryBlock(t, code, ip - 1)) {
c->saveLocals();
}
if (CheckArrayBounds) { if (CheckArrayBounds) {
c->checkBounds(array, ArrayLength, index, reinterpret_cast<intptr_t> c->checkBounds(array, ArrayLength, index, reinterpret_cast<intptr_t>
(&singletonValue(t, aioobThunk(t), 0))); (&singletonValue(t, aioobThunk(t), 0)));
@ -1982,6 +2004,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
Compiler::Operand* index = frame->popInt(); Compiler::Operand* index = frame->popInt();
Compiler::Operand* array = frame->popObject(); Compiler::Operand* array = frame->popObject();
if (inTryBlock(t, code, ip - 1)) {
c->saveLocals();
}
if (CheckArrayBounds) { if (CheckArrayBounds) {
c->checkBounds(array, ArrayLength, index, reinterpret_cast<intptr_t> c->checkBounds(array, ArrayLength, index, reinterpret_cast<intptr_t>
(&singletonValue(t, aioobThunk(t), 0))); (&singletonValue(t, aioobThunk(t), 0)));
@ -2405,6 +2431,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
table = frame->append(classStaticTable(t, fieldClass(t, field))); table = frame->append(classStaticTable(t, fieldClass(t, field)));
} else { } else {
table = frame->popObject(); table = frame->popObject();
if (inTryBlock(t, code, ip - 3)) {
c->saveLocals();
}
} }
switch (fieldCode(t, field)) { switch (fieldCode(t, field)) {
@ -3330,6 +3360,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
} }
staticTable = classStaticTable(t, fieldClass(t, field)); staticTable = classStaticTable(t, fieldClass(t, field));
} else if (inTryBlock(t, code, ip - 3)) {
c->saveLocals();
} }
Compiler::Operand* value; Compiler::Operand* value;
@ -3968,7 +4000,7 @@ finish(MyThread* t, Context* context)
strcmp strcmp
(reinterpret_cast<const char*> (reinterpret_cast<const char*>
(&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)), (&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)),
"Longs") == 0 and "Arrays") == 0 and
strcmp strcmp
(reinterpret_cast<const char*> (reinterpret_cast<const char*>
(&byteArrayBody(t, methodName(t, context->method), 0)), (&byteArrayBody(t, methodName(t, context->method), 0)),

View File

@ -2294,7 +2294,7 @@ clean(Context* c, Event* e, Stack* stack, Local* locals, Read* reads,
for (Read* r = reads; r; r = r->eventNext) { for (Read* r = reads; r; r = r->eventNext) {
nextRead(c, e, r->value); nextRead(c, e, r->value);
} }
} }
CodePromise* CodePromise*
@ -2313,6 +2313,26 @@ codePromise(Context* c, Promise* offset)
void void
append(Context* c, Event* e); 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 { class CallEvent: public Event {
public: public:
CallEvent(Context* c, Value* address, unsigned flags, CallEvent(Context* c, Value* address, unsigned flags,
@ -2422,21 +2442,7 @@ class CallEvent: public Event {
frameIndex += s->footprint; frameIndex += s->footprint;
} }
for (unsigned li = 0; li < c->localFootprint; ++li) { saveLocals(c, this);
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)));
}
}
} }
virtual const char* name() { virtual const char* name() {
@ -3412,6 +3418,32 @@ appendBuddy(Context* c, Value* original, Value* buddy, unsigned size)
BuddyEvent(c, original, buddy, 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 { class DummyEvent: public Event {
public: public:
DummyEvent(Context* c): DummyEvent(Context* c):
@ -4482,6 +4514,10 @@ class MyCompiler: public Compiler {
return c.locals[index].value; return c.locals[index].value;
} }
virtual void saveLocals() {
appendSaveLocals(&c);
}
virtual void checkBounds(Operand* object, unsigned lengthOffset, virtual void checkBounds(Operand* object, unsigned lengthOffset,
Operand* index, intptr_t handler) Operand* index, intptr_t handler)
{ {

View File

@ -92,6 +92,7 @@ class Compiler {
virtual void storeLocal(unsigned footprint, Operand* src, virtual void storeLocal(unsigned footprint, Operand* src,
unsigned index) = 0; unsigned index) = 0;
virtual Operand* loadLocal(unsigned footprint, unsigned index) = 0; virtual Operand* loadLocal(unsigned footprint, unsigned index) = 0;
virtual void saveLocals() = 0;
virtual void checkBounds(Operand* object, unsigned lengthOffset, virtual void checkBounds(Operand* object, unsigned lengthOffset,
Operand* index, intptr_t handler) = 0; Operand* index, intptr_t handler) = 0;