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:
Joel Dice 2008-04-11 13:03:40 -06:00
parent 2cf62a5926
commit bd618a51f6
5 changed files with 126 additions and 79 deletions

View File

@ -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(),

View File

@ -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)
{ {

View File

@ -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)
{ {

View File

@ -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);

View File

@ -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))