mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +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):
|
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)),
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user