Skip to content

Commit

Permalink
- move VM creation into the jitted function. this will allow the jit …
Browse files Browse the repository at this point in the history
…compiler to skip vm frame creation when possible
  • Loading branch information
dpjudas committed Oct 9, 2018
1 parent e930dfa commit b7c0cd5
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 30 deletions.
59 changes: 53 additions & 6 deletions src/scripting/vm/jit.cpp
Expand Up @@ -142,20 +142,24 @@ void JitCompiler::Setup()
{
using namespace asmjit;

ResetTemp();

FString funcname;
funcname.Format("Function: %s", sfunc->PrintableName.GetChars());
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
numret = cc.newInt32("numret"); // int numret
exceptInfo = cc.newIntPtr("exceptinfo"); // JitExceptionInfo *exceptInfo

cc.addFunc(FuncSignature4<int, void *, void *, int, void *>());
cc.setArg(0, stack);
cc.setArg(1, ret);
cc.setArg(2, numret);
cc.setArg(3, exceptInfo);
cc.addFunc(FuncSignature5<int, void *, int, void *, int, void *>());
cc.setArg(0, args);
cc.setArg(1, numargs);
cc.setArg(2, ret);
cc.setArg(3, numret);
cc.setArg(4, exceptInfo);

auto stackalloc = cc.newStack(sizeof(VMReturn) * MAX_RETURNS, alignof(VMReturn));
callReturns = cc.newIntPtr("callReturns");
Expand Down Expand Up @@ -185,6 +189,29 @@ void JitCompiler::Setup()
int offsetD = offsetA + (int)(sfunc->NumRegA * sizeof(void*));
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();
cc.mov(vmframe, x86::ptr(stack)); // stack->Blocks
cc.mov(vmframe, x86::ptr(vmframe, VMFrameStack::OffsetLastFrame())); // Blocks->LastFrame
Expand Down Expand Up @@ -232,6 +259,23 @@ void JitCompiler::Setup()
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)
{
auto label = cc.newLabel();
Expand All @@ -253,6 +297,7 @@ void JitCompiler::EmitThrowException(EVMAbortException reason)
cc.mov(x86::dword_ptr(exceptInfo, 4 * 4), imm_ptr(pc));

// Return from function
EmitPopFrame();
X86Gp vReg = newTempInt32();
cc.mov(vReg, 0);
cc.ret(vReg);
Expand All @@ -271,6 +316,7 @@ void JitCompiler::EmitThrowException(EVMAbortException reason, asmjit::X86Gp arg
cc.mov(x86::dword_ptr(exceptInfo, 4 * 4), imm_ptr(pc));

// Return from function
EmitPopFrame();
X86Gp vReg = newTempInt32();
cc.mov(vReg, 0);
cc.ret(vReg);
Expand All @@ -283,6 +329,7 @@ void JitCompiler::EmitCheckForException()
cc.mov(exceptResult, asmjit::x86::dword_ptr(exceptInfo, 0 * 4));
cc.cmp(exceptResult, (int)-1);
cc.je(noexception);
EmitPopFrame();
asmjit::X86Gp vReg = newTempInt32();
cc.mov(vReg, 0);
cc.ret(vReg);
Expand Down
1 change: 1 addition & 0 deletions src/scripting/vm/jit_call.cpp
Expand Up @@ -225,6 +225,7 @@ void JitCompiler::EmitDoTail(asmjit::X86Gp ptr)
call->setArg(5, ret);
call->setArg(6, exceptInfo);

EmitPopFrame();
cc.ret(result);

NumParam -= B;
Expand Down
9 changes: 9 additions & 0 deletions src/scripting/vm/jit_flow.cpp
Expand Up @@ -104,6 +104,7 @@ void JitCompiler::EmitRET()
using namespace asmjit;
if (B == REGT_NIL)
{
EmitPopFrame();
X86Gp vReg = newTempInt32();
cc.mov(vReg, 0);
cc.ret(vReg);
Expand Down Expand Up @@ -215,12 +216,16 @@ void JitCompiler::EmitRET()
if (a & RET_FINAL)
{
cc.add(reg_retnum, 1);
EmitPopFrame();
cc.ret(reg_retnum);
}

cc.bind(L_endif);
if (a & RET_FINAL)
{
EmitPopFrame();
cc.ret(numret);
}
}
}

Expand All @@ -245,12 +250,16 @@ void JitCompiler::EmitRETI()
if (a & RET_FINAL)
{
cc.add(reg_retnum, 1);
EmitPopFrame();
cc.ret(reg_retnum);
}

cc.bind(L_endif);
if (a & RET_FINAL)
{
EmitPopFrame();
cc.ret(numret);
}
}

void JitCompiler::EmitNEW()
Expand Down
5 changes: 4 additions & 1 deletion src/scripting/vm/jitintern.h
Expand Up @@ -39,6 +39,7 @@ class JitCompiler

void Setup();
void EmitOpcode();
void EmitPopFrame();

void EmitDoCall(asmjit::X86Gp ptr);
void EmitDoTail(asmjit::X86Gp ptr);
Expand Down Expand Up @@ -141,10 +142,12 @@ class JitCompiler
asmjit::X86Compiler cc;
VMScriptFunction *sfunc;

asmjit::X86Gp stack;
asmjit::X86Gp args;
asmjit::X86Gp numargs;
asmjit::X86Gp ret;
asmjit::X86Gp numret;
asmjit::X86Gp exceptInfo;
asmjit::X86Gp stack;

int offsetExtra;
asmjit::X86Gp vmframe;
Expand Down
31 changes: 9 additions & 22 deletions src/scripting/vm/vmframe.cpp
Expand Up @@ -226,30 +226,17 @@ int VMScriptFunction::FirstScriptCall(VMScriptFunction *func, VMValue *params, i

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;
exceptInfo.reason = -1;
int result = func->JitFunc(stack, ret, numret, &exceptInfo);
if (exceptInfo.reason != -1)
{
if (exceptInfo.cppException)
std::rethrow_exception(exceptInfo.cppException);
else
ThrowAbortException(func, exceptInfo.pcOnJitAbort, (EVMAbortException)exceptInfo.reason, nullptr);
}
return result;
}
catch (...)
JitExceptionInfo exceptInfo;
exceptInfo.reason = -1;
int result = func->JitFunc(params, numparams, ret, numret, &exceptInfo);
if (exceptInfo.reason != -1)
{
stack->PopFrame();
throw;
if (exceptInfo.cppException)
std::rethrow_exception(exceptInfo.cppException);
else
ThrowAbortException(func, exceptInfo.pcOnJitAbort, (EVMAbortException)exceptInfo.reason, nullptr);
}
stack->PopFrame();
return numret;
return result;
}

//===========================================================================
Expand Down
2 changes: 1 addition & 1 deletion src/scripting/vm/vmintern.h
Expand Up @@ -446,7 +446,7 @@ struct JitExceptionInfo
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
{
Expand Down

0 comments on commit b7c0cd5

Please sign in to comment.