This commit is contained in:
Joel Dice 2007-10-01 18:08:17 -06:00
parent 45dc118ab9
commit 68e382ca8d
4 changed files with 182 additions and 54 deletions

View File

@ -34,7 +34,7 @@ src = src
classpath = classpath
test = test
input = $(cls)/Hello.class
input = $(cls)/Exceptions.class
cxx = g++
cc = gcc

View File

@ -11,6 +11,9 @@ extern "C" uint64_t
vmInvoke(void* function, void* stack, unsigned stackSize,
unsigned returnType);
extern "C" void NO_RETURN
vmJump(void* address);
namespace {
const bool Verbose = false;
@ -36,10 +39,108 @@ class MyThread: public Thread {
Reference* reference;
};
inline bool
frameValid(void* frame)
{
return frame != 0;
}
inline void*
frameBase(void* frame)
{
return static_cast<void**>(frame)[- (FrameFootprint / BytesPerWord) - 1];
}
inline void*
frameNext(void* frame)
{
return static_cast<void**>(frameBase(frame))[FrameNext / BytesPerWord];
}
inline object
frameMethod(void* frame)
{
return static_cast<object*>(frameBase(frame))[FrameMethod / BytesPerWord];
}
inline object
frameAddress(void* frame)
{
return static_cast<void**>(frame)[- (FrameFootprint / BytesPerWord)];
}
inline void*
frameReturnAddress(void* frame)
{
return static_cast<void**>(frameBase(frame))[1];
}
uint32_t
ipToOffset(Thread* t, object method, uint16_t ip)
{
object compiled = methodCompiled(t, method);
unsigned bottom = 0;
unsigned top = compiledIpTableLength(t, compiled);
for (unsigned span = top - bottom; span; span = top - bottom) {
unsigned middle = bottom + (span / 2);
uint16_t k = compiledIpTable(t, compiled, middle);
if (ip < k) {
top = middle;
} else if (ip > k) {
bottom = middle + 1;
} else {
return compiledOffsetTable(t, compiled, middle);
}
}
abort(t);
}
uint16_t
offsetToIp(Thread* t, object method, uint32_t offset)
{
object compiled = methodCompiled(t, method);
unsigned bottom = 0;
unsigned top = compiledOffsetTableLength(t, compiled);
for (unsigned span = top - bottom; span; span = top - bottom) {
unsigned middle = bottom + (span / 2);
uint32_t k = compiledOffsetTable(t, compiled, middle);
if (ip < k) {
top = middle;
} else if (ip > k) {
bottom = middle + 1;
} else {
return compiledIpTable(t, compiled, middle);
}
}
abort(t);
}
void NO_RETURN
unwind(Thread* t)
{
// todo
for (void* frame = t->frame; frameValid(frame); frame = frameNext(frame)) {
void* next = frameNext(frame);
if (not frameValid(next)
or methodFlags(t, frameMethod(next)) & ACC_NATIVE)
{
t->frame = next;
vmJump(frameReturnAddress(frame));
} else if ((methodFlags(t, frameMethod(frame)) & ACC_NATIVE) == 0) {
ExceptionHandler* eh = findExceptionHandler(t, frameMethod(t, frame));
if (eh) {
t->frame = frame;
uint32_t offset = ipToAddress
(t, frameMethod(frame), exceptionHandlerIp(eh));
vmJump(&compiledBody(t, methodCompiled(t, method), offset));
}
}
}
abort(t);
}
@ -851,7 +952,7 @@ class Compiler: public Assembler {
uint8_t* code = &compiledBody(t, methodCompiled(t, target), 0);
push(rbp);
push(rsp);
pushAddress(reinterpret_cast<uintptr_t>(target));
push(rbp, FrameThread);
@ -864,6 +965,9 @@ class Compiler: public Assembler {
}
void compileCall(uintptr_t function, uintptr_t arg1) {
mov(rbp, FrameThread, rax);
mov(rbp, rax, frameOffset); // set thread frame to current
if (BytesPerWord == 4) {
push(arg1);
push(rbp, FrameThread);
@ -881,6 +985,9 @@ class Compiler: public Assembler {
}
void compileCall(uintptr_t function, Register arg1) {
mov(rbp, FrameThread, rax);
mov(rbp, rax, frameOffset); // set thread frame to current
if (BytesPerWord == 4) {
push(arg1);
push(rbp, FrameThread);
@ -898,6 +1005,9 @@ class Compiler: public Assembler {
}
void compileCall(uintptr_t function, uintptr_t arg1, Register arg2) {
mov(rbp, FrameThread, rax);
mov(rbp, rax, frameOffset); // set thread frame to current
if (BytesPerWord == 4) {
push(arg2);
push(arg1);
@ -917,6 +1027,9 @@ class Compiler: public Assembler {
}
void compileCall(uintptr_t function, Register arg1, Register arg2) {
mov(rbp, FrameThread, rax);
mov(rbp, rax, frameOffset); // set thread frame to current
if (BytesPerWord == 4) {
push(arg2);
push(arg1);
@ -1613,7 +1726,7 @@ class Compiler: public Assembler {
mov(rax, ClassVirtualTable, rax); // load vtable
mov(rax, offset, rax); // load method
push(rbp);
push(rsp);
push(rax);
push(rbp, FrameThread);
@ -2377,33 +2490,33 @@ class MyProcessor: public Processor {
}
virtual uintptr_t
frameStart(Thread* t)
frameStart(Thread* vmt)
{
abort(t);
return static_cast<MyThread*>(vmt)->frame;
}
virtual uintptr_t
frameNext(Thread* t, uintptr_t)
frameNext(Thread*, uintptr_t frame)
{
abort(t);
::frameNext(reinterpret_cast<void*>(frame));
}
virtual bool
frameValid(Thread* t, uintptr_t)
frameValid(Thread*, uintptr_t frame)
{
abort(t);
return ::frameValid(frame);
}
virtual object
frameMethod(Thread* t, uintptr_t)
frameMethod(Thread*, uintptr_t frame)
{
abort(t);
return ::frameMethod(frame);
}
virtual unsigned
frameIp(Thread* t, uintptr_t)
frameIp(Thread*, uintptr_t frame)
{
abort(t);
return addressToIp(t, frameMethod(frame), frameAddress(frame));
}
virtual object*

View File

@ -537,21 +537,24 @@ invokeNative(Thread* t, object method)
unsigned returnCode = methodReturnCode(t, method);
unsigned returnType = fieldType(t, returnCode);
void* function = nativeMethodDataFunction(t, data);
uint8_t types[nativeMethodDataLength(t, data)];
memcpy(&types,
&nativeMethodDataParameterTypes(t, data, 0),
nativeMethodDataLength(t, data));
uint64_t result;
if (DebugRun) {
fprintf(stderr, "invoke native method %s.%s\n",
&byteArrayBody(t, className(t, methodClass(t, method)), 0),
&byteArrayBody(t, methodName(t, method), 0));
}
uint64_t result;
{ ENTER(t, Thread::IdleState);
result = t->m->system->call
(function,
args,
&nativeMethodDataParameterTypes(t, data, 0),
types,
count + 1,
size,
returnType);
@ -2570,43 +2573,13 @@ interpret(Thread* t)
pokeInt(t, t->frame + FrameIpOffset, t->ip);
for (; frame >= base; popFrame(t)) {
code = methodCode(t, frameMethod(t, frame));
object eht = codeExceptionHandlerTable(t, code);
if (eht) {
for (unsigned i = 0; i < exceptionHandlerTableLength(t, eht); ++i) {
ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i);
if (frameIp(t, frame) - 1 >= exceptionHandlerStart(eh)
and frameIp(t, frame) - 1 < exceptionHandlerEnd(eh))
{
object catchType = 0;
if (exceptionHandlerCatchType(eh)) {
object e = exception;
exception = 0;
PROTECT(t, e);
PROTECT(t, eht);
catchType = resolveClass
(t, codePool(t, code), exceptionHandlerCatchType(eh) - 1);
if (catchType) {
eh = exceptionHandlerTableBody(t, eht, i);
exception = e;
} else {
// can't find what we're supposed to catch - move on.
continue;
}
}
if (catchType == 0 or instanceOf(t, catchType, exception)) {
sp = frame + FrameFootprint;
ip = exceptionHandlerIp(eh);
pushObject(t, exception);
exception = 0;
goto loop;
}
}
}
ExceptionHandler* eh = findExceptionHandler(t, frameMethod(t, frame));
if (eh) {
sp = frame + FrameFootprint;
ip = exceptionHandlerIp(eh);
pushObject(t, exception);
exception = 0;
goto loop;
}
}

View File

@ -145,6 +145,48 @@ resolveNativeMethod(Thread* t, object method)
return 0;
}
inline ExceptionHandler*
findExceptionHandler(Thread* t, object method)
{
object code = methodCode(t, method);
object eht = codeExceptionHandlerTable(t, code);
if (eht) {
for (unsigned i = 0; i < exceptionHandlerTableLength(t, eht); ++i) {
ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i);
if (frameIp(t, frame) - 1 >= exceptionHandlerStart(eh)
and frameIp(t, frame) - 1 < exceptionHandlerEnd(eh))
{
object catchType = 0;
if (exceptionHandlerCatchType(eh)) {
object e = t->exception;
exception = 0;
PROTECT(t, e);
PROTECT(t, eht);
catchType = resolveClass
(t, codePool(t, code), exceptionHandlerCatchType(eh) - 1);
if (catchType) {
eh = exceptionHandlerTableBody(t, eht, i);
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;
}
} // namespace vm
#endif//PROCESS_H