mirror of
https://github.com/corda/corda.git
synced 2025-02-12 13:45:48 +00:00
translate exception handler table into a form which does not depend on the constant pool after JIT compiling a method
This commit is contained in:
parent
2cf62a5926
commit
bd618a51f6
106
src/compile.cpp
106
src/compile.cpp
@ -26,10 +26,10 @@ vmCall();
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const bool Verbose = true;
|
const bool Verbose = false;
|
||||||
const bool DebugNatives = false;
|
const bool DebugNatives = false;
|
||||||
const bool DebugCallTable = false;
|
const bool DebugCallTable = false;
|
||||||
const bool DebugMethodTree = true;
|
const bool DebugMethodTree = false;
|
||||||
const bool DebugFrameMaps = false;
|
const bool DebugFrameMaps = false;
|
||||||
|
|
||||||
const bool CheckArrayBounds = true;
|
const bool CheckArrayBounds = true;
|
||||||
@ -188,8 +188,6 @@ class MyStackWalker: public Processor::StackWalker {
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void walk(Processor::StackVisitor* v) {
|
virtual void walk(Processor::StackVisitor* v) {
|
||||||
fprintf(stderr, "ip: %p stack: %p method: %p\n", ip_, stack, method_);
|
|
||||||
|
|
||||||
if (stack == 0) {
|
if (stack == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -212,6 +210,7 @@ class MyStackWalker: public Processor::StackWalker {
|
|||||||
} else {
|
} else {
|
||||||
stack = static_cast<void**>(base) + 1;
|
stack = static_cast<void**>(base) + 1;
|
||||||
base = *static_cast<void**>(base);
|
base = *static_cast<void**>(base);
|
||||||
|
ip_ = *static_cast<void**>(stack);
|
||||||
method_ = methodForIp(t, *static_cast<void**>(stack));
|
method_ = methodForIp(t, *static_cast<void**>(stack));
|
||||||
if (method_ == 0) {
|
if (method_ == 0) {
|
||||||
if (trace and trace->stack) {
|
if (trace and trace->stack) {
|
||||||
@ -1134,6 +1133,54 @@ insertCallNode(MyThread* t, object node);
|
|||||||
void
|
void
|
||||||
removeCallNode(MyThread* t, object node);
|
removeCallNode(MyThread* t, object node);
|
||||||
|
|
||||||
|
void*
|
||||||
|
findExceptionHandler(Thread* t, object method, void* ip)
|
||||||
|
{
|
||||||
|
PROTECT(t, method);
|
||||||
|
|
||||||
|
object table = codeExceptionHandlerTable(t, methodCode(t, method));
|
||||||
|
if (table) {
|
||||||
|
object index = arrayBody(t, table, 0);
|
||||||
|
|
||||||
|
uint8_t* compiled = reinterpret_cast<uint8_t*>
|
||||||
|
(&singletonValue(t, methodCompiled(t, method), 0));
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < arrayLength(t, table) - 1; ++i) {
|
||||||
|
unsigned start = intArrayBody(t, index, i * 3);
|
||||||
|
unsigned end = intArrayBody(t, index, (i * 3) + 1);
|
||||||
|
unsigned key = difference(ip, compiled) - 1;
|
||||||
|
|
||||||
|
if (key >= start and key < end) {
|
||||||
|
object catchType = 0;
|
||||||
|
if (arrayBody(t, table, i + 1)) {
|
||||||
|
object e = t->exception;
|
||||||
|
t->exception = 0;
|
||||||
|
PROTECT(t, e);
|
||||||
|
|
||||||
|
PROTECT(t, table);
|
||||||
|
PROTECT(t, index);
|
||||||
|
|
||||||
|
catchType = resolveClassInObject
|
||||||
|
(t, table, ArrayBody + ((i + 1) * BytesPerWord));
|
||||||
|
|
||||||
|
if (catchType) {
|
||||||
|
t->exception = e;
|
||||||
|
} else {
|
||||||
|
// can't find what we're supposed to catch - move on.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (catchType == 0 or instanceOf(t, catchType, t->exception)) {
|
||||||
|
return compiled + intArrayBody(t, index, (i * 3) + 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
|
findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
|
||||||
void** targetStack)
|
void** targetStack)
|
||||||
@ -1153,11 +1200,7 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
|
|||||||
if (method) {
|
if (method) {
|
||||||
PROTECT(t, method);
|
PROTECT(t, method);
|
||||||
|
|
||||||
uint8_t* compiled = reinterpret_cast<uint8_t*>
|
void* handler = findExceptionHandler(t, method, ip);
|
||||||
(&singletonValue(t, methodCompiled(t, method), 0));
|
|
||||||
|
|
||||||
ExceptionHandler* handler = findExceptionHandler
|
|
||||||
(t, method, difference(ip, compiled));
|
|
||||||
|
|
||||||
if (handler) {
|
if (handler) {
|
||||||
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
unsigned parameterFootprint = methodParameterFootprint(t, method);
|
||||||
@ -1169,7 +1212,7 @@ findUnwindTarget(MyThread* t, void** targetIp, void** targetBase,
|
|||||||
*(--stack) = t->exception;
|
*(--stack) = t->exception;
|
||||||
t->exception = 0;
|
t->exception = 0;
|
||||||
|
|
||||||
*targetIp = compiled + exceptionHandlerIp(handler);
|
*targetIp = handler;
|
||||||
*targetBase = base;
|
*targetBase = base;
|
||||||
*targetStack = stack;
|
*targetStack = stack;
|
||||||
} else {
|
} else {
|
||||||
@ -3532,8 +3575,8 @@ logCompile(const void* code, unsigned size, const char* class_,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
updateExceptionHandlerTable(MyThread* t, Compiler* c, object code,
|
translateExceptionHandlerTable(MyThread* t, Compiler* c, object code,
|
||||||
intptr_t start)
|
intptr_t start)
|
||||||
{
|
{
|
||||||
object oldTable = codeExceptionHandlerTable(t, code);
|
object oldTable = codeExceptionHandlerTable(t, code);
|
||||||
if (oldTable) {
|
if (oldTable) {
|
||||||
@ -3541,24 +3584,32 @@ updateExceptionHandlerTable(MyThread* t, Compiler* c, object code,
|
|||||||
PROTECT(t, oldTable);
|
PROTECT(t, oldTable);
|
||||||
|
|
||||||
unsigned length = exceptionHandlerTableLength(t, oldTable);
|
unsigned length = exceptionHandlerTableLength(t, oldTable);
|
||||||
object newTable = makeExceptionHandlerTable(t, length, false);
|
|
||||||
|
object newIndex = makeIntArray(t, length * 3, false);
|
||||||
|
PROTECT(t, newIndex);
|
||||||
|
|
||||||
|
object newTable = makeArray(t, length + 1, false);
|
||||||
|
set(t, newTable, ArrayBody, newIndex);
|
||||||
|
|
||||||
for (unsigned i = 0; i < length; ++i) {
|
for (unsigned i = 0; i < length; ++i) {
|
||||||
ExceptionHandler* oldHandler = exceptionHandlerTableBody
|
ExceptionHandler* oldHandler = exceptionHandlerTableBody
|
||||||
(t, oldTable, i);
|
(t, oldTable, i);
|
||||||
ExceptionHandler* newHandler = exceptionHandlerTableBody
|
|
||||||
(t, newTable, i);
|
|
||||||
|
|
||||||
exceptionHandlerStart(newHandler)
|
intArrayBody(t, newIndex, i * 3)
|
||||||
= c->machineIp(exceptionHandlerStart(oldHandler))->value(c) - start;
|
= c->machineIp(exceptionHandlerStart(oldHandler))->value(c) - start;
|
||||||
|
|
||||||
exceptionHandlerEnd(newHandler)
|
intArrayBody(t, newIndex, (i * 3) + 1)
|
||||||
= c->machineIp(exceptionHandlerEnd(oldHandler))->value(c) - start;
|
= c->machineIp(exceptionHandlerEnd(oldHandler))->value(c) - start;
|
||||||
|
|
||||||
exceptionHandlerIp(newHandler)
|
intArrayBody(t, newIndex, (i * 3) + 2)
|
||||||
= c->machineIp(exceptionHandlerIp(oldHandler))->value(c) - start;
|
= c->machineIp(exceptionHandlerIp(oldHandler))->value(c) - start;
|
||||||
|
|
||||||
exceptionHandlerCatchType(newHandler)
|
object type =
|
||||||
= exceptionHandlerCatchType(oldHandler);
|
(exceptionHandlerCatchType(oldHandler) ?
|
||||||
|
singletonObject(t, codePool(t, code),
|
||||||
|
exceptionHandlerCatchType(oldHandler) - 1) : 0);
|
||||||
|
|
||||||
|
set(t, newTable, ArrayBody + ((i + 1) * BytesPerWord), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
set(t, code, CodeExceptionHandlerTable, newTable);
|
set(t, code, CodeExceptionHandlerTable, newTable);
|
||||||
@ -3566,8 +3617,7 @@ updateExceptionHandlerTable(MyThread* t, Compiler* c, object code,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
updateLineNumberTable(MyThread* t, Compiler* c, object code,
|
translateLineNumberTable(MyThread* t, Compiler* c, object code, intptr_t start)
|
||||||
intptr_t start)
|
|
||||||
{
|
{
|
||||||
object oldTable = codeLineNumberTable(t, code);
|
object oldTable = codeLineNumberTable(t, code);
|
||||||
if (oldTable) {
|
if (oldTable) {
|
||||||
@ -3764,6 +3814,12 @@ finish(MyThread* t, Context* context, const char* name)
|
|||||||
if (context->method) {
|
if (context->method) {
|
||||||
PROTECT(t, result);
|
PROTECT(t, result);
|
||||||
|
|
||||||
|
translateExceptionHandlerTable(t, c, methodCode(t, context->method),
|
||||||
|
reinterpret_cast<intptr_t>(start));
|
||||||
|
|
||||||
|
translateLineNumberTable(t, c, methodCode(t, context->method),
|
||||||
|
reinterpret_cast<intptr_t>(start));
|
||||||
|
|
||||||
{ object code = methodCode(t, context->method);
|
{ object code = methodCode(t, context->method);
|
||||||
|
|
||||||
code = makeCode(t, 0,
|
code = makeCode(t, 0,
|
||||||
@ -3830,12 +3886,6 @@ finish(MyThread* t, Context* context, const char* name)
|
|||||||
set(t, result, SingletonBody + offset, p->value);
|
set(t, result, SingletonBody + offset, p->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateExceptionHandlerTable(t, c, methodCode(t, context->method),
|
|
||||||
reinterpret_cast<intptr_t>(start));
|
|
||||||
|
|
||||||
updateLineNumberTable(t, c, methodCode(t, context->method),
|
|
||||||
reinterpret_cast<intptr_t>(start));
|
|
||||||
|
|
||||||
if (Verbose) {
|
if (Verbose) {
|
||||||
logCompile
|
logCompile
|
||||||
(start, c->codeSize(),
|
(start, c->codeSize(),
|
||||||
|
@ -704,6 +704,50 @@ store(Thread* t, unsigned index)
|
|||||||
BytesPerWord * 2);
|
BytesPerWord * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExceptionHandler*
|
||||||
|
findExceptionHandler(Thread* t, object method, unsigned ip)
|
||||||
|
{
|
||||||
|
PROTECT(t, method);
|
||||||
|
|
||||||
|
object eht = codeExceptionHandlerTable(t, methodCode(t, method));
|
||||||
|
|
||||||
|
if (eht) {
|
||||||
|
for (unsigned i = 0; i < exceptionHandlerTableLength(t, eht); ++i) {
|
||||||
|
ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i);
|
||||||
|
|
||||||
|
if (ip - 1 >= exceptionHandlerStart(eh)
|
||||||
|
and ip - 1 < exceptionHandlerEnd(eh))
|
||||||
|
{
|
||||||
|
object catchType = 0;
|
||||||
|
if (exceptionHandlerCatchType(eh)) {
|
||||||
|
object e = t->exception;
|
||||||
|
t->exception = 0;
|
||||||
|
PROTECT(t, e);
|
||||||
|
|
||||||
|
PROTECT(t, eht);
|
||||||
|
catchType = resolveClassInPool
|
||||||
|
(t, codePool(t, methodCode(t, method)),
|
||||||
|
exceptionHandlerCatchType(eh) - 1);
|
||||||
|
|
||||||
|
if (catchType) {
|
||||||
|
eh = exceptionHandlerTableBody(t, eht, i);
|
||||||
|
t->exception = e;
|
||||||
|
} else {
|
||||||
|
// can't find what we're supposed to catch - move on.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (catchType == 0 or instanceOf(t, catchType, t->exception)) {
|
||||||
|
return eh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ExceptionHandler*
|
ExceptionHandler*
|
||||||
findExceptionHandler(Thread* t, int frame)
|
findExceptionHandler(Thread* t, int frame)
|
||||||
{
|
{
|
||||||
|
@ -191,50 +191,6 @@ resolveNativeMethod2(Thread* t, object method)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExceptionHandler*
|
|
||||||
findExceptionHandler(Thread* t, object method, unsigned ip)
|
|
||||||
{
|
|
||||||
PROTECT(t, method);
|
|
||||||
|
|
||||||
object eht = codeExceptionHandlerTable(t, methodCode(t, method));
|
|
||||||
|
|
||||||
if (eht) {
|
|
||||||
for (unsigned i = 0; i < exceptionHandlerTableLength(t, eht); ++i) {
|
|
||||||
ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i);
|
|
||||||
|
|
||||||
if (ip - 1 >= exceptionHandlerStart(eh)
|
|
||||||
and ip - 1 < exceptionHandlerEnd(eh))
|
|
||||||
{
|
|
||||||
object catchType = 0;
|
|
||||||
if (exceptionHandlerCatchType(eh)) {
|
|
||||||
object e = t->exception;
|
|
||||||
t->exception = 0;
|
|
||||||
PROTECT(t, e);
|
|
||||||
|
|
||||||
PROTECT(t, eht);
|
|
||||||
catchType = resolveClassInPool
|
|
||||||
(t, codePool(t, methodCode(t, method)),
|
|
||||||
exceptionHandlerCatchType(eh) - 1);
|
|
||||||
|
|
||||||
if (catchType) {
|
|
||||||
eh = exceptionHandlerTableBody(t, eht, i);
|
|
||||||
t->exception = e;
|
|
||||||
} else {
|
|
||||||
// can't find what we're supposed to catch - move on.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (catchType == 0 or instanceOf(t, catchType, t->exception)) {
|
|
||||||
return eh;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
findLineNumber(Thread* t, object method, unsigned ip)
|
findLineNumber(Thread* t, object method, unsigned ip)
|
||||||
{
|
{
|
||||||
|
@ -192,9 +192,6 @@ populateMultiArray(Thread* t, object array, int32_t* counts,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ExceptionHandler*
|
|
||||||
findExceptionHandler(Thread* t, object method, unsigned ip);
|
|
||||||
|
|
||||||
int
|
int
|
||||||
findLineNumber(Thread* t, object method, unsigned ip);
|
findLineNumber(Thread* t, object method, unsigned ip);
|
||||||
|
|
||||||
|
@ -24,10 +24,10 @@
|
|||||||
(void* value))
|
(void* value))
|
||||||
|
|
||||||
(pod exceptionHandler
|
(pod exceptionHandler
|
||||||
(uint32_t start)
|
(uint16_t start)
|
||||||
(uint32_t end)
|
(uint16_t end)
|
||||||
(uint32_t ip)
|
(uint16_t ip)
|
||||||
(uint32_t catchType))
|
(uint16_t catchType))
|
||||||
|
|
||||||
(type exceptionHandlerTable
|
(type exceptionHandlerTable
|
||||||
(array exceptionHandler body))
|
(array exceptionHandler body))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user