progress towards JIT stack unwinding

This commit is contained in:
Joel Dice 2007-10-03 21:19:39 -06:00
parent 404d996c1e
commit 2135f62584
3 changed files with 92 additions and 69 deletions

View File

@ -109,12 +109,12 @@ exit:
.globl vmJump .globl vmJump
vmJump: vmJump:
// 8(%ebp): address // 4(%esp): address
// 12(%ebp): base // 8(%esp): base
movq 8(%ebp),%eax movl 4(%esp),%eax
movq 12(%ebp),%rsp movl 8(%esp),%esp
popq %rbp popl %ebp
jmp *(%eax) jmp *%eax
#else #else
# error unsupported platform # error unsupported platform

View File

@ -11,6 +11,9 @@ extern "C" uint64_t
vmInvoke(void* function, void* stack, unsigned stackSize, vmInvoke(void* function, void* stack, unsigned stackSize,
unsigned returnType); unsigned returnType);
extern "C" void
vmCall();
extern "C" void NO_RETURN extern "C" void NO_RETURN
vmJump(void* address, void* base); vmJump(void* address, void* base);
@ -138,19 +141,19 @@ class MyThread: public Thread {
inline void* inline void*
frameBase(void* frame) frameBase(void* frame)
{ {
return *static_cast<void**>(frame); return static_cast<void**>(frame)[(-FrameFootprint / BytesPerWord) - 2];
} }
inline bool inline bool
frameValid(void* frame) frameValid(void* frame)
{ {
return frameBase(frame) != 0; return frame != 0;
} }
inline void* inline void*
frameNext(void* frame) frameNext(void* frame)
{ {
return static_cast<void**>(frameBase(frame))[FrameNext / BytesPerWord] ; return static_cast<void**>(frameBase(frame))[FrameNext / BytesPerWord];
} }
inline object inline object
@ -162,7 +165,7 @@ frameMethod(void* frame)
inline void* inline void*
frameAddress(void* frame) frameAddress(void* frame)
{ {
return static_cast<void**>(frame)[1]; return static_cast<void**>(frame)[(-FrameFootprint / BytesPerWord) - 1];
} }
inline void* inline void*
@ -352,7 +355,7 @@ invokeNative2(MyThread* t, object method)
args[argOffset++] = reinterpret_cast<uintptr_t>(t); args[argOffset++] = reinterpret_cast<uintptr_t>(t);
types[typeOffset++] = POINTER_TYPE; types[typeOffset++] = POINTER_TYPE;
uintptr_t* sp = static_cast<uintptr_t*>(t->frame) uintptr_t* sp = static_cast<uintptr_t*>(frameBase(t->frame))
+ (methodParameterFootprint(t, method) + 1) + (methodParameterFootprint(t, method) + 1)
+ (FrameFootprint / BytesPerWord); + (FrameFootprint / BytesPerWord);
@ -417,7 +420,7 @@ invokeNative2(MyThread* t, object method)
args, args,
types, types,
count + 1, count + 1,
footprint, footprint * BytesPerWord,
returnType); returnType);
} }
@ -960,6 +963,9 @@ parameterOffset(unsigned index)
return FrameFootprint + ((index + 2) * BytesPerWord); return FrameFootprint + ((index + 2) * BytesPerWord);
} }
Compiled*
caller(MyThread* t);
class Compiler: public Assembler { class Compiler: public Assembler {
public: public:
Compiler(MyThread* t): Compiler(MyThread* t):
@ -1005,7 +1011,7 @@ class Compiler: public Assembler {
Compiled* code = reinterpret_cast<Compiled*>(methodCompiled(t, target)); Compiled* code = reinterpret_cast<Compiled*>(methodCompiled(t, target));
push(rbp); push(rsp);
push(poolRegister(), poolReference(target)); push(poolRegister(), poolReference(target));
push(rbp, FrameThread); push(rbp, FrameThread);
@ -1017,11 +1023,15 @@ class Compiler: public Assembler {
} }
void compileCall2(void* function, unsigned argCount) { void compileCall2(void* function, unsigned argCount) {
mov(rbp, FrameThread, rax); if (BytesPerWord == 4) {
lea(rsp, -(BytesPerWord * 2), rcx); push(rbp, FrameThread);
mov(rcx, rax, threadFrameOffset()); // set thread frame to current } else {
mov(rbp, FrameThread, rdi);
}
callAddress(function); mov(reinterpret_cast<uintptr_t>(function), rbx);
callAddress(compiledCode(caller(t)));
if (BytesPerWord == 4) { if (BytesPerWord == 4) {
add(BytesPerWord * argCount, rsp); add(BytesPerWord * argCount, rsp);
@ -1031,10 +1041,8 @@ class Compiler: public Assembler {
void compileCall(void* function, object arg1) { void compileCall(void* function, object arg1) {
if (BytesPerWord == 4) { if (BytesPerWord == 4) {
push(poolRegister(), poolReference(arg1)); push(poolRegister(), poolReference(arg1));
push(rbp, FrameThread);
} else { } else {
mov(poolRegister(), poolReference(arg1), rsi); mov(poolRegister(), poolReference(arg1), rsi);
mov(rbp, FrameThread, rdi);
} }
compileCall2(function, 2); compileCall2(function, 2);
@ -1043,10 +1051,8 @@ class Compiler: public Assembler {
void compileCall(void* function, Register arg1) { void compileCall(void* function, Register arg1) {
if (BytesPerWord == 4) { if (BytesPerWord == 4) {
push(arg1); push(arg1);
push(rbp, FrameThread);
} else { } else {
mov(arg1, rsi); mov(arg1, rsi);
mov(rbp, FrameThread, rdi);
} }
compileCall2(function, 2); compileCall2(function, 2);
@ -1056,11 +1062,9 @@ class Compiler: public Assembler {
if (BytesPerWord == 4) { if (BytesPerWord == 4) {
push(arg2); push(arg2);
push(poolRegister(), poolReference(arg1)); push(poolRegister(), poolReference(arg1));
push(rbp, FrameThread);
} else { } else {
mov(arg2, rdx); mov(arg2, rdx);
mov(poolRegister(), poolReference(arg1), rsi); mov(poolRegister(), poolReference(arg1), rsi);
mov(rbp, FrameThread, rdi);
} }
compileCall2(function, 3); compileCall2(function, 3);
@ -1070,11 +1074,9 @@ class Compiler: public Assembler {
if (BytesPerWord == 4) { if (BytesPerWord == 4) {
push(arg2); push(arg2);
pushAddress(reinterpret_cast<uintptr_t>(arg1)); pushAddress(reinterpret_cast<uintptr_t>(arg1));
push(rbp, FrameThread);
} else { } else {
mov(arg2, rdx); mov(arg2, rdx);
mov(reinterpret_cast<uintptr_t>(arg1), rsi); mov(reinterpret_cast<uintptr_t>(arg1), rsi);
mov(rbp, FrameThread, rdi);
} }
compileCall2(function, 3); compileCall2(function, 3);
@ -1084,11 +1086,9 @@ class Compiler: public Assembler {
if (BytesPerWord == 4) { if (BytesPerWord == 4) {
push(arg2); push(arg2);
push(arg1); push(arg1);
push(rbp, FrameThread);
} else { } else {
mov(arg2, rdx); mov(arg2, rdx);
mov(arg1, rsi); mov(arg1, rsi);
mov(rbp, FrameThread, rdi);
} }
compileCall2(function, 3); compileCall2(function, 3);
@ -2107,35 +2107,6 @@ class Compiler: public Assembler {
- reinterpret_cast<uintptr_t>(t); - reinterpret_cast<uintptr_t>(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<uintptr_t>(invokeNative), rax);
call(rax);
if (BytesPerWord == 4) {
add(BytesPerWord * 2, rsp);
}
mov(rbp, rsp);
pop(rbp);
ret();
return finish();
}
Compiled* compileStub() { Compiled* compileStub() {
push(rbp); push(rbp);
mov(rsp, rbp); mov(rsp, rbp);
@ -2148,11 +2119,8 @@ class Compiler: public Assembler {
mov(rbp, FrameThread, rdi); mov(rbp, FrameThread, rdi);
} }
mov(rbp, FrameThread, rax); mov(reinterpret_cast<uintptr_t>(compileMethod), rbx);
mov(rbp, rax, threadFrameOffset()); // set thread frame to current callAddress(compiledCode(caller(t)));
mov(reinterpret_cast<uintptr_t>(compileMethod), rax);
call(rax);
if (BytesPerWord == 4) { if (BytesPerWord == 4) {
add(BytesPerWord * 2, rsp); add(BytesPerWord * 2, rsp);
@ -2170,6 +2138,42 @@ class Compiler: public Assembler {
return finish(); 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<uintptr_t>(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() { Compiled* finish() {
return makeCompiled(t, &code, &lineNumbers, &exceptionHandlers); return makeCompiled(t, &code, &lineNumbers, &exceptionHandlers);
} }
@ -2544,6 +2548,16 @@ class MyProcessor: public Processor {
return nativeInvoker_; return nativeInvoker_;
} }
Compiled*
caller(Thread* t)
{
if (caller_ == 0) {
Compiler c(static_cast<MyThread*>(t));
caller_ = c.compileCaller();
}
return caller_;
}
virtual unsigned virtual unsigned
parameterFootprint(vm::Thread*, const char* s, bool static_) parameterFootprint(vm::Thread*, const char* s, bool static_)
{ {
@ -2743,14 +2757,25 @@ class MyProcessor: public Processor {
s->free(nativeInvoker_); s->free(nativeInvoker_);
} }
if (caller_) {
s->free(caller_);
}
s->free(this); s->free(this);
} }
System* s; System* s;
Compiled* methodStub_; Compiled* methodStub_;
Compiled* nativeInvoker_; Compiled* nativeInvoker_;
Compiled* caller_;
}; };
Compiled*
caller(MyThread* t)
{
return static_cast<MyProcessor*>(t->m->processor)->caller(t);
}
} // namespace } // namespace
namespace vm { namespace vm {

View File

@ -123,15 +123,13 @@ cdeclCall:
// reserve space for arguments // reserve space for arguments
movl 16(%ebp),%ecx movl 16(%ebp),%ecx
subl %ecx,%esp
#ifdef __APPLE__ #ifdef __APPLE__
// align to a 16 byte boundary on Darwin // align to a 16 byte boundary on Darwin
addl $15,%ecx andl $0xFFFFFFF0,%esp
andl $0xFFFFFFF0,%ecx
addl $8,%ecx
#endif #endif
subl %ecx,%esp
// copy arguments into place // copy arguments into place
movl $0,%ecx movl $0,%ecx
jmp test jmp test