From ba4606c1d5f979c567d6201342afaf4ba2e8323d Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 16 Sep 2018 03:20:56 +0200 Subject: [PATCH] - read the parameters and registers directly off the stack --- src/scripting/vm/jit.cpp | 90 ++++++++++++++++++------------------ src/scripting/vm/jitintern.h | 1 - src/scripting/vm/vmexec.h | 5 +- src/scripting/vm/vmintern.h | 3 +- 4 files changed, 50 insertions(+), 49 deletions(-) diff --git a/src/scripting/vm/jit.cpp b/src/scripting/vm/jit.cpp index 1070c15660..1b67a326e9 100644 --- a/src/scripting/vm/jit.cpp +++ b/src/scripting/vm/jit.cpp @@ -201,21 +201,19 @@ void JitCompiler::Setup() cc.comment(funcname.GetChars(), funcname.Len()); stack = cc.newIntPtr("stack"); // VMFrameStack *stack - vmregs = cc.newIntPtr("vmregs"); // VMRegisters *vmregs ret = cc.newIntPtr("ret"); // VMReturn *ret numret = cc.newInt32("numret"); // int numret exceptInfo = cc.newIntPtr("exceptinfo"); // JitExceptionInfo *exceptInfo - cc.addFunc(FuncSignature5()); + cc.addFunc(FuncSignature4()); cc.setArg(0, stack); - cc.setArg(1, vmregs); - cc.setArg(2, ret); - cc.setArg(3, numret); - cc.setArg(4, exceptInfo); + cc.setArg(1, ret); + cc.setArg(2, numret); + cc.setArg(3, exceptInfo); - auto stack = cc.newStack(sizeof(VMReturn) * MAX_RETURNS, alignof(VMReturn)); + auto stackalloc = cc.newStack(sizeof(VMReturn) * MAX_RETURNS, alignof(VMReturn)); callReturns = cc.newIntPtr("callReturns"); - cc.lea(callReturns, stack); + cc.lea(callReturns, stackalloc); konstd = sfunc->KonstD; konstf = sfunc->KonstF; @@ -232,51 +230,53 @@ void JitCompiler::Setup() frameS = cc.newIntPtr(); frameA = cc.newIntPtr(); params = cc.newIntPtr(); - cc.mov(frameD, x86::ptr(vmregs, offsetof(VMRegisters, d))); - cc.mov(frameF, x86::ptr(vmregs, offsetof(VMRegisters, f))); - cc.mov(frameS, x86::ptr(vmregs, offsetof(VMRegisters, s))); - cc.mov(frameA, x86::ptr(vmregs, offsetof(VMRegisters, a))); - cc.mov(params, x86::ptr(vmregs, offsetof(VMRegisters, param))); - if (sfunc->NumRegD > 0) + // the VM version reads this from the stack, but it is constant data + int offsetParams = ((int)sizeof(VMFrame) + 15) & ~15; + int offsetF = offsetParams + (int)(sfunc->MaxParam * sizeof(VMValue)); + int offsetS = offsetF + (int)(sfunc->NumRegF * sizeof(double)); + int offsetA = offsetS + (int)(sfunc->NumRegS * sizeof(FString)); + int offsetD = offsetA + (int)(sfunc->NumRegA * sizeof(void*)); + + auto vmregs = cc.newIntPtr(); + cc.mov(vmregs, x86::ptr(stack)); // stack->Blocks + cc.mov(vmregs, x86::ptr(vmregs, VMFrameStack::OffsetLastFrame())); // Blocks->LastFrame + cc.lea(params, x86::ptr(vmregs, offsetParams)); + cc.lea(frameF, x86::ptr(vmregs, offsetF)); + cc.lea(frameS, x86::ptr(vmregs, offsetS)); + cc.lea(frameA, x86::ptr(vmregs, offsetA)); + cc.lea(frameD, x86::ptr(vmregs, offsetD)); + + for (int i = 0; i < sfunc->NumRegD; i++) { - for (int i = 0; i < sfunc->NumRegD; i++) - { - FString regname; - regname.Format("regD%d", i); - regD[i] = cc.newInt32(regname.GetChars()); - cc.mov(regD[i], x86::dword_ptr(frameD, i * sizeof(int32_t))); - } + FString regname; + regname.Format("regD%d", i); + regD[i] = cc.newInt32(regname.GetChars()); + cc.mov(regD[i], x86::dword_ptr(frameD, i * sizeof(int32_t))); } - if (sfunc->NumRegF > 0) + + for (int i = 0; i < sfunc->NumRegF; i++) { - for (int i = 0; i < sfunc->NumRegF; i++) - { - FString regname; - regname.Format("regF%d", i); - regF[i] = cc.newXmmSd(regname.GetChars()); - cc.movsd(regF[i], x86::qword_ptr(frameF, i * sizeof(double))); - } + FString regname; + regname.Format("regF%d", i); + regF[i] = cc.newXmmSd(regname.GetChars()); + cc.movsd(regF[i], x86::qword_ptr(frameF, i * sizeof(double))); } - if (sfunc->NumRegS > 0) + + for (int i = 0; i < sfunc->NumRegS; i++) { - for (int i = 0; i < sfunc->NumRegS; i++) - { - FString regname; - regname.Format("regS%d", i); - regS[i] = cc.newIntPtr(regname.GetChars()); - cc.lea(regS[i], x86::ptr(frameS, i * sizeof(FString))); - } + FString regname; + regname.Format("regS%d", i); + regS[i] = cc.newIntPtr(regname.GetChars()); + cc.lea(regS[i], x86::ptr(frameS, i * sizeof(FString))); } - if (sfunc->NumRegA > 0) + + for (int i = 0; i < sfunc->NumRegA; i++) { - for (int i = 0; i < sfunc->NumRegA; i++) - { - FString regname; - regname.Format("regA%d", i); - regA[i] = cc.newIntPtr(regname.GetChars()); - cc.mov(regA[i], x86::ptr(frameA, i * sizeof(void*))); - } + FString regname; + regname.Format("regA%d", i); + regA[i] = cc.newIntPtr(regname.GetChars()); + cc.mov(regA[i], x86::ptr(frameA, i * sizeof(void*))); } int size = sfunc->CodeSize; diff --git a/src/scripting/vm/jitintern.h b/src/scripting/vm/jitintern.h index e19b5c6c2f..a59240cdc6 100644 --- a/src/scripting/vm/jitintern.h +++ b/src/scripting/vm/jitintern.h @@ -91,7 +91,6 @@ private: VMScriptFunction *sfunc; asmjit::X86Gp stack; - asmjit::X86Gp vmregs; asmjit::X86Gp ret; asmjit::X86Gp numret; asmjit::X86Gp exceptInfo; diff --git a/src/scripting/vm/vmexec.h b/src/scripting/vm/vmexec.h index 0d58f95f9f..d2ad8c894c 100644 --- a/src/scripting/vm/vmexec.h +++ b/src/scripting/vm/vmexec.h @@ -50,7 +50,6 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret) //int try_depth = 0; VMFrame *f = stack->TopFrame(); VMScriptFunction *sfunc; - const VMRegisters reg(f); const int *konstd; const double *konstf; const FString *konsts; @@ -84,7 +83,7 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret) { JitExceptionInfo exceptInfo; exceptInfo.reason = -1; - int result = sfunc->JitFunc(stack, ®, ret, numret, &exceptInfo); + int result = sfunc->JitFunc(stack, ret, numret, &exceptInfo); if (exceptInfo.reason != -1) { ThrowAbortException(sfunc, exceptInfo.pcOnJitAbort, (EVMAbortException)exceptInfo.reason, nullptr); @@ -93,6 +92,8 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret) } } + const VMRegisters reg(f); + void *ptr; double fb, fc; const double *fbp, *fcp; diff --git a/src/scripting/vm/vmintern.h b/src/scripting/vm/vmintern.h index 99cf97214c..909d3c3b56 100644 --- a/src/scripting/vm/vmintern.h +++ b/src/scripting/vm/vmintern.h @@ -356,6 +356,7 @@ public: assert(Blocks != NULL && Blocks->LastFrame != NULL); return Blocks->LastFrame; } + static int OffsetLastFrame() { return (int)(ptrdiff_t)offsetof(BlockHeader, LastFrame); } private: enum { BLOCK_SIZE = 4096 }; // Default block size struct BlockHeader @@ -444,7 +445,7 @@ struct JitExceptionInfo VMOP* pcOnJitAbort; }; -typedef int(*JitFuncPtr)(VMFrameStack *stack, const void *vmregs, VMReturn *ret, int numret, JitExceptionInfo *exceptInfo); +typedef int(*JitFuncPtr)(VMFrameStack *stack, VMReturn *ret, int numret, JitExceptionInfo *exceptInfo); class VMScriptFunction : public VMFunction {