From 2135f62584db0b75c3816ea9ef79dc0422d360d3 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 3 Oct 2007 21:19:39 -0600 Subject: [PATCH] progress towards JIT stack unwinding --- src/compile.S | 12 ++--- src/compile.cpp | 137 ++++++++++++++++++++++++++++-------------------- src/system.S | 12 ++--- 3 files changed, 92 insertions(+), 69 deletions(-) diff --git a/src/compile.S b/src/compile.S index e444b0f034..d616272dc7 100644 --- a/src/compile.S +++ b/src/compile.S @@ -109,12 +109,12 @@ exit: .globl vmJump vmJump: - // 8(%ebp): address - // 12(%ebp): base - movq 8(%ebp),%eax - movq 12(%ebp),%rsp - popq %rbp - jmp *(%eax) + // 4(%esp): address + // 8(%esp): base + movl 4(%esp),%eax + movl 8(%esp),%esp + popl %ebp + jmp *%eax #else # error unsupported platform diff --git a/src/compile.cpp b/src/compile.cpp index ee865b63da..bb09450bd3 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 +vmCall(); + extern "C" void NO_RETURN vmJump(void* address, void* base); @@ -138,19 +141,19 @@ class MyThread: public Thread { inline void* frameBase(void* frame) { - return *static_cast(frame); + return static_cast(frame)[(-FrameFootprint / BytesPerWord) - 2]; } inline bool frameValid(void* frame) { - return frameBase(frame) != 0; + return frame != 0; } inline void* frameNext(void* frame) { - return static_cast(frameBase(frame))[FrameNext / BytesPerWord] ; + return static_cast(frameBase(frame))[FrameNext / BytesPerWord]; } inline object @@ -162,7 +165,7 @@ frameMethod(void* frame) inline void* frameAddress(void* frame) { - return static_cast(frame)[1]; + return static_cast(frame)[(-FrameFootprint / BytesPerWord) - 1]; } inline void* @@ -352,7 +355,7 @@ invokeNative2(MyThread* t, object method) args[argOffset++] = reinterpret_cast(t); types[typeOffset++] = POINTER_TYPE; - uintptr_t* sp = static_cast(t->frame) + uintptr_t* sp = static_cast(frameBase(t->frame)) + (methodParameterFootprint(t, method) + 1) + (FrameFootprint / BytesPerWord); @@ -417,7 +420,7 @@ invokeNative2(MyThread* t, object method) args, types, count + 1, - footprint, + footprint * BytesPerWord, returnType); } @@ -960,6 +963,9 @@ parameterOffset(unsigned index) return FrameFootprint + ((index + 2) * BytesPerWord); } +Compiled* +caller(MyThread* t); + class Compiler: public Assembler { public: Compiler(MyThread* t): @@ -1005,23 +1011,27 @@ class Compiler: public Assembler { Compiled* code = reinterpret_cast(methodCompiled(t, target)); - push(rbp); + push(rsp); push(poolRegister(), poolReference(target)); push(rbp, FrameThread); callAlignedAddress(compiledCode(code)); - add(footprint, rsp); // pop arguments + add(footprint, rsp); // pop arguments pushReturnValue(methodReturnCode(t, target)); } void compileCall2(void* function, unsigned argCount) { - mov(rbp, FrameThread, rax); - lea(rsp, -(BytesPerWord * 2), rcx); - mov(rcx, rax, threadFrameOffset()); // set thread frame to current + if (BytesPerWord == 4) { + push(rbp, FrameThread); + } else { + mov(rbp, FrameThread, rdi); + } - callAddress(function); + mov(reinterpret_cast(function), rbx); + + callAddress(compiledCode(caller(t))); if (BytesPerWord == 4) { add(BytesPerWord * argCount, rsp); @@ -1031,10 +1041,8 @@ class Compiler: public Assembler { void compileCall(void* function, object arg1) { if (BytesPerWord == 4) { push(poolRegister(), poolReference(arg1)); - push(rbp, FrameThread); } else { mov(poolRegister(), poolReference(arg1), rsi); - mov(rbp, FrameThread, rdi); } compileCall2(function, 2); @@ -1043,10 +1051,8 @@ class Compiler: public Assembler { void compileCall(void* function, Register arg1) { if (BytesPerWord == 4) { push(arg1); - push(rbp, FrameThread); } else { mov(arg1, rsi); - mov(rbp, FrameThread, rdi); } compileCall2(function, 2); @@ -1056,11 +1062,9 @@ class Compiler: public Assembler { if (BytesPerWord == 4) { push(arg2); push(poolRegister(), poolReference(arg1)); - push(rbp, FrameThread); } else { mov(arg2, rdx); mov(poolRegister(), poolReference(arg1), rsi); - mov(rbp, FrameThread, rdi); } compileCall2(function, 3); @@ -1070,11 +1074,9 @@ class Compiler: public Assembler { if (BytesPerWord == 4) { push(arg2); pushAddress(reinterpret_cast(arg1)); - push(rbp, FrameThread); } else { mov(arg2, rdx); mov(reinterpret_cast(arg1), rsi); - mov(rbp, FrameThread, rdi); } compileCall2(function, 3); @@ -1084,11 +1086,9 @@ class Compiler: public Assembler { if (BytesPerWord == 4) { push(arg2); push(arg1); - push(rbp, FrameThread); } else { mov(arg2, rdx); mov(arg1, rsi); - mov(rbp, FrameThread, rdi); } compileCall2(function, 3); @@ -2107,35 +2107,6 @@ class Compiler: public Assembler { - reinterpret_cast(t); } - Compiled* compileNativeInvoker() { - push(rbp); - mov(rsp, rbp); - - if (BytesPerWord == 4) { - push(rbp, FrameMethod); - push(rbp, FrameThread); - } else { - mov(rbp, FrameMethod, rsi); - mov(rbp, FrameThread, rdi); - } - - mov(rbp, FrameThread, rax); - mov(rbp, rax, threadFrameOffset()); // set thread frame to current - - mov(reinterpret_cast(invokeNative), rax); - call(rax); - - if (BytesPerWord == 4) { - add(BytesPerWord * 2, rsp); - } - - mov(rbp, rsp); - pop(rbp); - ret(); - - return finish(); - } - Compiled* compileStub() { push(rbp); mov(rsp, rbp); @@ -2148,11 +2119,8 @@ class Compiler: public Assembler { mov(rbp, FrameThread, rdi); } - mov(rbp, FrameThread, rax); - mov(rbp, rax, threadFrameOffset()); // set thread frame to current - - mov(reinterpret_cast(compileMethod), rax); - call(rax); + mov(reinterpret_cast(compileMethod), rbx); + callAddress(compiledCode(caller(t))); if (BytesPerWord == 4) { add(BytesPerWord * 2, rsp); @@ -2170,6 +2138,42 @@ class Compiler: public Assembler { return finish(); } + Compiled* compileNativeInvoker() { + push(rbp); + mov(rsp, rbp); + + if (BytesPerWord == 4) { + push(rbp, FrameMethod); + push(rbp, FrameThread); + } else { + mov(rbp, FrameMethod, rsi); + mov(rbp, FrameThread, rdi); + } + + mov(reinterpret_cast(invokeNative), rbx); + callAddress(compiledCode(caller(t))); + + if (BytesPerWord == 4) { + add(BytesPerWord * 2, rsp); + } + + mov(rbp, rsp); + pop(rbp); + ret(); + + return finish(); + } + + Compiled* compileCaller() { + mov(rbp, FrameThread, rdi); + lea(rsp, FrameFootprint + BytesPerWord, rcx); + mov(rcx, rdi, threadFrameOffset()); // set thread frame to current + + jmp(rbx); + + return finish(); + } + Compiled* finish() { return makeCompiled(t, &code, &lineNumbers, &exceptionHandlers); } @@ -2544,6 +2548,16 @@ class MyProcessor: public Processor { return nativeInvoker_; } + Compiled* + caller(Thread* t) + { + if (caller_ == 0) { + Compiler c(static_cast(t)); + caller_ = c.compileCaller(); + } + return caller_; + } + virtual unsigned parameterFootprint(vm::Thread*, const char* s, bool static_) { @@ -2743,14 +2757,25 @@ class MyProcessor: public Processor { s->free(nativeInvoker_); } + if (caller_) { + s->free(caller_); + } + s->free(this); } System* s; Compiled* methodStub_; Compiled* nativeInvoker_; + Compiled* caller_; }; +Compiled* +caller(MyThread* t) +{ + return static_cast(t->m->processor)->caller(t); +} + } // namespace namespace vm { diff --git a/src/system.S b/src/system.S index 724493f141..b8bfffd221 100644 --- a/src/system.S +++ b/src/system.S @@ -122,16 +122,14 @@ cdeclCall: // reserve space for arguments movl 16(%ebp),%ecx - -#ifdef __APPLE__ - // align to a 16 byte boundary on Darwin - addl $15,%ecx - andl $0xFFFFFFF0,%ecx - addl $8,%ecx -#endif subl %ecx,%esp +#ifdef __APPLE__ + // align to a 16 byte boundary on Darwin + andl $0xFFFFFFF0,%esp +#endif + // copy arguments into place movl $0,%ecx jmp test