mirror of
https://github.com/corda/corda.git
synced 2025-01-17 18:29:49 +00:00
progress towards JIT stack unwinding
This commit is contained in:
parent
404d996c1e
commit
2135f62584
@ -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
|
||||||
|
135
src/compile.cpp
135
src/compile.cpp
@ -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 {
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user