From 68e382ca8d6b2f869dc88a844edd78b1722ae9fc Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 1 Oct 2007 18:08:17 -0600 Subject: [PATCH] snapshot --- makefile | 2 +- src/compile.cpp | 139 +++++++++++++++++++++++++++++++++++++++++----- src/interpret.cpp | 53 +++++------------- src/process.h | 42 ++++++++++++++ 4 files changed, 182 insertions(+), 54 deletions(-) diff --git a/makefile b/makefile index ae27d9cacc..275d3882e4 100644 --- a/makefile +++ b/makefile @@ -34,7 +34,7 @@ src = src classpath = classpath test = test -input = $(cls)/Hello.class +input = $(cls)/Exceptions.class cxx = g++ cc = gcc diff --git a/src/compile.cpp b/src/compile.cpp index 4d0997c2d6..32fda50406 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -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(frame)[- (FrameFootprint / BytesPerWord) - 1]; +} + +inline void* +frameNext(void* frame) +{ + return static_cast(frameBase(frame))[FrameNext / BytesPerWord]; +} + +inline object +frameMethod(void* frame) +{ + return static_cast(frameBase(frame))[FrameMethod / BytesPerWord]; +} + +inline object +frameAddress(void* frame) +{ + return static_cast(frame)[- (FrameFootprint / BytesPerWord)]; +} + +inline void* +frameReturnAddress(void* frame) +{ + return static_cast(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(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(vmt)->frame; } virtual uintptr_t - frameNext(Thread* t, uintptr_t) + frameNext(Thread*, uintptr_t frame) { - abort(t); + ::frameNext(reinterpret_cast(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* diff --git a/src/interpret.cpp b/src/interpret.cpp index 778d56b3ea..fcc0d44fdc 100644 --- a/src/interpret.cpp +++ b/src/interpret.cpp @@ -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; } } diff --git a/src/process.h b/src/process.h index 547f452ab9..ffbd0dcbaa 100644 --- a/src/process.h +++ b/src/process.h @@ -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