mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 07:11:54 +00:00
- move VM creation into the jitted function. this will allow the jit compiler to skip vm frame creation when possible
This commit is contained in:
parent
e930dfaae7
commit
b7c0cd5d05
6 changed files with 77 additions and 30 deletions
|
@ -142,20 +142,24 @@ void JitCompiler::Setup()
|
||||||
{
|
{
|
||||||
using namespace asmjit;
|
using namespace asmjit;
|
||||||
|
|
||||||
|
ResetTemp();
|
||||||
|
|
||||||
FString funcname;
|
FString funcname;
|
||||||
funcname.Format("Function: %s", sfunc->PrintableName.GetChars());
|
funcname.Format("Function: %s", sfunc->PrintableName.GetChars());
|
||||||
cc.comment(funcname.GetChars(), funcname.Len());
|
cc.comment(funcname.GetChars(), funcname.Len());
|
||||||
|
|
||||||
stack = cc.newIntPtr("stack"); // VMFrameStack *stack
|
args = cc.newIntPtr("args"); // VMValue *params
|
||||||
|
numargs = cc.newInt32("numargs"); // int numargs
|
||||||
ret = cc.newIntPtr("ret"); // VMReturn *ret
|
ret = cc.newIntPtr("ret"); // VMReturn *ret
|
||||||
numret = cc.newInt32("numret"); // int numret
|
numret = cc.newInt32("numret"); // int numret
|
||||||
exceptInfo = cc.newIntPtr("exceptinfo"); // JitExceptionInfo *exceptInfo
|
exceptInfo = cc.newIntPtr("exceptinfo"); // JitExceptionInfo *exceptInfo
|
||||||
|
|
||||||
cc.addFunc(FuncSignature4<int, void *, void *, int, void *>());
|
cc.addFunc(FuncSignature5<int, void *, int, void *, int, void *>());
|
||||||
cc.setArg(0, stack);
|
cc.setArg(0, args);
|
||||||
cc.setArg(1, ret);
|
cc.setArg(1, numargs);
|
||||||
cc.setArg(2, numret);
|
cc.setArg(2, ret);
|
||||||
cc.setArg(3, exceptInfo);
|
cc.setArg(3, numret);
|
||||||
|
cc.setArg(4, exceptInfo);
|
||||||
|
|
||||||
auto stackalloc = cc.newStack(sizeof(VMReturn) * MAX_RETURNS, alignof(VMReturn));
|
auto stackalloc = cc.newStack(sizeof(VMReturn) * MAX_RETURNS, alignof(VMReturn));
|
||||||
callReturns = cc.newIntPtr("callReturns");
|
callReturns = cc.newIntPtr("callReturns");
|
||||||
|
@ -185,6 +189,29 @@ void JitCompiler::Setup()
|
||||||
int offsetD = offsetA + (int)(sfunc->NumRegA * sizeof(void*));
|
int offsetD = offsetA + (int)(sfunc->NumRegA * sizeof(void*));
|
||||||
offsetExtra = (offsetD + (int)(sfunc->NumRegD * sizeof(int32_t)) + 15) & ~15;
|
offsetExtra = (offsetD + (int)(sfunc->NumRegD * sizeof(int32_t)) + 15) & ~15;
|
||||||
|
|
||||||
|
stack = cc.newIntPtr("stack");
|
||||||
|
auto allocFrame = CreateCall<VMFrameStack *, VMScriptFunction *, VMValue *, int, JitExceptionInfo *>([](VMScriptFunction *func, VMValue *args, int numargs, JitExceptionInfo *exceptinfo) -> VMFrameStack* {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
VMFrameStack *stack = &GlobalVMStack;
|
||||||
|
VMFrame *newf = stack->AllocFrame(func);
|
||||||
|
VMFillParams(args, newf, numargs);
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
exceptinfo->reason = X_OTHER;
|
||||||
|
exceptinfo->cppException = std::current_exception();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
allocFrame->setRet(0, stack);
|
||||||
|
allocFrame->setArg(0, imm_ptr(sfunc));
|
||||||
|
allocFrame->setArg(1, args);
|
||||||
|
allocFrame->setArg(2, numargs);
|
||||||
|
allocFrame->setArg(3, exceptInfo);
|
||||||
|
EmitCheckForException();
|
||||||
|
|
||||||
vmframe = cc.newIntPtr();
|
vmframe = cc.newIntPtr();
|
||||||
cc.mov(vmframe, x86::ptr(stack)); // stack->Blocks
|
cc.mov(vmframe, x86::ptr(stack)); // stack->Blocks
|
||||||
cc.mov(vmframe, x86::ptr(vmframe, VMFrameStack::OffsetLastFrame())); // Blocks->LastFrame
|
cc.mov(vmframe, x86::ptr(vmframe, VMFrameStack::OffsetLastFrame())); // Blocks->LastFrame
|
||||||
|
@ -232,6 +259,23 @@ void JitCompiler::Setup()
|
||||||
for (int i = 0; i < size; i++) labels[i] = cc.newLabel();
|
for (int i = 0; i < size; i++) labels[i] = cc.newLabel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JitCompiler::EmitPopFrame()
|
||||||
|
{
|
||||||
|
auto popFrame = CreateCall<void, VMFrameStack *, JitExceptionInfo *>([](VMFrameStack *stack, JitExceptionInfo *exceptinfo) {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
stack->PopFrame();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
exceptinfo->reason = X_OTHER;
|
||||||
|
exceptinfo->cppException = std::current_exception();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
popFrame->setArg(0, stack);
|
||||||
|
popFrame->setArg(1, exceptInfo);
|
||||||
|
}
|
||||||
|
|
||||||
void JitCompiler::EmitNullPointerThrow(int index, EVMAbortException reason)
|
void JitCompiler::EmitNullPointerThrow(int index, EVMAbortException reason)
|
||||||
{
|
{
|
||||||
auto label = cc.newLabel();
|
auto label = cc.newLabel();
|
||||||
|
@ -253,6 +297,7 @@ void JitCompiler::EmitThrowException(EVMAbortException reason)
|
||||||
cc.mov(x86::dword_ptr(exceptInfo, 4 * 4), imm_ptr(pc));
|
cc.mov(x86::dword_ptr(exceptInfo, 4 * 4), imm_ptr(pc));
|
||||||
|
|
||||||
// Return from function
|
// Return from function
|
||||||
|
EmitPopFrame();
|
||||||
X86Gp vReg = newTempInt32();
|
X86Gp vReg = newTempInt32();
|
||||||
cc.mov(vReg, 0);
|
cc.mov(vReg, 0);
|
||||||
cc.ret(vReg);
|
cc.ret(vReg);
|
||||||
|
@ -271,6 +316,7 @@ void JitCompiler::EmitThrowException(EVMAbortException reason, asmjit::X86Gp arg
|
||||||
cc.mov(x86::dword_ptr(exceptInfo, 4 * 4), imm_ptr(pc));
|
cc.mov(x86::dword_ptr(exceptInfo, 4 * 4), imm_ptr(pc));
|
||||||
|
|
||||||
// Return from function
|
// Return from function
|
||||||
|
EmitPopFrame();
|
||||||
X86Gp vReg = newTempInt32();
|
X86Gp vReg = newTempInt32();
|
||||||
cc.mov(vReg, 0);
|
cc.mov(vReg, 0);
|
||||||
cc.ret(vReg);
|
cc.ret(vReg);
|
||||||
|
@ -283,6 +329,7 @@ void JitCompiler::EmitCheckForException()
|
||||||
cc.mov(exceptResult, asmjit::x86::dword_ptr(exceptInfo, 0 * 4));
|
cc.mov(exceptResult, asmjit::x86::dword_ptr(exceptInfo, 0 * 4));
|
||||||
cc.cmp(exceptResult, (int)-1);
|
cc.cmp(exceptResult, (int)-1);
|
||||||
cc.je(noexception);
|
cc.je(noexception);
|
||||||
|
EmitPopFrame();
|
||||||
asmjit::X86Gp vReg = newTempInt32();
|
asmjit::X86Gp vReg = newTempInt32();
|
||||||
cc.mov(vReg, 0);
|
cc.mov(vReg, 0);
|
||||||
cc.ret(vReg);
|
cc.ret(vReg);
|
||||||
|
|
|
@ -225,6 +225,7 @@ void JitCompiler::EmitDoTail(asmjit::X86Gp ptr)
|
||||||
call->setArg(5, ret);
|
call->setArg(5, ret);
|
||||||
call->setArg(6, exceptInfo);
|
call->setArg(6, exceptInfo);
|
||||||
|
|
||||||
|
EmitPopFrame();
|
||||||
cc.ret(result);
|
cc.ret(result);
|
||||||
|
|
||||||
NumParam -= B;
|
NumParam -= B;
|
||||||
|
|
|
@ -104,6 +104,7 @@ void JitCompiler::EmitRET()
|
||||||
using namespace asmjit;
|
using namespace asmjit;
|
||||||
if (B == REGT_NIL)
|
if (B == REGT_NIL)
|
||||||
{
|
{
|
||||||
|
EmitPopFrame();
|
||||||
X86Gp vReg = newTempInt32();
|
X86Gp vReg = newTempInt32();
|
||||||
cc.mov(vReg, 0);
|
cc.mov(vReg, 0);
|
||||||
cc.ret(vReg);
|
cc.ret(vReg);
|
||||||
|
@ -215,13 +216,17 @@ void JitCompiler::EmitRET()
|
||||||
if (a & RET_FINAL)
|
if (a & RET_FINAL)
|
||||||
{
|
{
|
||||||
cc.add(reg_retnum, 1);
|
cc.add(reg_retnum, 1);
|
||||||
|
EmitPopFrame();
|
||||||
cc.ret(reg_retnum);
|
cc.ret(reg_retnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
cc.bind(L_endif);
|
cc.bind(L_endif);
|
||||||
if (a & RET_FINAL)
|
if (a & RET_FINAL)
|
||||||
|
{
|
||||||
|
EmitPopFrame();
|
||||||
cc.ret(numret);
|
cc.ret(numret);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::EmitRETI()
|
void JitCompiler::EmitRETI()
|
||||||
|
@ -245,12 +250,16 @@ void JitCompiler::EmitRETI()
|
||||||
if (a & RET_FINAL)
|
if (a & RET_FINAL)
|
||||||
{
|
{
|
||||||
cc.add(reg_retnum, 1);
|
cc.add(reg_retnum, 1);
|
||||||
|
EmitPopFrame();
|
||||||
cc.ret(reg_retnum);
|
cc.ret(reg_retnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
cc.bind(L_endif);
|
cc.bind(L_endif);
|
||||||
if (a & RET_FINAL)
|
if (a & RET_FINAL)
|
||||||
|
{
|
||||||
|
EmitPopFrame();
|
||||||
cc.ret(numret);
|
cc.ret(numret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::EmitNEW()
|
void JitCompiler::EmitNEW()
|
||||||
|
|
|
@ -39,6 +39,7 @@ private:
|
||||||
|
|
||||||
void Setup();
|
void Setup();
|
||||||
void EmitOpcode();
|
void EmitOpcode();
|
||||||
|
void EmitPopFrame();
|
||||||
|
|
||||||
void EmitDoCall(asmjit::X86Gp ptr);
|
void EmitDoCall(asmjit::X86Gp ptr);
|
||||||
void EmitDoTail(asmjit::X86Gp ptr);
|
void EmitDoTail(asmjit::X86Gp ptr);
|
||||||
|
@ -141,10 +142,12 @@ private:
|
||||||
asmjit::X86Compiler cc;
|
asmjit::X86Compiler cc;
|
||||||
VMScriptFunction *sfunc;
|
VMScriptFunction *sfunc;
|
||||||
|
|
||||||
asmjit::X86Gp stack;
|
asmjit::X86Gp args;
|
||||||
|
asmjit::X86Gp numargs;
|
||||||
asmjit::X86Gp ret;
|
asmjit::X86Gp ret;
|
||||||
asmjit::X86Gp numret;
|
asmjit::X86Gp numret;
|
||||||
asmjit::X86Gp exceptInfo;
|
asmjit::X86Gp exceptInfo;
|
||||||
|
asmjit::X86Gp stack;
|
||||||
|
|
||||||
int offsetExtra;
|
int offsetExtra;
|
||||||
asmjit::X86Gp vmframe;
|
asmjit::X86Gp vmframe;
|
||||||
|
|
|
@ -226,14 +226,9 @@ int VMScriptFunction::FirstScriptCall(VMScriptFunction *func, VMValue *params, i
|
||||||
|
|
||||||
int VMScriptFunction::JitCall(VMScriptFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret)
|
int VMScriptFunction::JitCall(VMScriptFunction *func, VMValue *params, int numparams, VMReturn *ret, int numret)
|
||||||
{
|
{
|
||||||
VMFrameStack *stack = &GlobalVMStack;
|
|
||||||
VMFrame *newf = stack->AllocFrame(func);
|
|
||||||
VMFillParams(params, newf, numparams);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
JitExceptionInfo exceptInfo;
|
JitExceptionInfo exceptInfo;
|
||||||
exceptInfo.reason = -1;
|
exceptInfo.reason = -1;
|
||||||
int result = func->JitFunc(stack, ret, numret, &exceptInfo);
|
int result = func->JitFunc(params, numparams, ret, numret, &exceptInfo);
|
||||||
if (exceptInfo.reason != -1)
|
if (exceptInfo.reason != -1)
|
||||||
{
|
{
|
||||||
if (exceptInfo.cppException)
|
if (exceptInfo.cppException)
|
||||||
|
@ -242,14 +237,6 @@ int VMScriptFunction::JitCall(VMScriptFunction *func, VMValue *params, int numpa
|
||||||
ThrowAbortException(func, exceptInfo.pcOnJitAbort, (EVMAbortException)exceptInfo.reason, nullptr);
|
ThrowAbortException(func, exceptInfo.pcOnJitAbort, (EVMAbortException)exceptInfo.reason, nullptr);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
stack->PopFrame();
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
stack->PopFrame();
|
|
||||||
return numret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
|
@ -446,7 +446,7 @@ struct JitExceptionInfo
|
||||||
std::exception_ptr cppException;
|
std::exception_ptr cppException;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int(*JitFuncPtr)(VMFrameStack *stack, VMReturn *ret, int numret, JitExceptionInfo *exceptInfo);
|
typedef int(*JitFuncPtr)(VMValue *params, int numparams, VMReturn *ret, int numret, JitExceptionInfo *exceptInfo);
|
||||||
|
|
||||||
class VMScriptFunction : public VMFunction
|
class VMScriptFunction : public VMFunction
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue