From eea222517612afab99a82545682e1cc4b7bb8a32 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Tue, 25 Nov 2008 10:34:48 -0700 Subject: [PATCH] save locals to memory before executing any instruction which might trigger an exception if that instruction lies within an exception handler --- src/compile.cpp | 36 +++++++++++++++++++++++-- src/compiler.cpp | 68 ++++++++++++++++++++++++++++++++++++------------ src/compiler.h | 1 + 3 files changed, 87 insertions(+), 18 deletions(-) diff --git a/src/compile.cpp b/src/compile.cpp index e5707abf27..8879a5317d 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -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 (&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 (&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 (&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)), - "Longs") == 0 and + "Arrays") == 0 and strcmp (reinterpret_cast (&byteArrayBody(t, methodName(t, context->method), 0)), diff --git a/src/compiler.cpp b/src/compiler.cpp index 0f775aa225..a3061720d6 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -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) { diff --git a/src/compiler.h b/src/compiler.h index 48ad96c300..e1cc207078 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -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;